@@ -69,18 +69,15 @@ SoftwareSerial::~SoftwareSerial() {
69
69
end ();
70
70
}
71
71
72
- #if __GNUC__ >= 10
73
- constexpr
74
- #endif
75
- bool SoftwareSerial::isValidGPIOpin (int8_t pin) const {
72
+ constexpr bool SoftwareSerial::isValidGPIOpin (int8_t pin) {
76
73
#if defined(ESP8266)
77
74
return (pin >= 0 && pin <= 16 ) && !isFlashInterfacePin (pin);
78
75
#elif defined(ESP32)
79
76
// Remove the strapping pins as defined in the datasheets, they affect bootup and other critical operations
80
77
// Remmove the flash memory pins on related devices, since using these causes memory access issues.
81
78
#ifdef CONFIG_IDF_TARGET_ESP32
82
79
// Datasheet https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf,
83
- // Pinout https://docs.espressif.com/projects/esp-idf/en/latest/esp32/_images/esp32-devkitC-v4-pinout.jpg
80
+ // Pinout https://docs.espressif.com/projects/esp-idf/en/latest/esp32/_images/esp32-devkitC-v4-pinout.jpg
84
81
return (pin == 1 ) || (pin >= 3 && pin <= 5 ) ||
85
82
(pin >= 12 && pin <= 15 ) ||
86
83
(!psramFound () && pin >= 16 && pin <= 17 ) ||
@@ -91,32 +88,26 @@ bool SoftwareSerial::isValidGPIOpin(int8_t pin) const {
91
88
// Pinout https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/_images/esp32-s2_saola1-pinout.jpg
92
89
return (pin >= 1 && pin <= 21 ) || (pin >= 33 && pin <= 44 );
93
90
#elif CONFIG_IDF_TARGET_ESP32C3
94
- // Datasheet https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf,
91
+ // Datasheet https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf,
95
92
// Pinout https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/_images/esp32-c3-devkitm-1-v1-pinout.jpg
96
93
return (pin >= 0 && pin <= 1 ) || (pin >= 3 && pin <= 7 ) || (pin >= 18 && pin <= 21 );
97
- #else
94
+ #else
98
95
return pin >= 0 ;
99
96
#endif
100
97
#else
101
98
return pin >= 0 ;
102
99
#endif
103
100
}
104
101
105
- #if __GNUC__ >= 10
106
- constexpr
107
- #endif
108
- bool SoftwareSerial::isValidRxGPIOpin (int8_t pin) const {
102
+ constexpr bool SoftwareSerial::isValidRxGPIOpin (int8_t pin) {
109
103
return isValidGPIOpin (pin)
110
104
#if defined(ESP8266)
111
105
&& (pin != 16 )
112
106
#endif
113
107
;
114
108
}
115
109
116
- #if __GNUC__ >= 10
117
- constexpr
118
- #endif
119
- bool SoftwareSerial::isValidTxGPIOpin (int8_t pin) const {
110
+ constexpr bool SoftwareSerial::isValidTxGPIOpin (int8_t pin) {
120
111
return isValidGPIOpin (pin)
121
112
#if defined(ESP32)
122
113
#ifdef CONFIG_IDF_TARGET_ESP32
@@ -130,10 +121,7 @@ bool SoftwareSerial::isValidTxGPIOpin(int8_t pin) const {
130
121
;
131
122
}
132
123
133
- #if __GNUC__ >= 10
134
- constexpr
135
- #endif
136
- bool SoftwareSerial::hasRxGPIOPullUp (int8_t pin) const {
124
+ constexpr bool SoftwareSerial::hasRxGPIOPullUp (int8_t pin) {
137
125
#if defined(ESP32)
138
126
return !(pin >= 34 && pin <= 39 );
139
127
#else
@@ -342,7 +330,7 @@ void SoftwareSerial::lazyDelay() {
342
330
if (!m_intTxEnabled) { restoreInterrupts (); }
343
331
const auto expired = microsToTicks (micros ()) - m_periodStart;
344
332
const int32_t remaining = m_periodDuration - expired;
345
- const int32_t ms = remaining > 0 ? static_cast < int32_t >( ticksToMicros (remaining) / 1000L ) : 0 ;
333
+ const uint32_t ms = remaining > 0 ? ticksToMicros (remaining) / 1000UL : 0 ;
346
334
if (ms > 0 )
347
335
{
348
336
delay (ms);
@@ -359,11 +347,9 @@ void SoftwareSerial::lazyDelay() {
359
347
360
348
void IRAM_ATTR SoftwareSerial::preciseDelay () {
361
349
uint32_t ticks;
362
- uint32_t expired;
363
350
do {
364
351
ticks = microsToTicks (micros ());
365
- expired = ticks - m_periodStart;
366
- } while (static_cast <int32_t >(m_periodDuration - expired) > 0 );
352
+ } while ((ticks - m_periodStart) < m_periodDuration);
367
353
m_periodDuration = 0 ;
368
354
m_periodStart = ticks;
369
355
}
@@ -634,19 +620,23 @@ void SoftwareSerial::rxBits(const uint32_t isrTick) {
634
620
}
635
621
636
622
void IRAM_ATTR SoftwareSerial::rxBitISR (SoftwareSerial* self) {
637
- uint32_t curTick = microsToTicks (micros ());
638
- bool level = *self->m_rxReg & self->m_rxBitMask ;
623
+ const bool level = *self->m_rxReg & self->m_rxBitMask ;
624
+ const uint32_t curTick = microsToTicks (micros ());
625
+ const bool empty = !self->m_isrBuffer ->available ();
639
626
640
627
// Store level and tick in the buffer unless we have an overflow
641
628
// tick's LSB is repurposed for the level bit
642
629
if (!self->m_isrBuffer ->push ((curTick | 1U ) ^ !level)) self->m_isrOverflow .store (true );
630
+ // Trigger rx callback only when receiver is starved
631
+ if (empty && self->m_rxHandler ) self->m_rxHandler ();
643
632
}
644
633
645
634
void IRAM_ATTR SoftwareSerial::rxBitSyncISR (SoftwareSerial* self) {
646
- uint32_t start = microsToTicks (micros ());
635
+ bool level = self->m_invert ;
636
+ const uint32_t start = microsToTicks (micros ());
647
637
uint32_t wait = self->m_bitTicks - microsToTicks (2U );
638
+ const bool empty = !self->m_isrBuffer ->available ();
648
639
649
- bool level = self->m_invert ;
650
640
// Store level and tick in the buffer unless we have an overflow
651
641
// tick's LSB is repurposed for the level bit
652
642
if (!self->m_isrBuffer ->push (((start + wait) | 1U ) ^ !level)) self->m_isrOverflow .store (true );
@@ -663,17 +653,11 @@ void IRAM_ATTR SoftwareSerial::rxBitSyncISR(SoftwareSerial* self) {
663
653
level = !level;
664
654
}
665
655
}
656
+ // Trigger rx callback only when receiver is starved
657
+ if (empty && self->m_rxHandler ) self->m_rxHandler ();
666
658
}
667
659
668
- void SoftwareSerial::onReceive (Delegate<void (int available ), void*> handler) {
669
- receiveHandler = handler;
660
+ void SoftwareSerial::onReceive (Delegate<void (), void*> handler) {
661
+ m_rxHandler = handler;
670
662
}
671
663
672
- void SoftwareSerial::perform_work () {
673
- if (!m_rxValid) { return ; }
674
- rxBits ();
675
- if (receiveHandler) {
676
- int avail = m_buffer->available ();
677
- if (avail) { receiveHandler (avail); }
678
- }
679
- }
0 commit comments