Open AvengerIl opened 10 years ago
A small patch against 9cba024f0ba6342a00fda6e1dfa7426f009ad8ad to implement optional TX parity bit. See enum parity_type in AltSoftSerial.h
diff --git a/AltSoftSerial.cpp b/AltSoftSerial.cpp
index 72ff290..5e59f98 100644
--- a/AltSoftSerial.cpp
+++ b/AltSoftSerial.cpp
@@ -56,13 +56,14 @@ 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 enum AltSoftSerial::parity_type tx_parity_flag;
+static uint8_t tx_parity_bit;
#ifndef INPUT_PULLUP
#define INPUT_PULLUP INPUT
#endif
-void AltSoftSerial::init(uint32_t cycles_per_bit)
+void AltSoftSerial::init(uint32_t cycles_per_bit, enum parity_type parity)
{
if (cycles_per_bit < 7085) {
CONFIG_TIMER_NOPRESCALE();
@@ -85,6 +86,7 @@ void AltSoftSerial::init(uint32_t cycles_per_bit)
tx_state = 0;
tx_buffer_head = 0;
tx_buffer_tail = 0;
+ tx_parity_flag = parity;
ENABLE_INT_INPUT_CAPTURE();
}
@@ -119,6 +121,7 @@ void AltSoftSerial::writeByte(uint8_t b)
tx_state = 1;
tx_byte = b;
tx_bit = 0;
+ tx_parity_bit = 0;
ENABLE_INT_COMPARE_A();
CONFIG_MATCH_CLEAR();
SET_COMPARE_A(GET_TIMER_COUNT() + 16);
@@ -138,6 +141,7 @@ ISR(COMPARE_A_INTERRUPT)
while (state < 9) {
target += ticks_per_bit;
bit = byte & 1;
+ tx_parity_bit ^= bit;
byte >>= 1;
state++;
if (bit != tx_bit) {
@@ -154,8 +158,25 @@ ISR(COMPARE_A_INTERRUPT)
return;
}
}
- if (state == 9) {
- tx_state = 10;
+ if(state == 9) {
+ state = tx_state = 10;
+ if(tx_parity_flag != AltSoftSerial::PARITY_NONE) {
+ if(tx_parity_flag == AltSoftSerial::PARITY_ODD)
+ tx_parity_bit ^= 1;
+ else if(tx_parity_flag == AltSoftSerial::PARITY_MARK)
+ tx_parity_bit = 1;
+ else if(tx_parity_flag == AltSoftSerial::PARITY_SPACE)
+ tx_parity_bit = 0;
+ if(tx_parity_bit)
+ CONFIG_MATCH_SET();
+ else
+ CONFIG_MATCH_CLEAR();
+ SET_COMPARE_A(target + ticks_per_bit);
+ return;
+ }
+ }
+ if (state == 10) {
+ tx_state = 11;
CONFIG_MATCH_SET();
SET_COMPARE_A(target + ticks_per_bit);
return;
@@ -172,6 +193,7 @@ ISR(COMPARE_A_INTERRUPT)
tx_buffer_tail = tail;
tx_byte = tx_buffer[tail];
tx_bit = 0;
+ tx_parity_bit = 0;
CONFIG_MATCH_CLEAR();
SET_COMPARE_A(target + ticks_per_bit);
// TODO: how to detect timing_error?
diff --git a/AltSoftSerial.h b/AltSoftSerial.h
index eccb8d8..a616fc0 100644
--- a/AltSoftSerial.h
+++ b/AltSoftSerial.h
@@ -44,7 +44,14 @@ class AltSoftSerial : public Stream
public:
AltSoftSerial() { }
~AltSoftSerial() { end(); }
- static void begin(uint32_t baud) { init((ALTSS_BASE_FREQ + baud / 2) / baud); }
+ enum parity_type {
+ PARITY_NONE,
+ PARITY_EVEN,
+ PARITY_ODD,
+ PARITY_MARK,
+ PARITY_SPACE,
+ };
+ static void begin(uint32_t baud, enum parity_type parity = PARITY_NONE) { init((ALTSS_BASE_FREQ + baud / 2) / baud, parity); }
static void end();
int peek();
int read();
@@ -68,7 +75,7 @@ public:
static void enable_timer0(bool enable) { }
static bool timing_error;
private:
- static void init(uint32_t cycles_per_bit);
+ static void init(uint32_t cycles_per_bit, enum parity_type parity);
static void writeByte(uint8_t byte);
};
I would REALLY appreciate this! Looking for a Software Serial lib with variable config (Parity- Stop bits) for a long time...
Is there any chance this will be added and pulled into the library?
I fixed the patch and applied it to the specified git hash in https://github.com/lausdahl/AltSoftSerial/tree/parity I haven't had time to merge it with head of this repo yet.
I tested it with 2400 8E1 which I needed. It works as also described in the original post: https://forum.pjrc.com/threads/24199-AltSoftSerial-amp-parity-e-g-begin%289600-SERIAL_8E1%29
If I get time I might create a pull-request for it.
i've found some code of yours online that has a parity implementation. is there any chance you could commit to this repo?
re:http://forum.pjrc.com/threads/24199-AltSoftSerial-amp-parity-e-g-begin%289600-SERIAL_8E1%29
Its impossible to follow that code and make the change myself.