Update deep sleep locks according to enabled state

pull/10924/head
Sebastian Stockhammer 2019-10-24 12:53:52 +02:00
parent a3107062d9
commit 1c907e6db9
1 changed files with 36 additions and 16 deletions

View File

@ -86,6 +86,11 @@ int SerialBase::writeable()
void SerialBase::attach(Callback<void()> func, IrqType type) void SerialBase::attach(Callback<void()> func, IrqType type)
{ {
lock(); lock();
const bool enabled { (_rx_enabled &&(type == RxIrq)) || (_tx_enabled &&(type == TxIrq)) };
// If corresponding direction is not enabled only update the handler
if (!enabled) {
_irq[type] = func;
} else {
// Disable interrupts when attaching interrupt handler // Disable interrupts when attaching interrupt handler
core_util_critical_section_enter(); core_util_critical_section_enter();
if (func) { if (func) {
@ -104,6 +109,7 @@ void SerialBase::attach(Callback<void()> func, IrqType type)
serial_irq_set(&_serial, (SerialIrq)type, 0); serial_irq_set(&_serial, (SerialIrq)type, 0);
} }
core_util_critical_section_exit(); core_util_critical_section_exit();
}
unlock(); unlock();
} }
@ -153,14 +159,21 @@ void SerialBase::enable_input(bool enable)
core_util_critical_section_enter(); core_util_critical_section_enter();
if (enable) { if (enable) {
// Enable rx IRQ if attached (indicated by rx IRQ callback not NULL) // Enable rx IRQ and lock deep sleep if a rx handler is attached
// (indicated by rx IRQ callback not NULL)
if (_irq[RxIrq]) { if (_irq[RxIrq]) {
_irq[RxIrq].call(); _irq[RxIrq].call();
sleep_manager_lock_deep_sleep();
serial_irq_set(&_serial, (SerialIrq)RxIrq, 1); serial_irq_set(&_serial, (SerialIrq)RxIrq, 1);
} }
} else { } else {
// Disable rx IRQ // Disable rx IRQ
serial_irq_set(&_serial, (SerialIrq)RxIrq, 0); serial_irq_set(&_serial, (SerialIrq)RxIrq, 0);
// Unlock deep sleep if a rx handler is attached
// (indicated by rx IRQ callback not NULL)
if (_irq[RxIrq]) {
sleep_manager_unlock_deep_sleep();
}
} }
core_util_critical_section_exit(); core_util_critical_section_exit();
@ -183,14 +196,21 @@ void SerialBase::enable_output(bool enable)
core_util_critical_section_enter(); core_util_critical_section_enter();
if (enable) { if (enable) {
// Enable tx IRQ if attached (indicated by tx IRQ callback not NULL) // Enable tx IRQ and lock deep sleep if a tx handler is attached
// (indicated by tx IRQ callback not NULL)
if (_irq[TxIrq]) { if (_irq[TxIrq]) {
_irq[TxIrq].call(); _irq[TxIrq].call();
sleep_manager_lock_deep_sleep();
serial_irq_set(&_serial, (SerialIrq)TxIrq, 1); serial_irq_set(&_serial, (SerialIrq)TxIrq, 1);
} }
} else { } else {
// Disable tx IRQ // Disable tx IRQ
serial_irq_set(&_serial, (SerialIrq)TxIrq, 0); serial_irq_set(&_serial, (SerialIrq)TxIrq, 0);
// Unlock deep sleep if a tx handler is attached
// (indicated by tx IRQ callback not NULL)
if (_irq[TxIrq]) {
sleep_manager_unlock_deep_sleep();
}
} }
core_util_critical_section_exit(); core_util_critical_section_exit();