Skip to content

Commit 1c907e6

Browse files
author
Sebastian Stockhammer
committed
Update deep sleep locks according to enabled state
1 parent a310706 commit 1c907e6

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

drivers/source/SerialBase.cpp

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,30 @@ int SerialBase::writeable()
8686
void SerialBase::attach(Callback<void()> func, IrqType type)
8787
{
8888
lock();
89-
// Disable interrupts when attaching interrupt handler
90-
core_util_critical_section_enter();
91-
if (func) {
92-
// lock deep sleep only the first time
93-
if (!_irq[type]) {
94-
sleep_manager_lock_deep_sleep();
95-
}
89+
const bool enabled { (_rx_enabled &&(type == RxIrq)) || (_tx_enabled &&(type == TxIrq)) };
90+
// If corresponding direction is not enabled only update the handler
91+
if (!enabled) {
9692
_irq[type] = func;
97-
serial_irq_set(&_serial, (SerialIrq)type, 1);
9893
} else {
99-
// unlock deep sleep only the first time
100-
if (_irq[type]) {
101-
sleep_manager_unlock_deep_sleep();
94+
// Disable interrupts when attaching interrupt handler
95+
core_util_critical_section_enter();
96+
if (func) {
97+
// lock deep sleep only the first time
98+
if (!_irq[type]) {
99+
sleep_manager_lock_deep_sleep();
100+
}
101+
_irq[type] = func;
102+
serial_irq_set(&_serial, (SerialIrq)type, 1);
103+
} else {
104+
// unlock deep sleep only the first time
105+
if (_irq[type]) {
106+
sleep_manager_unlock_deep_sleep();
107+
}
108+
_irq[type] = NULL;
109+
serial_irq_set(&_serial, (SerialIrq)type, 0);
102110
}
103-
_irq[type] = NULL;
104-
serial_irq_set(&_serial, (SerialIrq)type, 0);
111+
core_util_critical_section_exit();
105112
}
106-
core_util_critical_section_exit();
107113
unlock();
108114
}
109115

@@ -153,14 +159,21 @@ void SerialBase::enable_input(bool enable)
153159

154160
core_util_critical_section_enter();
155161
if (enable) {
156-
// Enable rx IRQ if attached (indicated by rx IRQ callback not NULL)
162+
// Enable rx IRQ and lock deep sleep if a rx handler is attached
163+
// (indicated by rx IRQ callback not NULL)
157164
if (_irq[RxIrq]) {
158165
_irq[RxIrq].call();
166+
sleep_manager_lock_deep_sleep();
159167
serial_irq_set(&_serial, (SerialIrq)RxIrq, 1);
160168
}
161169
} else {
162170
// Disable rx IRQ
163171
serial_irq_set(&_serial, (SerialIrq)RxIrq, 0);
172+
// Unlock deep sleep if a rx handler is attached
173+
// (indicated by rx IRQ callback not NULL)
174+
if (_irq[RxIrq]) {
175+
sleep_manager_unlock_deep_sleep();
176+
}
164177
}
165178
core_util_critical_section_exit();
166179

@@ -183,14 +196,21 @@ void SerialBase::enable_output(bool enable)
183196

184197
core_util_critical_section_enter();
185198
if (enable) {
186-
// Enable tx IRQ if attached (indicated by tx IRQ callback not NULL)
199+
// Enable tx IRQ and lock deep sleep if a tx handler is attached
200+
// (indicated by tx IRQ callback not NULL)
187201
if (_irq[TxIrq]) {
188202
_irq[TxIrq].call();
203+
sleep_manager_lock_deep_sleep();
189204
serial_irq_set(&_serial, (SerialIrq)TxIrq, 1);
190205
}
191206
} else {
192207
// Disable tx IRQ
193208
serial_irq_set(&_serial, (SerialIrq)TxIrq, 0);
209+
// Unlock deep sleep if a tx handler is attached
210+
// (indicated by tx IRQ callback not NULL)
211+
if (_irq[TxIrq]) {
212+
sleep_manager_unlock_deep_sleep();
213+
}
194214
}
195215
core_util_critical_section_exit();
196216

0 commit comments

Comments
 (0)