diff options
author | David A. Mellis <d.mellis@arduino.cc> | 2009-07-12 02:58:59 +0000 |
---|---|---|
committer | David A. Mellis <d.mellis@arduino.cc> | 2009-07-12 02:58:59 +0000 |
commit | 12ea12d14cfe1c7ae208651210a0cb1f73c5977f (patch) | |
tree | 77d36c1b7d285fc5a8ee034cb1c61ce7c3cf2e44 | |
parent | 2fc32fc3411472151ce5d0e19ec42440e0c8ed3d (diff) |
Adding improved baud rate calculation, including use (or not) of the U2X bit. (Code from gabebear).
-rwxr-xr-x | cores/arduino/HardwareSerial.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index d7a2d6e..1af6a66 100755 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -128,11 +128,38 @@ HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, // Public Methods ////////////////////////////////////////////////////////////// -void HardwareSerial::begin(long speed) +void HardwareSerial::begin(long baud) { - *_ubrrh = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8; - *_ubrrl = ((F_CPU / 16 + speed / 2) / speed - 1); - cbi(*_ucsra, _u2x); + uint16_t baud_setting; + bool use_u2x; + + // U2X mode is needed for baud rates higher than (CPU Hz / 16) + if (baud > F_CPU / 16) { + use_u2x = true; + } else { + // figure out if U2X mode would allow for a better connection + + // calculate the percent difference between the baud-rate specified and + // the real baud rate for both U2X and non-U2X mode (0-255 error percent) + uint8_t nonu2x_baud_error = abs((int)(255-((F_CPU/(16*(((F_CPU/8/baud-1)/2)+1))*255)/baud))); + uint8_t u2x_baud_error = abs((int)(255-((F_CPU/(8*(((F_CPU/4/baud-1)/2)+1))*255)/baud))); + + // prefer non-U2X mode because it handles clock skew better + use_u2x = (nonu2x_baud_error > u2x_baud_error); + } + + 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; + } + + // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) + *_ubrrh = baud_setting >> 8; + *_ubrrl = baud_setting; + sbi(*_ucsrb, _rxen); sbi(*_ucsrb, _txen); sbi(*_ucsrb, _rxcie); |