Skip to content

New Serial.begin(baud, config); #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 30, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 85 additions & 15 deletions hardware/arduino/cores/arduino/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

Modified 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/

#include <stdlib.h>
Expand Down Expand Up @@ -109,13 +110,22 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#endif
{
#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)
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
#error UDR not defined
#endif
store_char(c, &rx_buffer);
}
#endif
#endif
Expand All @@ -126,8 +136,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent1_implemented
SIGNAL(USART1_RX_vect)
{
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
if (bit_is_clear(UCSR1A, UPE1)) {
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
} else {
unsigned char c = UDR1;
};
}
#elif defined(SIG_USART1_RECV)
#error SIG_USART1_RECV
Expand All @@ -139,8 +153,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent2_implemented
SIGNAL(USART2_RX_vect)
{
unsigned char c = UDR2;
store_char(c, &rx_buffer2);
if (bit_is_clear(UCSR2A, UPE2)) {
unsigned char c = UDR2;
store_char(c, &rx_buffer2);
} else {
unsigned char c = UDR2;
};
}
#elif defined(SIG_USART2_RECV)
#error SIG_USART2_RECV
Expand All @@ -152,8 +170,12 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
#define serialEvent3_implemented
SIGNAL(USART3_RX_vect)
{
unsigned char c = UDR3;
store_char(c, &rx_buffer3);
if (bit_is_clear(UCSR3A, UPE3)) {
unsigned char c = UDR3;
store_char(c, &rx_buffer3);
} else {
unsigned char c = UDR3;
};
}
#elif defined(SIG_USART3_RECV)
#error SIG_USART3_RECV
Expand Down Expand Up @@ -274,7 +296,7 @@ ISR(USART3_UDRE_vect)
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
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)
{
_rx_buffer = rx_buffer;
Expand All @@ -283,6 +305,7 @@ HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
_ubrrl = ubrrl;
_ucsra = ucsra;
_ucsrb = ucsrb;
_ucsrc = ucsrc;
_udr = udr;
_rxen = rxen;
_txen = txen;
Expand Down Expand Up @@ -333,6 +356,53 @@ void HardwareSerial::begin(unsigned long baud)
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()
{
// wait for transmission of outgoing data
Expand Down Expand Up @@ -405,23 +475,23 @@ HardwareSerial::operator bool() {
// Preinstantiate Objects //////////////////////////////////////////////////////

#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)
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)
// do nothing - Serial object and buffers are initialized in CDC code
#else
#error no serial port defined (port 0)
#endif

#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
#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
#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 // whole file
Expand Down
55 changes: 54 additions & 1 deletion hardware/arduino/cores/arduino/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/

#ifndef HardwareSerial_h
Expand All @@ -37,6 +38,7 @@ class HardwareSerial : public Stream
volatile uint8_t *_ubrrl;
volatile uint8_t *_ucsra;
volatile uint8_t *_ucsrb;
volatile uint8_t *_ucsrc;
volatile uint8_t *_udr;
uint8_t _rxen;
uint8_t _txen;
Expand All @@ -47,9 +49,10 @@ class HardwareSerial : public Stream
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
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);
void begin(unsigned long);
void begin(unsigned long, byte);
void end();
virtual int available(void);
virtual int peek(void);
Expand All @@ -60,6 +63,56 @@ class HardwareSerial : public Stream
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)
extern HardwareSerial Serial;
#elif defined(USBCON)
Expand Down