Created
March 30, 2015 15:37
-
-
Save narrowtux/4e8213db2b817fdfe863 to your computer and use it in GitHub Desktop.
Arduino SoftwareSerial 7E1 read support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <avr/interrupt.h> | |
#include <avr/pgmspace.h> | |
#include <Arduino.h> | |
#include <SoftwareSerial.h> | |
#ifndef SEVEN_E_1_SERIAL | |
#define SEVEN_E_1_SERIAL | |
#define _DEBUG 0 | |
#define _DEBUG_PIN1 11 | |
#define _DEBUG_PIN2 13 | |
// | |
// Debugging | |
// | |
// This function generates a brief pulse | |
// for debugging or measuring on an oscilloscope. | |
inline void DebugPulse(uint8_t pin, uint8_t count) { | |
#if _DEBUG | |
volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin)); | |
uint8_t val = *pport; | |
while (count--) | |
{ | |
*pport = val | digitalPinToBitMask(pin); | |
*pport = val; | |
} | |
#endif | |
} | |
/** | |
* Modification of the SoftwareSerial class to support reading from 7E1 serial. | |
* Does not support any other baud rate than 9600 and does also not support sending data. | |
*/ | |
class SevenE1Serial : public SoftwareSerial { | |
public: | |
SevenE1Serial(int RX, int TX) : SoftwareSerial(RX, TX) {} | |
void adjust() { | |
_rx_delay_centering = 105; | |
} | |
void recv() { | |
#if GCC_VERSION < 40302 | |
// Work-around for avr-gcc 4.3.0 OSX version bug | |
// Preserve the registers that the compiler misses | |
// (courtesy of Arduino forum user *etracer*) | |
asm volatile( | |
"push r18 \n\t" | |
"push r19 \n\t" | |
"push r20 \n\t" | |
"push r21 \n\t" | |
"push r22 \n\t" | |
"push r23 \n\t" | |
"push r26 \n\t" | |
"push r27 \n\t" | |
::); | |
#endif | |
uint8_t d = 0; | |
// If RX line is high, then we don't see any start bit | |
// so interrupt is probably not for us | |
if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) | |
{ | |
// Wait approximately 1/2 of a bit width to "center" the sample | |
tunedDelay(_rx_delay_centering); | |
DebugPulse(_DEBUG_PIN2, 1); | |
// Read each of the 7 data bits | |
for (uint8_t i=0x1; i < 0x80; i <<= 1) | |
{ | |
tunedDelay(_rx_delay_intrabit); | |
DebugPulse(_DEBUG_PIN2, 1); | |
uint8_t noti = ~i; | |
if (rx_pin_read()) { | |
d |= i; | |
} else // else clause added to ensure function timing is ~balanced | |
d &= noti; | |
} | |
// read the parity bit | |
tunedDelay(_rx_delay_intrabit); | |
bool parityBit = rx_pin_read(); | |
// skip the stop bit | |
tunedDelay(_rx_delay_stopbit); | |
DebugPulse(_DEBUG_PIN2, 1); | |
// check for parity even | |
bool parityValid = true; | |
if (parityBit != (d % 2 == 1)) { | |
parityValid = false; | |
} | |
if (_inverse_logic) | |
d = ~d; | |
// if parity valid, append byte to buffer | |
if (parityValid) { | |
// if buffer full, set the overflow flag and return | |
if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head) | |
{ | |
// save new data in buffer: tail points to where byte goes | |
_receive_buffer[_receive_buffer_tail] = d; // save new byte | |
_receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; | |
} | |
else | |
{ | |
#if _DEBUG // for scope: pulse pin as overflow indictator | |
DebugPulse(_DEBUG_PIN1, 1); | |
#endif | |
_buffer_overflow = true; | |
} | |
} | |
} | |
#if GCC_VERSION < 40302 | |
// Work-around for avr-gcc 4.3.0 OSX version bug | |
// Restore the registers that the compiler misses | |
asm volatile( | |
"pop r27 \n\t" | |
"pop r26 \n\t" | |
"pop r23 \n\t" | |
"pop r22 \n\t" | |
"pop r21 \n\t" | |
"pop r20 \n\t" | |
"pop r19 \n\t" | |
"pop r18 \n\t" | |
::); | |
#endif | |
} | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This snippet was made eight years ago, arduino development environment has probably changed so much that it wouldn't even work any more, even if it compiled.
Sadly I can't help you with that, since I don't work with arduino any more, and also I don't have a device that uses this encoding.