From 9cd3985f2170334033c4c6b3b8037c205b60124e Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Sat, 6 Feb 2016 18:18:15 -0800 Subject: [PATCH] Support slower baud rates --- AltSoftSerial.cpp | 35 ++++++++++++++++++++++++---- config/AltSoftSerial_Timers.h | 10 ++++++++ examples/ReceiveTest/ReceiveTest.ino | 5 +++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/AltSoftSerial.cpp b/AltSoftSerial.cpp index d6f38ec..86061cc 100644 --- a/AltSoftSerial.cpp +++ b/AltSoftSerial.cpp @@ -21,6 +21,9 @@ * THE SOFTWARE. */ +// Revisions are now tracked on GitHub +// https://github.com/PaulStoffregen/AltSoftSerial +// // Version 1.2: Support Teensy 3.x // // Version 1.1: Improve performance in receiver code @@ -62,16 +65,38 @@ static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; #define INPUT_PULLUP INPUT #endif +#define MAX_COUNTS_PER_BIT 6241 // 65536 / 10.5 + void AltSoftSerial::init(uint32_t cycles_per_bit) { - if (cycles_per_bit < 7085) { + //Serial.printf("cycles_per_bit = %d\n", cycles_per_bit); + if (cycles_per_bit < MAX_COUNTS_PER_BIT) { CONFIG_TIMER_NOPRESCALE(); } else { cycles_per_bit /= 8; - if (cycles_per_bit < 7085) { + //Serial.printf("cycles_per_bit/8 = %d\n", cycles_per_bit); + if (cycles_per_bit < MAX_COUNTS_PER_BIT) { CONFIG_TIMER_PRESCALE_8(); } else { - return; // minimum 283 baud at 16 MHz clock +#if defined(CONFIG_TIMER_PRESCALE_256) + cycles_per_bit /= 32; + //Serial.printf("cycles_per_bit/256 = %d\n", cycles_per_bit); + if (cycles_per_bit < MAX_COUNTS_PER_BIT) { + CONFIG_TIMER_PRESCALE_256(); + } else { + return; // baud rate too low for AltSoftSerial + } +#elif defined(CONFIG_TIMER_PRESCALE_128) + cycles_per_bit /= 16; + //Serial.printf("cycles_per_bit/128 = %d\n", cycles_per_bit); + if (cycles_per_bit < MAX_COUNTS_PER_BIT) { + CONFIG_TIMER_PRESCALE_128(); + } else { + return; // baud rate too low for AltSoftSerial + } +#else + return; // baud rate too low for AltSoftSerial +#endif } } ticks_per_bit = cycles_per_bit; @@ -194,7 +219,6 @@ void AltSoftSerial::flushOutput(void) /** Reception **/ /****************************************/ - ISR(CAPTURE_INTERRUPT) { uint8_t state, bit, head; @@ -213,7 +237,8 @@ ISR(CAPTURE_INTERRUPT) state = rx_state; if (state == 0) { if (!bit) { - SET_COMPARE_B(capture + rx_stop_ticks); + uint16_t end = capture + rx_stop_ticks; + SET_COMPARE_B(end); ENABLE_INT_COMPARE_B(); rx_target = capture + ticks_per_bit + ticks_per_bit/2; rx_state = 1; diff --git a/config/AltSoftSerial_Timers.h b/config/AltSoftSerial_Timers.h index 86cd4d9..16df5b8 100644 --- a/config/AltSoftSerial_Timers.h +++ b/config/AltSoftSerial_Timers.h @@ -24,6 +24,7 @@ #if defined(ALTSS_USE_TIMER1) #define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<