Skip to content

Commit 8d9d01e

Browse files
authored
Implement tx open drain. (#239)
1 parent dead84f commit 8d9d01e

File tree

4 files changed

+55
-25
lines changed

4 files changed

+55
-25
lines changed

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "EspSoftwareSerial",
3-
"version": "6.16.1",
3+
"version": "6.17.0",
44
"description": "Implementation of the Arduino software serial for ESP8266/ESP32.",
55
"keywords": [
66
"serial", "io", "softwareserial"

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=EspSoftwareSerial
2-
version=6.16.1
2+
version=6.17.0
33
author=Dirk Kaar, Peter Lerup
44
maintainer=Dirk Kaar <dok@dok-net.net>
55
sentence=Implementation of the Arduino software serial for ESP8266/ESP32.

src/SoftwareSerial.cpp

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ constexpr uint8_t BYTE_ALL_BITS_SET = ~static_cast<uint8_t>(0);
5151

5252
SoftwareSerial::SoftwareSerial() {
5353
m_isrOverflow = false;
54-
m_rxGPIOPullupEnabled = true;
54+
m_rxGPIOPullUpEnabled = true;
55+
m_txGPIOOpenDrain = false;
5556
}
5657

5758
SoftwareSerial::SoftwareSerial(int8_t rxPin, int8_t txPin, bool invert)
5859
{
5960
m_isrOverflow = false;
60-
m_rxGPIOPullupEnabled = true;
61+
m_rxGPIOPullUpEnabled = true;
62+
m_txGPIOOpenDrain = false;
6163
m_rxPin = rxPin;
6264
m_txPin = txPin;
6365
m_invert = invert;
@@ -67,7 +69,10 @@ SoftwareSerial::~SoftwareSerial() {
6769
end();
6870
}
6971

70-
bool SoftwareSerial::isValidGPIOpin(int8_t pin) {
72+
#if __GNUC__ >= 10
73+
constexpr
74+
#endif
75+
bool SoftwareSerial::isValidGPIOpin(int8_t pin) const {
7176
#if defined(ESP8266)
7277
return (pin >= 0 && pin <= 16) && !isFlashInterfacePin(pin);
7378
#elif defined(ESP32)
@@ -97,15 +102,21 @@ bool SoftwareSerial::isValidGPIOpin(int8_t pin) {
97102
#endif
98103
}
99104

100-
bool SoftwareSerial::isValidRxGPIOpin(int8_t pin) {
105+
#if __GNUC__ >= 10
106+
constexpr
107+
#endif
108+
bool SoftwareSerial::isValidRxGPIOpin(int8_t pin) const {
101109
return isValidGPIOpin(pin)
102110
#if defined(ESP8266)
103111
&& (pin != 16)
104112
#endif
105113
;
106114
}
107115

108-
bool SoftwareSerial::isValidTxGPIOpin(int8_t pin) {
116+
#if __GNUC__ >= 10
117+
constexpr
118+
#endif
119+
bool SoftwareSerial::isValidTxGPIOpin(int8_t pin) const {
109120
return isValidGPIOpin(pin)
110121
#if defined(ESP32)
111122
#ifdef CONFIG_IDF_TARGET_ESP32
@@ -119,7 +130,10 @@ bool SoftwareSerial::isValidTxGPIOpin(int8_t pin) {
119130
;
120131
}
121132

122-
bool SoftwareSerial::hasRxGPIOPullUp(int8_t pin) {
133+
#if __GNUC__ >= 10
134+
constexpr
135+
#endif
136+
bool SoftwareSerial::hasRxGPIOPullUp(int8_t pin) const {
123137
#if defined(ESP32)
124138
return !(pin >= 34 && pin <= 39);
125139
#else
@@ -128,9 +142,15 @@ bool SoftwareSerial::hasRxGPIOPullUp(int8_t pin) {
128142
#endif
129143
}
130144

131-
void SoftwareSerial::setRxGPIOPullUp() {
145+
void SoftwareSerial::setRxGPIOPinMode() {
132146
if (m_rxValid) {
133-
pinMode(m_rxPin, hasRxGPIOPullUp(m_rxPin) && m_rxGPIOPullupEnabled ? INPUT_PULLUP : INPUT);
147+
pinMode(m_rxPin, hasRxGPIOPullUp(m_rxPin) && m_rxGPIOPullUpEnabled ? INPUT_PULLUP : INPUT);
148+
}
149+
}
150+
151+
void SoftwareSerial::setTxGPIOPinMode() {
152+
if (m_txValid) {
153+
pinMode(m_txPin, m_txGPIOOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
134154
}
135155
}
136156

@@ -160,7 +180,7 @@ void SoftwareSerial::begin(uint32_t baud, SoftwareSerialConfig config,
160180
isrBufCapacity : m_buffer->capacity() * (2 + m_dataBits + static_cast<bool>(m_parityMode))));
161181
if (m_buffer && (!m_parityMode || m_parityBuffer) && m_isrBuffer) {
162182
m_rxValid = true;
163-
setRxGPIOPullUp();
183+
setRxGPIOPinMode();
164184
}
165185
}
166186
if (isValidTxGPIOpin(m_txPin)) {
@@ -170,7 +190,7 @@ void SoftwareSerial::begin(uint32_t baud, SoftwareSerialConfig config,
170190
m_txBitMask = digitalPinToBitMask(m_txPin);
171191
m_txValid = true;
172192
if (!m_oneWire) {
173-
pinMode(m_txPin, OUTPUT);
193+
setTxGPIOPinMode();
174194
digitalWrite(m_txPin, !m_invert);
175195
}
176196
}
@@ -210,20 +230,25 @@ void SoftwareSerial::enableIntTx(bool on) {
210230
m_intTxEnabled = on;
211231
}
212232

213-
void SoftwareSerial::enableRxGPIOPullup(bool on) {
214-
m_rxGPIOPullupEnabled = on;
215-
setRxGPIOPullUp();
233+
void SoftwareSerial::enableRxGPIOPullUp(bool on) {
234+
m_rxGPIOPullUpEnabled = on;
235+
setRxGPIOPinMode();
236+
}
237+
238+
void SoftwareSerial::enableTxGPIOOpenDrain(bool on) {
239+
m_txGPIOOpenDrain = on;
240+
setTxGPIOPinMode();
216241
}
217242

218243
void SoftwareSerial::enableTx(bool on) {
219244
if (m_txValid && m_oneWire) {
220245
if (on) {
221246
enableRx(false);
222-
pinMode(m_txPin, OUTPUT);
247+
setTxGPIOPinMode();
223248
digitalWrite(m_txPin, !m_invert);
224249
}
225250
else {
226-
setRxGPIOPullUp();
251+
setRxGPIOPinMode();
227252
enableRx(true);
228253
}
229254
}

src/SoftwareSerial.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,10 @@ class SoftwareSerial : public Stream {
124124
void setTransmitEnablePin(int8_t txEnablePin);
125125
/// Enable (default) or disable interrupts during tx.
126126
void enableIntTx(bool on);
127-
/// Enable (default) or disable internal rx GPIO pullup.
128-
void enableRxGPIOPullup(bool on);
127+
/// Enable (default) or disable internal rx GPIO pull-up.
128+
void enableRxGPIOPullUp(bool on);
129+
/// Enable or disable (default) tx GPIO output mode.
130+
void enableTxGPIOOpenDrain(bool on);
129131

130132
bool overflow();
131133

@@ -221,13 +223,15 @@ class SoftwareSerial : public Stream {
221223
// If offCycle == 0, the level remains unchanged from dutyCycle.
222224
void writePeriod(
223225
uint32_t dutyCycle, uint32_t offCycle, bool withStopBit);
224-
bool isValidGPIOpin(int8_t pin);
225-
bool isValidRxGPIOpin(int8_t pin);
226-
bool isValidTxGPIOpin(int8_t pin);
226+
constexpr bool isValidGPIOpin(int8_t pin) const;
227+
constexpr bool isValidRxGPIOpin(int8_t pin) const;
228+
constexpr bool isValidTxGPIOpin(int8_t pin) const;
227229
// result is only defined for a valid Rx GPIO pin
228-
bool hasRxGPIOPullUp(int8_t pin);
230+
constexpr bool hasRxGPIOPullUp(int8_t pin) const;
229231
// safely set the pin mode for the Rx GPIO pin
230-
void setRxGPIOPullUp();
232+
void setRxGPIOPinMode();
233+
// safely set the pin mode for the Tx GPIO pin
234+
void setTxGPIOPinMode();
231235
/* check m_rxValid that calling is safe */
232236
void rxBits();
233237
void rxBits(const uint32_t isrTick);
@@ -264,7 +268,8 @@ class SoftwareSerial : public Stream {
264268
/// PDU bits include data, parity and stop bits; the start bit is not counted.
265269
uint8_t m_pduBits;
266270
bool m_intTxEnabled;
267-
bool m_rxGPIOPullupEnabled;
271+
bool m_rxGPIOPullUpEnabled;
272+
bool m_txGPIOOpenDrain;
268273
SoftwareSerialParity m_parityMode;
269274
uint8_t m_stopBits;
270275
bool m_lastReadParity;

0 commit comments

Comments
 (0)