[SoftSerial] Half duplex support

Squash and rebase of https://github.com/arduino/Arduino/pull/4377
This commit is contained in:
peteruithoven 2017-11-13 17:18:28 +01:00 committed by Martino Facchin
parent b084848f2e
commit f00c1c14f3
2 changed files with 19 additions and 4 deletions

View File

@ -246,13 +246,14 @@ ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */, bool full_duplex /* = true */) :
_rx_delay_centering(0),
_rx_delay_intrabit(0),
_rx_delay_stopbit(0),
_tx_delay(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic)
_inverse_logic(inverse_logic),
_full_duplex(full_duplex)
{
setTX(transmitPin);
setRX(receivePin);
@ -273,7 +274,11 @@ void SoftwareSerial::setTX(uint8_t tx)
// output high. Now, it is input with pullup for a short while, which
// is fine. With inverse logic, either order is fine.
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
pinMode(tx, OUTPUT);
if(_full_duplex)
pinMode(tx, OUTPUT);
else
pinMode(tx, INPUT);
_transmitPin = tx;
_transmitBitMask = digitalPinToBitMask(tx);
uint8_t port = digitalPinToPort(tx);
_transmitPortRegister = portOutputRegister(port);
@ -418,6 +423,9 @@ size_t SoftwareSerial::write(uint8_t b)
setWriteError();
return 0;
}
if(!_full_duplex)
pinMode(_transmitPin, OUTPUT);
// By declaring these as local variables, the compiler will put them
// in registers _before_ disabling interrupts and entering the
@ -461,6 +469,11 @@ size_t SoftwareSerial::write(uint8_t b)
else
*reg |= reg_mask;
if(!_full_duplex){
pinMode(_transmitPin, INPUT);
*reg |= reg_mask; // send 1
}
SREG = oldSREG; // turn interrupts back on
tunedDelay(_tx_delay);

View File

@ -54,6 +54,7 @@ private:
uint8_t _receivePin;
uint8_t _receiveBitMask;
volatile uint8_t *_receivePortRegister;
uint8_t _transmitPin;
uint8_t _transmitBitMask;
volatile uint8_t *_transmitPortRegister;
volatile uint8_t *_pcint_maskreg;
@ -67,6 +68,7 @@ private:
uint16_t _buffer_overflow:1;
uint16_t _inverse_logic:1;
uint16_t _full_duplex:1;
// static data
static uint8_t _receive_buffer[_SS_MAX_RX_BUFF];
@ -89,7 +91,7 @@ private:
public:
// public methods
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false, bool full_duplex = true);
~SoftwareSerial();
void begin(long speed);
bool listen();