@@ -86,24 +86,30 @@ int SerialBase::writeable()
8686void 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