@@ -86,24 +86,30 @@ int SerialBase::writeable()
86
86
void SerialBase::attach (Callback<void ()> func, IrqType type)
87
87
{
88
88
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) {
96
92
_irq[type] = func;
97
- serial_irq_set (&_serial, (SerialIrq)type, 1 );
98
93
} 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 );
102
110
}
103
- _irq[type] = NULL ;
104
- serial_irq_set (&_serial, (SerialIrq)type, 0 );
111
+ core_util_critical_section_exit ();
105
112
}
106
- core_util_critical_section_exit ();
107
113
unlock ();
108
114
}
109
115
@@ -153,14 +159,21 @@ void SerialBase::enable_input(bool enable)
153
159
154
160
core_util_critical_section_enter ();
155
161
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)
157
164
if (_irq[RxIrq]) {
158
165
_irq[RxIrq].call ();
166
+ sleep_manager_lock_deep_sleep ();
159
167
serial_irq_set (&_serial, (SerialIrq)RxIrq, 1 );
160
168
}
161
169
} else {
162
170
// Disable rx IRQ
163
171
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
+ }
164
177
}
165
178
core_util_critical_section_exit ();
166
179
@@ -183,14 +196,21 @@ void SerialBase::enable_output(bool enable)
183
196
184
197
core_util_critical_section_enter ();
185
198
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)
187
201
if (_irq[TxIrq]) {
188
202
_irq[TxIrq].call ();
203
+ sleep_manager_lock_deep_sleep ();
189
204
serial_irq_set (&_serial, (SerialIrq)TxIrq, 1 );
190
205
}
191
206
} else {
192
207
// Disable tx IRQ
193
208
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
+ }
194
214
}
195
215
core_util_critical_section_exit ();
196
216
0 commit comments