@@ -93,6 +93,8 @@ bool SoftwareSerial::listen()
9393 {
9494 if (active_object)
9595 active_object->stopListening ();
96+ if (_singleWirePin)
97+ setupRXPin (_singleWirePin);
9698
9799 _buffer_overflow = false ;
98100 _receive_buffer_head = _receive_buffer_tail = 0 ;
@@ -111,6 +113,8 @@ bool SoftwareSerial::stopListening()
111113 if (active_object == this )
112114 {
113115 setRxIntMsk (false );
116+ if (_singleWirePin)
117+ setupTXPin (_singleWirePin);
114118 active_object = NULL ;
115119 return true ;
116120 }
@@ -246,7 +250,8 @@ ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
246250//
247251// Constructor
248252//
249- SoftwareSerial::SoftwareSerial (uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */ ) :
253+ SoftwareSerial::SoftwareSerial (uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */ ) :
254+ _singleWirePin(receivePin == transmitPin ? receivePin : 0 ),
250255 _rx_delay_centering(0 ),
251256 _rx_delay_intrabit(0 ),
252257 _rx_delay_stopbit(0 ),
@@ -256,6 +261,9 @@ SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inv
256261{
257262 setTX (transmitPin);
258263 setRX (receivePin);
264+
265+ if (_singleWirePin)
266+ setupTXPin (_singleWirePin);
259267}
260268
261269//
@@ -266,24 +274,38 @@ SoftwareSerial::~SoftwareSerial()
266274 end ();
267275}
268276
269- void SoftwareSerial::setTX (uint8_t tx)
277+ void SoftwareSerial::setupTXPin (uint8_t tx)
270278{
271279 // First write, then set output. If we do this the other way around,
272280 // the pin would be output low for a short while before switching to
273281 // output high. Now, it is input with pullup for a short while, which
274282 // is fine. With inverse logic, either order is fine.
275283 digitalWrite (tx, _inverse_logic ? LOW : HIGH);
276284 pinMode (tx, OUTPUT);
285+ }
286+
287+ void SoftwareSerial::setTX (uint8_t tx)
288+ {
289+ if (!_singleWirePin)
290+ setupTXPin (tx);
291+
277292 _transmitBitMask = digitalPinToBitMask (tx);
278293 uint8_t port = digitalPinToPort (tx);
279294 _transmitPortRegister = portOutputRegister (port);
280295}
281296
282- void SoftwareSerial::setRX (uint8_t rx)
297+ void SoftwareSerial::setupRXPin (uint8_t rx)
283298{
284299 pinMode (rx, INPUT);
285300 if (!_inverse_logic)
286301 digitalWrite (rx, HIGH); // pullup for normal logic!
302+ }
303+
304+ void SoftwareSerial::setRX (uint8_t rx)
305+ {
306+ if (!_singleWirePin)
307+ setupRXPin (rx);
308+
287309 _receivePin = rx;
288310 _receiveBitMask = digitalPinToBitMask (rx);
289311 uint8_t port = digitalPinToPort (rx);
@@ -371,7 +393,9 @@ void SoftwareSerial::begin(long speed)
371393 pinMode (_DEBUG_PIN2, OUTPUT);
372394#endif
373395
374- listen ();
396+ // Single-wire will be in TX mode by default
397+ if (!_singleWirePin)
398+ listen ();
375399}
376400
377401void SoftwareSerial::setRxIntMsk (bool enable)
@@ -414,6 +438,9 @@ int SoftwareSerial::available()
414438
415439size_t SoftwareSerial::write (uint8_t b)
416440{
441+ if (_singleWirePin && isListening ())
442+ return 0 ;
443+
417444 if (_tx_delay == 0 ) {
418445 setWriteError ();
419446 return 0 ;
0 commit comments