Skip to content
Merged
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
10 changes: 4 additions & 6 deletions drivers/include/drivers/BufferedSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,19 @@ class BufferedSerial:
ssize_t write_unbuffered(const char *buf_ptr, size_t length);

/** Enable processing of byte reception IRQs and register a callback to
* process them.
* process them if the IRQs are not yet enabled and reception is enabled.
*/
void enable_rx_irq();
void update_rx_irq();

/** Disable processing of byte reception IRQs and de-register callback to
* process them.
*/
void disable_rx_irq();

/** Enable processing of byte transmission IRQs and register a callback to
* process them.
* process them if the IRQs are not yet enabled and transmission is enabled.
*/
void enable_tx_irq();
void update_tx_irq();

/** Disable processing of byte transmission IRQs and de-register callback to
* process them.
Expand All @@ -335,8 +335,6 @@ class BufferedSerial:
bool _blocking = true;
bool _tx_irq_enabled = false;
bool _rx_irq_enabled = false;
bool _tx_enabled = true;
bool _rx_enabled = true;
InterruptIn *_dcd_irq = nullptr;

/** Device Hanged up
Expand Down
59 changes: 31 additions & 28 deletions drivers/source/BufferedSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ namespace mbed {
BufferedSerial::BufferedSerial(PinName tx, PinName rx, int baud):
SerialBase(tx, rx, baud)
{
enable_rx_irq();
update_rx_irq();
}

BufferedSerial::BufferedSerial(const serial_pinmap_t &static_pinmap, int baud):
SerialBase(static_pinmap, baud)
{
enable_rx_irq();
update_rx_irq();
}

BufferedSerial::~BufferedSerial()
Expand Down Expand Up @@ -184,15 +184,7 @@ ssize_t BufferedSerial::write(const void *buffer, size_t length)
data_written++;
}

core_util_critical_section_enter();
if (_tx_enabled && !_tx_irq_enabled) {
// only write to hardware in one place
BufferedSerial::tx_irq();
if (!_txbuf.empty()) {
enable_tx_irq();
}
}
core_util_critical_section_exit();
update_tx_irq();
}

api_unlock();
Expand Down Expand Up @@ -228,15 +220,7 @@ ssize_t BufferedSerial::read(void *buffer, size_t length)
data_read++;
}

core_util_critical_section_enter();
if (_rx_enabled && !_rx_irq_enabled) {
// only read from hardware in one place
BufferedSerial::rx_irq();
if (!_rxbuf.full()) {
enable_rx_irq();
}
}
core_util_critical_section_exit();
update_rx_irq();

api_unlock();

Expand Down Expand Up @@ -329,27 +313,44 @@ void BufferedSerial::tx_irq(void)
}
}

/* These are all called from critical section
* Attatch IRQ routines to the serial device.
/* Attach Rx-IRQ routine to the serial device eventually.
*/
void BufferedSerial::enable_rx_irq()
void BufferedSerial::update_rx_irq()
{
SerialBase::attach(callback(this, &BufferedSerial::rx_irq), RxIrq);
_rx_irq_enabled = true;
core_util_critical_section_enter();
if (_rx_enabled && !_rx_irq_enabled) {
BufferedSerial::rx_irq();
if (!_rxbuf.full()) {
SerialBase::attach(callback(this, &BufferedSerial::rx_irq), RxIrq);
_rx_irq_enabled = true;
}
}
core_util_critical_section_exit();
}

/* This is called called from critical section or interrupt context */
void BufferedSerial::disable_rx_irq()
{
SerialBase::attach(NULL, RxIrq);
_rx_irq_enabled = false;
}

void BufferedSerial::enable_tx_irq()
/* Attach Tx-IRQ routine to the serial device eventually.
*/
void BufferedSerial::update_tx_irq()
{
SerialBase::attach(callback(this, &BufferedSerial::tx_irq), TxIrq);
_tx_irq_enabled = true;
core_util_critical_section_enter();
if (_tx_enabled && !_tx_irq_enabled) {
BufferedSerial::tx_irq();
if (!_txbuf.empty()) {
SerialBase::attach(callback(this, &BufferedSerial::tx_irq), TxIrq);
_tx_irq_enabled = true;
}
}
core_util_critical_section_exit();
}

/* This is called called from critical section or interrupt context */
void BufferedSerial::disable_tx_irq()
{
SerialBase::attach(NULL, TxIrq);
Expand All @@ -360,6 +361,7 @@ int BufferedSerial::enable_input(bool enabled)
{
api_lock();
SerialBase::enable_input(enabled);
update_rx_irq(); // Eventually enable rx-interrupt to handle incoming data
api_unlock();

return 0;
Expand All @@ -369,6 +371,7 @@ int BufferedSerial::enable_output(bool enabled)
{
api_lock();
SerialBase::enable_output(enabled);
update_tx_irq(); // Eventually enable tx-interrupt to flush buffered data
api_unlock();

return 0;
Expand Down