[SoftSerial] Half duplex support
Squash and rebase of https://github.com/arduino/Arduino/pull/4377
This commit is contained in:
parent
b084848f2e
commit
f00c1c14f3
|
@ -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);
|
||||
if(_full_duplex)
|
||||
pinMode(tx, OUTPUT);
|
||||
else
|
||||
pinMode(tx, INPUT);
|
||||
_transmitPin = tx;
|
||||
_transmitBitMask = digitalPinToBitMask(tx);
|
||||
uint8_t port = digitalPinToPort(tx);
|
||||
_transmitPortRegister = portOutputRegister(port);
|
||||
|
@ -419,6 +424,9 @@ size_t SoftwareSerial::write(uint8_t b)
|
|||
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
|
||||
// critical timing sections below, which makes it a lot easier to
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue