Skip to content

Commit

Permalink
Support slower baud rates
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulStoffregen committed Feb 7, 2016
1 parent c2ffb99 commit 9cd3985
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
35 changes: 30 additions & 5 deletions AltSoftSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -194,7 +219,6 @@ void AltSoftSerial::flushOutput(void)
/** Reception **/
/****************************************/


ISR(CAPTURE_INTERRUPT)
{
uint8_t state, bit, head;
Expand All @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions config/AltSoftSerial_Timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#if defined(ALTSS_USE_TIMER1)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS10))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS11))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK1 = 0, TCCR1A = 0, TCCR1B = (1<<ICNC1) | (1<<CS12))
#define CONFIG_MATCH_NORMAL() (TCCR1A = TCCR1A & ~((1<<COM1A1) | (1<<COM1A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1A0))
#define CONFIG_MATCH_CLEAR() (TCCR1A = (TCCR1A | (1<<COM1A1)) & ~(1<<COM1A0))
Expand All @@ -50,6 +51,7 @@
#elif defined(ALTSS_USE_TIMER3)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS30))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS31))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK3 = 0, TCCR3A = 0, TCCR3B = (1<<ICNC3) | (1<<CS32))
#define CONFIG_MATCH_NORMAL() (TCCR3A = TCCR3A & ~((1<<COM3A1) | (1<<COM3A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR3A = (TCCR3A & ~(1<<COM3A1)) | (1<<COM3A0))
#define CONFIG_MATCH_CLEAR() (TCCR3A = (TCCR3A | (1<<COM3A1)) & ~(1<<COM3A0))
Expand All @@ -76,6 +78,7 @@
#elif defined(ALTSS_USE_TIMER4)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS40))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS41))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK4 = 0, TCCR4A = 0, TCCR4B = (1<<ICNC4) | (1<<CS42))
#define CONFIG_MATCH_NORMAL() (TCCR4A = TCCR4A & ~((1<<COM4A1) | (1<<COM4A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR4A = (TCCR4A & ~(1<<COM4A1)) | (1<<COM4A0))
#define CONFIG_MATCH_CLEAR() (TCCR4A = (TCCR4A | (1<<COM4A1)) & ~(1<<COM4A0))
Expand All @@ -102,6 +105,7 @@
#elif defined(ALTSS_USE_TIMER5)
#define CONFIG_TIMER_NOPRESCALE() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS50))
#define CONFIG_TIMER_PRESCALE_8() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS51))
#define CONFIG_TIMER_PRESCALE_256() (TIMSK5 = 0, TCCR5A = 0, TCCR5B = (1<<ICNC5) | (1<<CS52))
#define CONFIG_MATCH_NORMAL() (TCCR5A = TCCR5A & ~((1<<COM5A1) | (1<<COM5A0)))
#define CONFIG_MATCH_TOGGLE() (TCCR5A = (TCCR5A & ~(1<<COM5A1)) | (1<<COM5A0))
#define CONFIG_MATCH_CLEAR() (TCCR5A = (TCCR5A | (1<<COM5A1)) & ~(1<<COM5A0))
Expand Down Expand Up @@ -141,6 +145,12 @@
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
FTM0_C0SC = 0x18; \
NVIC_ENABLE_IRQ(IRQ_FTM0);
#define CONFIG_TIMER_PRESCALE_128() FTM0_SC = 0; FTM0_CNT = 0; FTM0_MOD = 0xFFFF; \
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(7); \
digitalWriteFast(21, HIGH); \
NVIC_SET_PRIORITY(IRQ_FTM0, 48); \
FTM0_C0SC = 0x18; \
NVIC_ENABLE_IRQ(IRQ_FTM0);
#define CONFIG_MATCH_NORMAL() (FTM0_C6SC = 0)
#define CONFIG_MATCH_TOGGLE() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x14)
#define CONFIG_MATCH_CLEAR() (FTM0_C6SC = (FTM0_C6SC & 0xC3) | 0x18)
Expand Down
5 changes: 4 additions & 1 deletion examples/ReceiveTest/ReceiveTest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

AltSoftSerial altser;
const int mybaud = 9600;

// Board Serial1 TX AltSoftSerial RX
// ----- ---------- ----------------
// Teensy 3.x 1 20
Expand All @@ -17,6 +17,9 @@ const int mybaud = 9600;
// Arduino Leonardo 1 13
// Arduino Mega 18 48

// Serial1 on AVR @ 16 MHz minimum baud is 245
// Serial1 on Teensy 3.2 @ 96 MHz minimum baud is 733

byte sentbyte;
unsigned long prevmillis;
byte testbyte=0xF0;
Expand Down

0 comments on commit 9cd3985

Please sign in to comment.