@@ -27,7 +27,8 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
27
27
#if DEVICE_SERIAL_ASYNCH
28
28
_thunk_irq (this ), _tx_usage(DMA_USAGE_NEVER),
29
29
_rx_usage(DMA_USAGE_NEVER), _tx_callback(NULL ),
30
- _rx_callback(NULL ),
30
+ _rx_callback(NULL ), _tx_asynch_set(false ),
31
+ _rx_asynch_set(false ),
31
32
#endif
32
33
_serial (), _baud(baud)
33
34
{
@@ -200,24 +201,33 @@ void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2)
200
201
201
202
int SerialBase::write (const uint8_t *buffer, int length, const event_callback_t &callback, int event)
202
203
{
203
- if (serial_tx_active (&_serial)) {
204
- return -1 ; // transaction ongoing
204
+ int result = 0 ;
205
+ lock ();
206
+ if (!serial_tx_active (&_serial) && !_tx_asynch_set) {
207
+ start_write ((void *)buffer, length, 8 , callback, event);
208
+ } else {
209
+ result = -1 ; // transaction ongoing
205
210
}
206
- start_write (( void *)buffer, length, 8 , callback, event );
207
- return 0 ;
211
+ unlock ( );
212
+ return result ;
208
213
}
209
214
210
215
int SerialBase::write (const uint16_t *buffer, int length, const event_callback_t &callback, int event)
211
216
{
212
- if (serial_tx_active (&_serial)) {
213
- return -1 ; // transaction ongoing
217
+ int result = 0 ;
218
+ lock ();
219
+ if (!serial_tx_active (&_serial) && !_tx_asynch_set) {
220
+ start_write ((void *)buffer, length, 16 , callback, event);
221
+ } else {
222
+ result = -1 ; // transaction ongoing
214
223
}
215
- start_write (( void *)buffer, length, 16 , callback, event );
216
- return 0 ;
224
+ unlock ( );
225
+ return result ;
217
226
}
218
227
219
228
void SerialBase::start_write (const void *buffer, int buffer_size, char buffer_width, const event_callback_t &callback, int event)
220
229
{
230
+ _tx_asynch_set = true ;
221
231
_tx_callback = callback;
222
232
223
233
_thunk_irq.callback (&SerialBase::interrupt_handler_asynch);
@@ -227,22 +237,30 @@ void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_wi
227
237
228
238
void SerialBase::abort_write (void )
229
239
{
230
- // rx might still be active
231
- if (_rx_callback) {
240
+ lock ();
241
+ core_util_critical_section_enter ();
242
+ if (_tx_asynch_set) {
243
+ _tx_callback = NULL ;
244
+ _tx_asynch_set = false ;
245
+ serial_tx_abort_asynch (&_serial);
232
246
sleep_manager_unlock_deep_sleep ();
233
247
}
234
- _tx_callback = NULL ;
235
- serial_tx_abort_asynch (&_serial );
248
+ core_util_critical_section_exit () ;
249
+ unlock ( );
236
250
}
237
251
238
252
void SerialBase::abort_read (void )
239
253
{
240
- // tx might still be active
241
- if (_tx_callback) {
254
+ lock ();
255
+ core_util_critical_section_enter ();
256
+ if (_rx_asynch_set) {
257
+ _rx_callback = NULL ;
258
+ _rx_asynch_set = false ;
259
+ serial_rx_abort_asynch (&_serial);
242
260
sleep_manager_unlock_deep_sleep ();
243
261
}
244
- _rx_callback = NULL ;
245
- serial_rx_abort_asynch (&_serial );
262
+ core_util_critical_section_exit () ;
263
+ unlock ( );
246
264
}
247
265
248
266
int SerialBase::set_dma_usage_tx (DMAUsage usage)
@@ -265,26 +283,35 @@ int SerialBase::set_dma_usage_rx(DMAUsage usage)
265
283
266
284
int SerialBase::read (uint8_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
267
285
{
268
- if (serial_rx_active (&_serial)) {
269
- return -1 ; // transaction ongoing
286
+ int result = 0 ;
287
+ lock ();
288
+ if (!serial_rx_active (&_serial) && !_rx_asynch_set) {
289
+ start_read ((void *)buffer, length, 8 , callback, event, char_match);
290
+ } else {
291
+ result = -1 ; // transaction ongoing
270
292
}
271
- start_read (( void *)buffer, length, 8 , callback, event, char_match );
272
- return 0 ;
293
+ unlock ( );
294
+ return result ;
273
295
}
274
296
275
297
276
298
int SerialBase::read (uint16_t *buffer, int length, const event_callback_t &callback, int event, unsigned char char_match)
277
299
{
278
- if (serial_rx_active (&_serial)) {
279
- return -1 ; // transaction ongoing
300
+ int result = 0 ;
301
+ lock ();
302
+ if (!serial_rx_active (&_serial) && !_rx_asynch_set) {
303
+ start_read ((void *)buffer, length, 16 , callback, event, char_match);
304
+ } else {
305
+ result = -1 ; // transaction ongoing
280
306
}
281
- start_read (( void *)buffer, length, 16 , callback, event, char_match );
282
- return 0 ;
307
+ unlock ( );
308
+ return result ;
283
309
}
284
310
285
311
286
312
void SerialBase::start_read (void *buffer, int buffer_size, char buffer_width, const event_callback_t &callback, int event, unsigned char char_match)
287
313
{
314
+ _rx_asynch_set = true ;
288
315
_rx_callback = callback;
289
316
_thunk_irq.callback (&SerialBase::interrupt_handler_asynch);
290
317
sleep_manager_lock_deep_sleep ();
@@ -295,20 +322,25 @@ void SerialBase::interrupt_handler_asynch(void)
295
322
{
296
323
int event = serial_irq_handler_asynch (&_serial);
297
324
int rx_event = event & SERIAL_EVENT_RX_MASK;
298
- bool unlock_deepsleep = false ;
299
325
300
- if (_rx_callback && rx_event) {
301
- unlock_deepsleep = true ;
302
- _rx_callback.call (rx_event);
326
+ if (_rx_asynch_set && rx_event) {
327
+ event_callback_t cb = _rx_callback;
328
+ _rx_asynch_set = false ;
329
+ _rx_callback = NULL ;
330
+ if (cb) {
331
+ cb.call (rx_event);
332
+ }
333
+ sleep_manager_unlock_deep_sleep ();
303
334
}
304
335
305
336
int tx_event = event & SERIAL_EVENT_TX_MASK;
306
- if (_tx_callback && tx_event) {
307
- unlock_deepsleep = true ;
308
- _tx_callback.call (tx_event);
309
- }
310
- // unlock if tx or rx events are generated
311
- if (unlock_deepsleep) {
337
+ if (_tx_asynch_set && tx_event) {
338
+ event_callback_t cb = _tx_callback;
339
+ _tx_asynch_set = false ;
340
+ _tx_callback = NULL ;
341
+ if (cb) {
342
+ cb.call (tx_event);
343
+ }
312
344
sleep_manager_unlock_deep_sleep ();
313
345
}
314
346
}
0 commit comments