Change the way that FastSerial ports are created, so that we can avoid

creating port drivers for ports that aren't used.

This lets us save the RAM (~200 bytes per port) that would otherwise
have been used for buffers.  It also frees up the port's interrupt
vectors so that on Mega we can use the ports for other things
(e.g. SPI Master mode).

Better to fix this now than later when we have more consumers.



git-svn-id: https://arducopter.googlecode.com/svn/trunk@355 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
DrZiplok@gmail.com 2010-08-30 04:01:15 +00:00
parent 3db966f378
commit 22c9ed317e
2 changed files with 53 additions and 5 deletions

View File

@ -29,10 +29,10 @@
//
#include "FastSerial.h"
#include <wiring.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include "FastSerial.h"
#if defined(__AVR_ATmega1280__)
# define FS_MAX_PORTS 4
@ -40,13 +40,14 @@
# define FS_MAX_PORTS 1
#endif
static FastSerial *ports[FS_MAX_PORTS];
FastSerial *__FastSerial__ports[FS_MAX_PORTS];
#define RX_BUFFER_SIZE sizeof(((FastSerial::RXBuffer *)1)->bytes)
#define TX_BUFFER_SIZE sizeof(((FastSerial::TXBuffer *)1)->bytes)
// Interrupt handlers //////////////////////////////////////////////////////////
#if 0
#define HANDLERS(_PORT, _RXVECTOR, _TXVECTOR, _UDR) \
SIGNAL(_RXVECTOR) \
{ \
@ -70,6 +71,7 @@ HANDLERS(2, SIG_USART2_RECV, SIG_USART2_DATA, UDR2);
HANDLERS(3, SIG_USART3_RECV, SIG_USART3_DATA, UDR3);
#endif
#endif
#endif
// Constructor /////////////////////////////////////////////////////////////////
@ -139,7 +141,7 @@ FastSerial::FastSerial(uint8_t portNumber)
_rxBuffer.head = _rxBuffer.tail = 0;
// claim the port
ports[portNumber] = this;
__FastSerial__ports[portNumber] = this;
}
// Public Methods //////////////////////////////////////////////////////////////

View File

@ -44,11 +44,26 @@
#ifndef FastSerial_h
#define FastSerial_h
// disable the stock Arduino serial driver
#define HardwareSerial_h
#include <inttypes.h>
#include <Print.h>
// disable the stock Arduino serial driver
#define HardwareSerial_h
//
// Because Arduino libraries aren't really libraries, but we want to
// only define interrupt handlers for serial ports that are actually
// used, we have to force our users to define them using a macro.
//
// Due to the way interrupt vectors are specified, we have to have
// a separate macro for every port. Ugh.
//
#define FastSerialPort0(_portName) FastSerial _portName(0); FastSerialHandler0
#if defined(__AVR_ATmega1280__)
#define FastSerialPort1(_portName) FastSerial _portName(1); FastSerialHandler1
#define FastSerialPort2(_portName) FastSerial _portName(2); FastSerialHandler2
#define FastSerialPort3(_portName) FastSerial _portName(3); FastSerialHandler3
#endif
class FastSerial : public Print {
public:
@ -97,9 +112,40 @@ private:
};
// For clients that want to assume that the default Serial* objects exist.
// Note that the application is responsible for ensuring that these actually get defined,
// otherwise Arduino will suck in the HardwareSerial library and linking will fail.
extern class FastSerial Serial;
extern class FastSerial Serial1;
extern class FastSerial Serial2;
extern class FastSerial Serial3;
// Used by the per-port interrupt vectors
extern FastSerial *__FastSerial__ports[];
// Generic Rx/Tx vectors for a serial port - needs to know magic numbers
#define FastSerialHandler(_PORT, _RXVECTOR, _TXVECTOR, _UDR) \
ISR(_RXVECTOR, ISR_BLOCK) \
{ \
unsigned char c = _UDR; \
__FastSerial__ports[_PORT]->receive(c); \
} \
ISR(_TXVECTOR, ISR_BLOCK) \
{ \
__FastSerial__ports[_PORT]->transmit(); \
} \
struct hack
// Magic numbers for the Rx/Tx vectors indexed by serial port number
#if defined(__AVR_ATmega8__)
# define FastSerialHandler0 FastSerialHandler(0, SIG_UART_RECV, SIG_UART_DATA, UDR);
#else
# define FastSerialHandler0 FastSerialHandler(0, SIG_USART0_RECV, SIG_USART0_DATA, UDR0);
#endif
#if defined(__AVR_ATmega1280__)
# define FastSerialHandler1 FastSerialHandler(1, SIG_USART1_RECV, SIG_USART1_DATA, UDR1);
# define FastSerialHandler2 FastSerialHandler(2, SIG_USART2_RECV, SIG_USART2_DATA, UDR2);
# define FastSerialHandler3 FastSerialHandler(3, SIG_USART3_RECV, SIG_USART3_DATA, UDR3);
#endif
#endif // FastSerial_h