From 4c5bcabc55c5037e313b71440ef18813ffc38698 Mon Sep 17 00:00:00 2001 From: Anthony Chiam <31916150+ultimate1112@users.noreply.github.com> Date: Sat, 22 Sep 2018 22:48:04 +1000 Subject: [PATCH 1/3] Update of Readme.MD Explanation of ISRN definition --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cf13a90..d9300db 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Arduino library for SBUS (Futaba) SBUS library supports synchronous (blocking) or asynchronous (non-blocking) decoding of Futaba SBUS **without** requiring a **TTL inverter**. -SBUS uses the TIMER 2 and the Pin Change interrupt. It doesn't use UARTs, so those pins can be used: +SBUS uses the TIMER 0 and the Pin Change interrupt. It doesn't use UARTs, so those pins can be used: ``` Arduino Uno/Nano/Mini: All pins are usable Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), @@ -59,6 +59,34 @@ void loop() { sbus.waitFrame() needs to be called. It returns "false" on timeout (default is 2 seconds). sbus.waitFrame() waits for the next frame the returns. +===== Additional Notes ===== +Thank you to fdivitto. You're work is awesome! + +Supported Pins +For unlisted boards, +1. Check the interrupt vector table for listing of PCINTx_vect +2. Chip pinouts for PCINTx, corresponding to PCINTx_vect +3. TIMER0 is an 8-bit timer + +ATMega328P (Uno, Nano): +ISRN(0): D8,D9,D10,D11,D12,D13 +ISRN(1): A0,A1,A2,A3,A4,A5,D0,D1 +ISRN(2): D2,D3,D4,D5,D6,D7 +VERIFIED 8-BIT TIMER ON TC0 and TC2 + +ATMega32u4 (Leonardo, Micro): +ISRN(0): SS(PB0),SCK(PB1),MOSI(PB2),MISO(PB3),8,9,10,11 +VERIFIED 8BIT TIMER ON TC0 + +ATMega2560 (Mega2560): +ISRN(0): SS(PB0),SCK(PB1),MOSI(PB2),MISO(PB3),D1,D10,D11,D12,D13 +ISRN(1): D0,D15,D14 +ISRN(2): A8,A9,A10,A11,A12,A13,A14,A15 +VERIFIED 8-BIT TIMER ON TC0 + +===== CHANGES ===== +Changed TIMER2 to TIMER0 for support for more boards; especially the ATMega32u4 +Conditional ISR for PinChangeInterrupt, since the smaller boards only have PCINT0_vect interrupt vector. From d5966affad21f2984b0f436c183c778841577528 Mon Sep 17 00:00:00 2001 From: Anthony Chiam <31916150+ultimate1112@users.noreply.github.com> Date: Sat, 22 Sep 2018 22:54:38 +1000 Subject: [PATCH 2/3] Update sbus.cpp Replaced TIMER2 with TIMER0 (should be same functionality for ATMega328 series, added support for 32u4 and possibly other boards) Conditional #define statement for ISRN, due to differences in the PCINTx_vect interrupt vectors. --- sbus.cpp | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/sbus.cpp b/sbus.cpp index 2287807..c69a12f 100644 --- a/sbus.cpp +++ b/sbus.cpp @@ -2,6 +2,7 @@ sbus.cpp Copyright (c) 2017, Fabrizio Di Vittorio (fdivitto2013@gmail.com) + Edited by ultimate1112. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,7 +22,7 @@ #include "sbus.h" -// quick IO functions +// Quick IO functions #define portOfPin(P) portOutputRegister(digitalPinToPort(P)) #define ddrOfPin(P) portModeRegister(digitalPinToPort(P)) #define pinOfPin(P) portInputRegister(digitalPinToPort(P)) @@ -89,10 +90,17 @@ inline void disablePinChangeInterrupts() } -// handle pin change interrupt here +// Handle pin change interrupt here static void handleInterrupt(); #define ISRN(N) ISR(PCINT ## N ## _vect) { if (s_PCICRMask == 1 << (N)) handleInterrupt(); } -ISRN(0) ISRN(1) ISRN(2) + +// Define Pin Change Interrupts for specific board +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__) + ISRN(0) ISRN(1) ISRN(2) +#else + // Fall back to PCINT[0-7] + ISRN(0) +#endif static void handleInterrupt() { @@ -100,31 +108,31 @@ static void handleInterrupt() // start bit? if (pinGet(s_pin, s_pinMask)) { - // reset timer 2 counter - TCNT2 = 0; + // reset timer 0 counter + TCNT0 = 0; disablePinChangeInterrupts(); // start bit received uint8_t receivingWord = 0; - // reset OCF2A flag by writing "1" - TIFR2 |= 1 << OCF2A; + // reset OCF0A flag by writing "1" + TIFR0 |= 1 << OCF0A; uint8_t parity = 0xFF; // receive other bits (including parity bit, ignore stop bits) for (uint8_t receivedBitIndex = 0; receivedBitIndex < 9; ++receivedBitIndex) { - // wait for TCNT2 == OCR2A + // wait for TCNT0 == OCR0A // warn: inside this loop interrupts are re-enabled to allow other libraries to work correctly (ie Servo library) interrupts(); - while (!(TIFR2 & (1 << OCF2A))) + while (!(TIFR0 & (1 << OCF0A))) ; noInterrupts(); - // reset OCF2A flag by writing "1" - TIFR2 |= 1 << OCF2A; + // reset OCF0A flag by writing "1" + TIFR0 |= 1 << OCF0A; // sample current bit if (pinGet(s_pin, s_pinMask)) @@ -272,17 +280,17 @@ void SBUS::begin(uint8_t pin, mode_t mode) s_pinMask = pinMask(pin); s_PCICRMask = 1 << digitalPinToPCICRbit(pin); - //// setup TIMER 2 CTC + //// setup TIMER 0 CTC // select "Clear Timer on Compare (CTC)" mode - TCCR2A = 1 << WGM21; + TCCR0A = 1 << WGM01; // no prescaling - TCCR2B = 1 << CS20; + TCCR0B = 1 << CS00; - // set TOP timer 2 value + // set TOP timer 0 value // with no-prescaler 1/16000000=0.00000000625, each bit requires 10us, so reset timer 2 every 10us, so reset timer every 10/0.0625 = 160 ticks - OCR2A = F_CPU / 1000000 * 10 - 1; // for 16MHz = 159; + OCR0A = F_CPU / 1000000 * 10 - 1; // for 16MHz = 159; //// setup pin change interrupt From 2411d6c2f7775496e6f259f3d9c339f77c24b385 Mon Sep 17 00:00:00 2001 From: Anthony Chiam <31916150+ultimate1112@users.noreply.github.com> Date: Sat, 22 Sep 2018 22:55:35 +1000 Subject: [PATCH 3/3] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9300db..16104b7 100755 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ sbus.waitFrame() needs to be called. It returns "false" on timeout (default is 2 ===== Additional Notes ===== -Thank you to fdivitto. You're work is awesome! +Thank you to fdivitto. Your work is awesome! Supported Pins For unlisted boards,