[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
|
// 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_centering(0),
|
||||||
_rx_delay_intrabit(0),
|
_rx_delay_intrabit(0),
|
||||||
_rx_delay_stopbit(0),
|
_rx_delay_stopbit(0),
|
||||||
_tx_delay(0),
|
_tx_delay(0),
|
||||||
_buffer_overflow(false),
|
_buffer_overflow(false),
|
||||||
_inverse_logic(inverse_logic)
|
_inverse_logic(inverse_logic),
|
||||||
|
_full_duplex(full_duplex)
|
||||||
{
|
{
|
||||||
setTX(transmitPin);
|
setTX(transmitPin);
|
||||||
setRX(receivePin);
|
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
|
// output high. Now, it is input with pullup for a short while, which
|
||||||
// is fine. With inverse logic, either order is fine.
|
// is fine. With inverse logic, either order is fine.
|
||||||
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
|
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
|
||||||
|
if(_full_duplex)
|
||||||
pinMode(tx, OUTPUT);
|
pinMode(tx, OUTPUT);
|
||||||
|
else
|
||||||
|
pinMode(tx, INPUT);
|
||||||
|
_transmitPin = tx;
|
||||||
_transmitBitMask = digitalPinToBitMask(tx);
|
_transmitBitMask = digitalPinToBitMask(tx);
|
||||||
uint8_t port = digitalPinToPort(tx);
|
uint8_t port = digitalPinToPort(tx);
|
||||||
_transmitPortRegister = portOutputRegister(port);
|
_transmitPortRegister = portOutputRegister(port);
|
||||||
|
@ -419,6 +424,9 @@ size_t SoftwareSerial::write(uint8_t b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_full_duplex)
|
||||||
|
pinMode(_transmitPin, OUTPUT);
|
||||||
|
|
||||||
// By declaring these as local variables, the compiler will put them
|
// By declaring these as local variables, the compiler will put them
|
||||||
// in registers _before_ disabling interrupts and entering the
|
// in registers _before_ disabling interrupts and entering the
|
||||||
// critical timing sections below, which makes it a lot easier to
|
// critical timing sections below, which makes it a lot easier to
|
||||||
|
@ -461,6 +469,11 @@ size_t SoftwareSerial::write(uint8_t b)
|
||||||
else
|
else
|
||||||
*reg |= reg_mask;
|
*reg |= reg_mask;
|
||||||
|
|
||||||
|
if(!_full_duplex){
|
||||||
|
pinMode(_transmitPin, INPUT);
|
||||||
|
*reg |= reg_mask; // send 1
|
||||||
|
}
|
||||||
|
|
||||||
SREG = oldSREG; // turn interrupts back on
|
SREG = oldSREG; // turn interrupts back on
|
||||||
tunedDelay(_tx_delay);
|
tunedDelay(_tx_delay);
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
uint8_t _receivePin;
|
uint8_t _receivePin;
|
||||||
uint8_t _receiveBitMask;
|
uint8_t _receiveBitMask;
|
||||||
volatile uint8_t *_receivePortRegister;
|
volatile uint8_t *_receivePortRegister;
|
||||||
|
uint8_t _transmitPin;
|
||||||
uint8_t _transmitBitMask;
|
uint8_t _transmitBitMask;
|
||||||
volatile uint8_t *_transmitPortRegister;
|
volatile uint8_t *_transmitPortRegister;
|
||||||
volatile uint8_t *_pcint_maskreg;
|
volatile uint8_t *_pcint_maskreg;
|
||||||
|
@ -67,6 +68,7 @@ private:
|
||||||
|
|
||||||
uint16_t _buffer_overflow:1;
|
uint16_t _buffer_overflow:1;
|
||||||
uint16_t _inverse_logic:1;
|
uint16_t _inverse_logic:1;
|
||||||
|
uint16_t _full_duplex:1;
|
||||||
|
|
||||||
// static data
|
// static data
|
||||||
static uint8_t _receive_buffer[_SS_MAX_RX_BUFF];
|
static uint8_t _receive_buffer[_SS_MAX_RX_BUFF];
|
||||||
|
@ -89,7 +91,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// public methods
|
// 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();
|
~SoftwareSerial();
|
||||||
void begin(long speed);
|
void begin(long speed);
|
||||||
bool listen();
|
bool listen();
|
||||||
|
|
Loading…
Reference in New Issue