Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: drivers/SerialBase.cpp
- Revision:
- 174:b96e65c34a4d
- Parent:
- 160:d5399cc887bb
- Child:
- 175:af195413fb11
--- a/drivers/SerialBase.cpp Fri Sep 15 14:59:18 2017 +0100 +++ b/drivers/SerialBase.cpp Mon Oct 02 15:33:19 2017 +0100 @@ -16,23 +16,23 @@ #include "drivers/SerialBase.h" #include "platform/mbed_wait_api.h" #include "platform/mbed_critical.h" +#include "platform/mbed_sleep.h" #if DEVICE_SERIAL namespace mbed { -static void donothing() {}; - SerialBase::SerialBase(PinName tx, PinName rx, int baud) : #if DEVICE_SERIAL_ASYNCH _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), - _rx_usage(DMA_USAGE_NEVER), + _rx_usage(DMA_USAGE_NEVER), _tx_callback(NULL), + _rx_callback(NULL), #endif _serial(), _baud(baud) { // No lock needed in the constructor for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { - _irq[i] = donothing; + _irq[i] = NULL; } serial_init(&_serial, tx, rx); @@ -73,10 +73,18 @@ // Disable interrupts when attaching interrupt handler core_util_critical_section_enter(); if (func) { + // lock deep sleep only the first time + if (!_irq[type]) { + sleep_manager_lock_deep_sleep(); + } _irq[type] = func; serial_irq_set(&_serial, (SerialIrq)type, 1); } else { - _irq[type] = donothing; + // unlock deep sleep only the first time + if (_irq[type]) { + sleep_manager_unlock_deep_sleep(); + } + _irq[type] = NULL; serial_irq_set(&_serial, (SerialIrq)type, 0); } core_util_critical_section_exit(); @@ -85,7 +93,9 @@ void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { SerialBase *handler = (SerialBase*)id; - handler->_irq[irq_type](); + if (handler->_irq[irq_type]) { + handler->_irq[irq_type](); + } } int SerialBase::_base_getc() { @@ -173,16 +183,27 @@ _tx_callback = callback; _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); + sleep_manager_lock_deep_sleep(); serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); } void SerialBase::abort_write(void) { + // rx might still be active + if (_rx_callback) { + sleep_manager_unlock_deep_sleep(); + } + _tx_callback = NULL; serial_tx_abort_asynch(&_serial); } void SerialBase::abort_read(void) { + // tx might still be active + if (_tx_callback) { + sleep_manager_unlock_deep_sleep(); + } + _rx_callback = NULL; serial_rx_abort_asynch(&_serial); } @@ -228,6 +249,7 @@ { _rx_callback = callback; _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); + sleep_manager_lock_deep_sleep(); serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); } @@ -235,14 +257,22 @@ { int event = serial_irq_handler_asynch(&_serial); int rx_event = event & SERIAL_EVENT_RX_MASK; + bool unlock_deepsleep = false; + if (_rx_callback && rx_event) { + unlock_deepsleep = true; _rx_callback.call(rx_event); } int tx_event = event & SERIAL_EVENT_TX_MASK; if (_tx_callback && tx_event) { + unlock_deepsleep = true; _tx_callback.call(tx_event); } + // unlock if tx or rx events are generated + if (unlock_deepsleep) { + sleep_manager_unlock_deep_sleep(); + } } #endif