Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parity #5

Open
AvengerIl opened this issue Jul 27, 2014 · 4 comments
Open

parity #5

AvengerIl opened this issue Jul 27, 2014 · 4 comments

Comments

@AvengerIl
Copy link

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.

@aCaB
Copy link

aCaB commented Dec 19, 2014

A small patch against 9cba024 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);
 };

@igittigitt
Copy link

I would REALLY appreciate this! Looking for a Software Serial lib with variable config (Parity- Stop bits) for a long time...

@SRGDamia1
Copy link
Contributor

Is there any chance this will be added and pulled into the library?

lausdahl added a commit to lausdahl/AltSoftSerial that referenced this issue Oct 29, 2018
@lausdahl
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants