diff --git a/AltSoftSerial.cpp b/AltSoftSerial.cpp index 916d056..91661e0 100644 --- a/AltSoftSerial.cpp +++ b/AltSoftSerial.cpp @@ -1,17 +1,17 @@ /* An Alternative Software Serial Library * http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html * Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -59,7 +59,7 @@ static volatile uint8_t tx_buffer_head; static volatile uint8_t tx_buffer_tail; #define TX_BUFFER_SIZE 68 static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; - +static bool invert = false; #ifndef INPUT_PULLUP #define INPUT_PULLUP INPUT @@ -67,6 +67,16 @@ static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; #define MAX_COUNTS_PER_BIT 6241 // 65536 / 10.5 +AltSoftSerial::AltSoftSerial(bool inverse) +{ + invert = inverse; +} + +AltSoftSerial::AltSoftSerial(uint8_t rxPin, uint8_t txPin, bool inverse = false) +{ + invert = inverse; +} + void AltSoftSerial::init(uint32_t cycles_per_bit) { //Serial.printf("cycles_per_bit = %d\n", cycles_per_bit); @@ -102,8 +112,12 @@ void AltSoftSerial::init(uint32_t cycles_per_bit) ticks_per_bit = cycles_per_bit; rx_stop_ticks = cycles_per_bit * 37 / 4; pinMode(INPUT_CAPTURE_PIN, INPUT_PULLUP); - digitalWrite(OUTPUT_COMPARE_A_PIN, HIGH); pinMode(OUTPUT_COMPARE_A_PIN, OUTPUT); + if (invert) { + digitalWrite(OUTPUT_COMPARE_A_PIN, LOW); + } else { + digitalWrite(OUTPUT_COMPARE_A_PIN, HIGH); + } // if-else invert rx_state = 0; rx_buffer_head = 0; rx_buffer_tail = 0; @@ -145,7 +159,11 @@ void AltSoftSerial::writeByte(uint8_t b) tx_byte = b; tx_bit = 0; ENABLE_INT_COMPARE_A(); - CONFIG_MATCH_CLEAR(); + if (invert) { + CONFIG_MATCH_SET(); + } else { + CONFIG_MATCH_CLEAR(); + } //if-else invert SET_COMPARE_A(GET_TIMER_COUNT() + 16); } SREG = intr_state; @@ -170,9 +188,17 @@ ISR(COMPARE_A_INTERRUPT) state++; if (bit != tx_bit) { if (bit) { - CONFIG_MATCH_SET(); + if (invert) { + CONFIG_MATCH_CLEAR(); + } else { + CONFIG_MATCH_SET(); + } //if-else invert } else { - CONFIG_MATCH_CLEAR(); + if (invert) { + CONFIG_MATCH_SET(); + } else { + CONFIG_MATCH_CLEAR(); + } //if-else invert } SET_COMPARE_A(target); tx_bit = bit; @@ -199,7 +225,11 @@ ISR(COMPARE_A_INTERRUPT) tx_buffer_tail = tail; tx_byte = tx_buffer[tail]; tx_bit = 0; - CONFIG_MATCH_CLEAR(); + if (invert) { + CONFIG_MATCH_SET(); + } else { + CONFIG_MATCH_CLEAR(); + } //if-else invert if (state == 10) SET_COMPARE_A(target + ticks_per_bit); else @@ -228,10 +258,18 @@ ISR(CAPTURE_INTERRUPT) capture = GET_INPUT_CAPTURE(); bit = rx_bit; if (bit) { - CONFIG_CAPTURE_FALLING_EDGE(); + if (invert) { + CONFIG_CAPTURE_RISING_EDGE(); + } else { + CONFIG_CAPTURE_FALLING_EDGE(); + } //if-else invert; rx_bit = 0; } else { - CONFIG_CAPTURE_RISING_EDGE(); + if (invert) { + CONFIG_CAPTURE_FALLING_EDGE(); + } else { + CONFIG_CAPTURE_RISING_EDGE(); + } //if-else invert rx_bit = 0x80; } state = rx_state; @@ -260,7 +298,11 @@ ISR(CAPTURE_INTERRUPT) rx_buffer[head] = rx_byte; rx_buffer_head = head; } - CONFIG_CAPTURE_FALLING_EDGE(); + if (invert) { + CONFIG_CAPTURE_RISING_EDGE(); + } else { + CONFIG_CAPTURE_FALLING_EDGE(); + } //if-else invert rx_bit = 0; rx_state = 0; return; @@ -277,7 +319,11 @@ ISR(COMPARE_B_INTERRUPT) uint8_t head, state, bit; DISABLE_INT_COMPARE_B(); - CONFIG_CAPTURE_FALLING_EDGE(); + if (invert) { + CONFIG_CAPTURE_RISING_EDGE(); + } else { + CONFIG_CAPTURE_FALLING_EDGE(); + } //if-else invert state = rx_state; bit = rx_bit ^ 0x80; while (state < 9) { @@ -291,7 +337,11 @@ ISR(COMPARE_B_INTERRUPT) rx_buffer_head = head; } rx_state = 0; - CONFIG_CAPTURE_FALLING_EDGE(); + if (invert) { + CONFIG_CAPTURE_RISING_EDGE(); + } else { + CONFIG_CAPTURE_FALLING_EDGE(); + } //if-else invert rx_bit = 0; } @@ -332,7 +382,7 @@ int AltSoftSerial::available(void) } int AltSoftSerial::availableForWrite(void) -{ +{ uint8_t head, tail; head = tx_buffer_head; tail = tx_buffer_tail; diff --git a/AltSoftSerial.h b/AltSoftSerial.h index 7860fdd..38aaa74 100644 --- a/AltSoftSerial.h +++ b/AltSoftSerial.h @@ -1,17 +1,17 @@ /* An Alternative Software Serial Library * http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html * Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -43,6 +43,7 @@ class AltSoftSerial : public Stream { public: AltSoftSerial() { } + AltSoftSerial(bool inverse); ~AltSoftSerial() { end(); } static void begin(uint32_t baud) { init((ALTSS_BASE_FREQ + baud / 2) / baud); } static void end(); @@ -61,7 +62,7 @@ class AltSoftSerial : public Stream static void flushInput(); static void flushOutput(); // for drop-in compatibility with NewSoftSerial, rxPin & txPin ignored - AltSoftSerial(uint8_t rxPin, uint8_t txPin, bool inverse = false) { (void)rxPin; (void)txPin; (void)inverse; } + // AltSoftSerial(uint8_t rxPin, uint8_t txPin, bool inverse = false); bool listen() { return false; } bool isListening() { return true; } bool overflow() { bool r = timing_error; timing_error = false; return r; }