Small RAM saving.
Some code ported for the ersky9x board Mavlink port commited
This commit is contained in:
+226
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Authors - Gerard Valade <gerard.valade@gmail.com>
|
||||
*
|
||||
* Adapted from frsky
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "open9x.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
Receive serial (RS-232) characters, detecting and storing each Fr-Sky
|
||||
0x7e-framed packet as it arrives. When a complete packet has been
|
||||
received, process its data into storage variables. NOTE: This is an
|
||||
interrupt routine and should not get too lengthy. I originally had
|
||||
the buffer being checked in the perMain function (because per10ms
|
||||
isn't quite often enough for data streaming at 9600baud) but alas
|
||||
that scheme lost packets also. So each packet is parsed as it arrives,
|
||||
directly at the ISR function (through a call to frskyProcessPacket).
|
||||
|
||||
If this proves a problem in the future, then I'll just have to implement
|
||||
a second buffer to receive data while one buffer is being processed (slowly).
|
||||
*/
|
||||
|
||||
#ifndef SIMU
|
||||
ISR (USART0_RX_vect)
|
||||
{
|
||||
uint8_t iostat; //USART control and Status Register 0 A
|
||||
// uint8_t rh; //USART control and Status Register 0 B
|
||||
UCSR0B &= ~(1 << RXCIE0); // disable Interrupt
|
||||
sei();
|
||||
iostat = UCSR0A; //USART control and Status Register 0 A
|
||||
uint8_t byte = UDR0;
|
||||
|
||||
/*
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
RxC0 TxC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0
|
||||
|
||||
RxC0: Receive complete
|
||||
TXC0: Transmit Complete
|
||||
UDRE0: USART Data Register Empty
|
||||
FE0: Frame Error
|
||||
DOR0: Data OverRun
|
||||
UPE0: USART Parity Error
|
||||
U2X0: Double Tx Speed
|
||||
MPCM0: MultiProcessor Comms Mode
|
||||
*/
|
||||
if (iostat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) {
|
||||
byte = 0;
|
||||
}
|
||||
//rh = UCSR0B; //USART control and Status Register 0 B
|
||||
#ifdef MAVLINK
|
||||
(RXHandler)(byte);
|
||||
#endif
|
||||
|
||||
cli();
|
||||
UCSR0B |= (1 << RXCIE0); // enable Interrupt
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void SERIAL_EnableRXD(void) {
|
||||
UCSR0B |= (1 << RXEN0); // enable RX
|
||||
UCSR0B |= (1 << RXCIE0); // enable Interrupt
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SERIAL_DisableRXD(void) {
|
||||
UCSR0B &= ~(1 << RXEN0); // disable RX
|
||||
UCSR0B &= ~(1 << RXCIE0); // disable Interrupt
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
USART0 (transmit) Data Register Emtpy ISR
|
||||
Usef to transmit FrSky data packets, which are buffered in frskyTXBuffer.
|
||||
*/
|
||||
uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters
|
||||
uint8_t serialTxBufferCount = 0;
|
||||
uint8_t * ptrTxISR = 0;
|
||||
serial_tx_state_t serialTxState = TX_STATE_EMPTY;
|
||||
|
||||
#ifndef SIMU
|
||||
ISR(USART0_UDRE_vect)
|
||||
{
|
||||
if (serialTxBufferCount > 0) {
|
||||
UDR0 = *ptrTxISR++;
|
||||
serialTxBufferCount--;
|
||||
} else {
|
||||
UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt
|
||||
serialTxState = TX_STATE_EMPTY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SERIAL_start_uart_send() {
|
||||
ptrTxISR = serialTxBuffer;
|
||||
serialTxBufferCount = 0;
|
||||
}
|
||||
|
||||
void SERIAL_end_uart_send() {
|
||||
ptrTxISR = serialTxBuffer;
|
||||
//UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt
|
||||
serialTxState = TX_STATE_READY;
|
||||
}
|
||||
|
||||
void SERIAL_send_uart_bytes(uint8_t * buf, uint16_t len) {
|
||||
while (len--) {
|
||||
*ptrTxISR++ = *buf++;
|
||||
serialTxBufferCount++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SERIAL_transmitBuffer(uint8_t len) {
|
||||
serialTxBufferCount = len;
|
||||
ptrTxISR = serialTxBuffer;
|
||||
//UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt
|
||||
serialTxState = TX_STATE_READY;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SERIAL_startTX(void) {
|
||||
if (serialTxState == TX_STATE_READY) {
|
||||
serialTxState = TX_STATE_BUSY;
|
||||
UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uart_19200(void) {
|
||||
#ifndef SIMU
|
||||
#define BAUD 19200
|
||||
#include <util/setbaud.h>
|
||||
UBRR0H = UBRRH_VALUE;
|
||||
UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= (1 << U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(1 << U2X0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void uart_38400(void) {
|
||||
#ifndef SIMU
|
||||
#undef BAUD // avoid compiler warning
|
||||
#define BAUD 38400
|
||||
#include <util/setbaud.h>
|
||||
UBRR0H = UBRRH_VALUE;
|
||||
UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= (1 << U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(1 << U2X0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void uart_57600(void) {
|
||||
#ifndef SIMU
|
||||
#undef BAUD // avoid compiler warning
|
||||
#define BAUD 57600
|
||||
#include <util/setbaud.h>
|
||||
UBRR0H = UBRRH_VALUE;
|
||||
UBRR0L = UBRRL_VALUE;
|
||||
#if USE_2X
|
||||
UCSR0A |= (1 << U2X0);
|
||||
#else
|
||||
UCSR0A &= ~(1 << U2X0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void SERIAL_EnableTXD(void) {
|
||||
//UCSR0B |= (1 << TXEN0); // enable TX
|
||||
UCSR0B |= (1 << TXEN0) | (1 << UDRIE0); // enable TX and TX interrupt
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SERIAL_DisableTXD(void) {
|
||||
UCSR0B &= ~(1 << TXEN0); // disable TX
|
||||
UCSR0B &= ~(1 << UDRIE0); // disable Interrupt
|
||||
}
|
||||
#endif
|
||||
|
||||
void SERIAL_Init(void) {
|
||||
DDRE &= ~(1 << DDE0); // set RXD0 pin as input
|
||||
PORTE &= ~(1 << PORTE0); // disable pullup on RXD0 pin
|
||||
|
||||
uint8_t b = 1; // TODO g_eeGeneral.baudRate;
|
||||
|
||||
if (b == 0) {
|
||||
uart_19200();
|
||||
}
|
||||
else if (b == 1) {
|
||||
uart_38400();
|
||||
}
|
||||
else if (b == 2) {
|
||||
uart_57600();
|
||||
}
|
||||
#if 0
|
||||
uart_57600();
|
||||
#endif
|
||||
|
||||
// UCSR0A &= ~(1 << U2X0); // disable double speed operation
|
||||
// set 8N1
|
||||
UCSR0B = 0 | (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (0 << RXEN0) | (0 << TXEN0) | (0 << UCSZ02);
|
||||
UCSR0C = 0 | (1 << UCSZ01) | (1 << UCSZ00);
|
||||
while (UCSR0A & (1 << RXC0))
|
||||
UDR0; // flush receive buffer
|
||||
|
||||
SERIAL_EnableTXD();
|
||||
SERIAL_EnableRXD();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user