Merge pull request #109 from Alarus/master

Serial.begin() parameter to set data bits, parity, stop bits.
This commit is contained in:
David A. Mellis 2012-08-30 05:08:28 -07:00
commit a72d05b2de
2 changed files with 139 additions and 16 deletions

View File

@ -18,6 +18,7 @@
Modified 23 November 2006 by David A. Mellis Modified 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -109,13 +110,22 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#endif #endif
{ {
#if defined(UDR0) #if defined(UDR0)
unsigned char c = UDR0; if (bit_is_clear(UCSR0A, UPE0)) {
unsigned char c = UDR0;
store_char(c, &rx_buffer);
} else {
unsigned char c = UDR0;
};
#elif defined(UDR) #elif defined(UDR)
unsigned char c = UDR; if (bit_is_clear(UCSRA, PE)) {
unsigned char c = UDR;
store_char(c, &rx_buffer);
} else {
unsigned char c = UDR;
};
#else #else
#error UDR not defined #error UDR not defined
#endif #endif
store_char(c, &rx_buffer);
} }
#endif #endif
#endif #endif
@ -126,8 +136,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent1_implemented #define serialEvent1_implemented
SIGNAL(USART1_RX_vect) SIGNAL(USART1_RX_vect)
{ {
unsigned char c = UDR1; if (bit_is_clear(UCSR1A, UPE1)) {
store_char(c, &rx_buffer1); unsigned char c = UDR1;
store_char(c, &rx_buffer1);
} else {
unsigned char c = UDR1;
};
} }
#elif defined(SIG_USART1_RECV) #elif defined(SIG_USART1_RECV)
#error SIG_USART1_RECV #error SIG_USART1_RECV
@ -139,8 +153,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent2_implemented #define serialEvent2_implemented
SIGNAL(USART2_RX_vect) SIGNAL(USART2_RX_vect)
{ {
unsigned char c = UDR2; if (bit_is_clear(UCSR2A, UPE2)) {
store_char(c, &rx_buffer2); unsigned char c = UDR2;
store_char(c, &rx_buffer2);
} else {
unsigned char c = UDR2;
};
} }
#elif defined(SIG_USART2_RECV) #elif defined(SIG_USART2_RECV)
#error SIG_USART2_RECV #error SIG_USART2_RECV
@ -152,8 +170,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent3_implemented #define serialEvent3_implemented
SIGNAL(USART3_RX_vect) SIGNAL(USART3_RX_vect)
{ {
unsigned char c = UDR3; if (bit_is_clear(UCSR3A, UPE3)) {
store_char(c, &rx_buffer3); unsigned char c = UDR3;
store_char(c, &rx_buffer3);
} else {
unsigned char c = UDR3;
};
} }
#elif defined(SIG_USART3_RECV) #elif defined(SIG_USART3_RECV)
#error SIG_USART3_RECV #error SIG_USART3_RECV
@ -274,7 +296,7 @@ ISR(USART3_UDRE_vect)
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr, volatile uint8_t *ucsrc, volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x) uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
{ {
_rx_buffer = rx_buffer; _rx_buffer = rx_buffer;
@ -283,6 +305,7 @@ HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
_ubrrl = ubrrl; _ubrrl = ubrrl;
_ucsra = ucsra; _ucsra = ucsra;
_ucsrb = ucsrb; _ucsrb = ucsrb;
_ucsrc = ucsrc;
_udr = udr; _udr = udr;
_rxen = rxen; _rxen = rxen;
_txen = txen; _txen = txen;
@ -335,6 +358,53 @@ try_again:
cbi(*_ucsrb, _udrie); cbi(*_ucsrb, _udrie);
} }
void HardwareSerial::begin(unsigned long baud, byte config)
{
uint16_t baud_setting;
uint8_t current_config;
bool use_u2x = true;
#if F_CPU == 16000000UL
// hardcoded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560.
if (baud == 57600) {
use_u2x = false;
}
#endif
try_again:
if (use_u2x) {
*_ucsra = 1 << _u2x;
baud_setting = (F_CPU / 4 / baud - 1) / 2;
} else {
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
if ((baud_setting > 4095) && use_u2x)
{
use_u2x = false;
goto try_again;
}
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
//set number of data bits
current_config = *_ubrrh;
current_config = *_ucsrc;
current_config |= config;
*_ucsrc = current_config;
sbi(*_ucsrb, _rxen);
sbi(*_ucsrb, _txen);
sbi(*_ucsrb, _rxcie);
cbi(*_ucsrb, _udrie);
}
void HardwareSerial::end() void HardwareSerial::end()
{ {
// wait for transmission of outgoing data // wait for transmission of outgoing data
@ -411,9 +481,9 @@ HardwareSerial::operator bool() {
// Preinstantiate Objects ////////////////////////////////////////////////////// // Preinstantiate Objects //////////////////////////////////////////////////////
#if defined(UBRRH) && defined(UBRRL) #if defined(UBRRH) && defined(UBRRL)
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X); HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
#elif defined(UBRR0H) && defined(UBRR0L) #elif defined(UBRR0H) && defined(UBRR0L)
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0); HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
#elif defined(USBCON) #elif defined(USBCON)
// do nothing - Serial object and buffers are initialized in CDC code // do nothing - Serial object and buffers are initialized in CDC code
#else #else
@ -421,13 +491,13 @@ HardwareSerial::operator bool() {
#endif #endif
#if defined(UBRR1H) #if defined(UBRR1H)
HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1); HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
#endif #endif
#if defined(UBRR2H) #if defined(UBRR2H)
HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2); HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
#endif #endif
#if defined(UBRR3H) #if defined(UBRR3H)
HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3); HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
#endif #endif
#endif // whole file #endif // whole file

View File

@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 28 September 2010 by Mark Sproul Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/ */
#ifndef HardwareSerial_h #ifndef HardwareSerial_h
@ -37,6 +38,7 @@ class HardwareSerial : public Stream
volatile uint8_t *_ubrrl; volatile uint8_t *_ubrrl;
volatile uint8_t *_ucsra; volatile uint8_t *_ucsra;
volatile uint8_t *_ucsrb; volatile uint8_t *_ucsrb;
volatile uint8_t *_ucsrc;
volatile uint8_t *_udr; volatile uint8_t *_udr;
uint8_t _rxen; uint8_t _rxen;
uint8_t _txen; uint8_t _txen;
@ -48,9 +50,10 @@ class HardwareSerial : public Stream
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr, volatile uint8_t *ucsrc, volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x); uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
void begin(unsigned long); void begin(unsigned long);
void begin(unsigned long, byte);
void end(); void end();
virtual int available(void); virtual int available(void);
virtual int peek(void); virtual int peek(void);
@ -65,6 +68,56 @@ class HardwareSerial : public Stream
operator bool(); operator bool();
}; };
// Define config for Serial.begin(baud, config);
#define _5n1_ 0x80
#define _5N1_ 0x80
#define _6n1_ 0x82
#define _6N1_ 0x82
#define _7n1_ 0x84
#define _7N1_ 0x84
#define _8n1_ 0x86
#define _8N1_ 0x86
#define _5n2_ 0x88
#define _5N2_ 0x88
#define _6n2_ 0x8A
#define _6N2_ 0x8A
#define _7n2_ 0x8C
#define _7N2_ 0x8C
#define _8n2_ 0x8E
#define _8N2_ 0x8E
#define _5e1_ 0xA0
#define _5E1_ 0xA0
#define _6e1_ 0xA2
#define _6E1_ 0xA2
#define _7e1_ 0xA4
#define _7E1_ 0xA4
#define _8e1_ 0xA6
#define _8E1_ 0xA6
#define _5e2_ 0xA8
#define _5E2_ 0xA8
#define _6e2_ 0xAA
#define _6E2_ 0xAA
#define _7e2_ 0xAC
#define _7E2_ 0xAC
#define _8e2_ 0xAE
#define _8E2_ 0xAE
#define _5o1_ 0xB0
#define _5O1_ 0xB0
#define _6o1_ 0xB2
#define _6O1_ 0xB2
#define _7o1_ 0xB4
#define _7O1_ 0xB4
#define _8o1_ 0xB6
#define _8O1_ 0xB6
#define _5o2_ 0xB8
#define _5O2_ 0xB8
#define _6o2_ 0xBA
#define _6O2_ 0xBA
#define _7o2_ 0xBC
#define _7O2_ 0xBC
#define _8o2_ 0xBE
#define _8O2_ 0xBE
#if defined(UBRRH) || defined(UBRR0H) #if defined(UBRRH) || defined(UBRR0H)
extern HardwareSerial Serial; extern HardwareSerial Serial;
#elif defined(USBCON) #elif defined(USBCON)