Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/SoftwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void UARTBase::begin(uint32_t baud, Config config,
m_stopBits = 1 + ((config & 0300) ? 1 : 0);
m_pduBits = m_dataBits + static_cast<bool>(m_parityMode) + m_stopBits;
m_bitTicks = (microsToTicks(1000000UL) + baud / 2) / baud;
m_origBitTicks = m_bitTicks;
m_intTxEnabled = true;
}

Expand Down Expand Up @@ -153,6 +154,12 @@ void UARTBase::enableIntTx(bool on) {
m_intTxEnabled = on;
}

void UARTBase::enableAutoBaud(bool on, uint8_t sep) {
m_autoBaudEnabled = on;
m_autoBaud = false;
m_frameSep = sep;
}

void UARTBase::enableRxGPIOPullUp(bool on) {
m_rxGPIOPullUpEnabled = on;
setRxGPIOPinMode();
Expand All @@ -163,6 +170,12 @@ void UARTBase::enableTxGPIOOpenDrain(bool on) {
setTxGPIOPinMode();
}

#ifdef xTaskNotify
void UARTBase::enableNotify(TaskHandle_t task) {
m_notifyTask = task;
}
#endif

void UARTBase::enableTx(bool on) {
if (m_txValid && m_oneWire) {
if (on) {
Expand Down Expand Up @@ -493,6 +506,11 @@ void UARTBase::rxBits(const uint32_t isrTick) {
uint32_t ticksDiff = isrTick - m_isrLastTick;
m_isrLastTick = isrTick;

if (m_autoBaudEnabled && (ticksDiff > m_origBitTicks*(m_pduBits+1))) {
m_autoBaud = true;
m_bitTicks = m_origBitTicks;
}

uint32_t bits = ticksDiff / m_bitTicks;
if (ticksDiff % m_bitTicks > (m_bitTicks >> 1)) ++bits;
while (bits > 0) {
Expand All @@ -502,6 +520,9 @@ void UARTBase::rxBits(const uint32_t isrTick) {
if (level) break;
m_rxLastBit = -1;
--bits;
if (m_autoBaud) {
m_rxByteTicks = 0;
}
continue;
}
// data bits
Expand All @@ -511,6 +532,9 @@ void UARTBase::rxBits(const uint32_t isrTick) {
bits -= dataBits;
m_rxCurByte >>= dataBits;
if (level) { m_rxCurByte |= (BYTE_ALL_BITS_SET << (8 - dataBits)); }
if (m_autoBaud) {
m_rxByteTicks += ticksDiff;
}
continue;
}
// parity bit
Expand All @@ -525,6 +549,10 @@ void UARTBase::rxBits(const uint32_t isrTick) {
// if not high stop bit level, discard word
if (bits >= static_cast<uint32_t>(m_pduBits - 1 - m_rxLastBit) && level) {
m_rxCurByte >>= (sizeof(uint8_t) * 8 - m_dataBits);
if (m_autoBaud && (m_rxCurByte == m_frameSep)) {
m_bitTicks = (m_rxByteTicks + (m_dataBits>>1)) / m_dataBits;
m_autoBaud = false;
}
if (!m_buffer->push(m_rxCurByte)) {
m_overflow = true;
}
Expand All @@ -545,6 +573,11 @@ void UARTBase::rxBits(const uint32_t isrTick) {
}
}
}
#ifdef xTaskNotify
if (m_notifyTask) {
xTaskNotify(m_notifyTask, 0, eSetValueWithOverwrite);
}
#endif
}
m_rxLastBit = m_pduBits - 1;
// reset to 0 is important for masked bit logic
Expand Down
14 changes: 14 additions & 0 deletions src/SoftwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,16 @@ class UARTBase : public Stream {
void setTransmitEnablePin(int8_t txEnablePin);
/// Enable (default) or disable interrupts during tx.
void enableIntTx(bool on);
/// Enable baud rate estimation based on frame separator
void enableAutoBaud(bool on, uint8_t sep = 0x55);
/// Enable (default) or disable internal rx GPIO pull-up.
void enableRxGPIOPullUp(bool on);
/// Enable or disable (default) tx GPIO output mode.
void enableTxGPIOOpenDrain(bool on);
#ifdef xTaskNotify
/// Enable or disable (default) FreeRTOS task notify
void enableNotify(TaskHandle_t task);
#endif

bool overflow();

Expand Down Expand Up @@ -371,7 +377,12 @@ class UARTBase : public Stream {
uint8_t m_stopBits;
bool m_lastReadParity;
bool m_overflow = false;
bool m_autoBaud = false;
bool m_autoBaudEnabled = false;
uint8_t m_frameSep;
uint32_t m_rxByteTicks;
uint32_t m_bitTicks;
uint32_t m_origBitTicks;
uint8_t m_parityInPos;
uint8_t m_parityOutPos;
int8_t m_rxLastBit; // 0 thru (m_pduBits - m_stopBits - 1): data/parity bits. -1: start bit. (m_pduBits - 1): stop bit.
Expand All @@ -380,6 +391,9 @@ class UARTBase : public Stream {
std::unique_ptr<circular_queue<uint8_t> > m_parityBuffer;
uint32_t m_periodStart;
uint32_t m_periodDuration;
#ifdef xTaskNotify
TaskHandle_t m_notifyTask = nullptr;
#endif
#ifndef ESP32
static uint32_t m_savedPS;
#else
Expand Down