38
38
#include "tick.h"
39
39
#include "stm32f4xx_hal.h"
40
40
41
+ bool iflag ;
42
+ int errflag ;
43
+ bool rxflag ;
44
+ bool bsyflag ;
45
+
41
46
STATIC bool reserved_uart [MAX_UART ];
42
47
43
48
void uart_reset (void ) {
44
49
#ifdef USART1
45
50
reserved_uart [0 ] = false;
46
51
MP_STATE_PORT (cpy_uart_obj_all )[0 ] = NULL ;
47
52
__HAL_RCC_USART1_CLK_DISABLE ();
48
- //HAL_NVIC_DisableIRQ(USART1_IRQn);
49
53
#endif
50
54
#ifdef USART2
51
55
reserved_uart [1 ] = false;
52
56
MP_STATE_PORT (cpy_uart_obj_all )[1 ] = NULL ;
53
57
__HAL_RCC_USART2_CLK_DISABLE ();
54
- //HAL_NVIC_DisableIRQ(USART2_IRQn);
55
58
#endif
56
59
#ifdef USART3
57
60
reserved_uart [2 ] = false;
58
61
MP_STATE_PORT (cpy_uart_obj_all )[2 ] = NULL ;
59
62
__HAL_RCC_USART3_CLK_DISABLE ();
60
- //HAL_NVIC_DisableIRQ(USART3_IRQn);
61
63
#endif
62
64
#ifdef UART4
63
65
reserved_uart [3 ] = false;
64
66
MP_STATE_PORT (cpy_uart_obj_all )[3 ] = NULL ;
65
67
__HAL_RCC_UART4_CLK_DISABLE ();
66
- //HAL_NVIC_DisableIRQ(UART4_IRQn);
67
68
#endif
68
69
#ifdef UART5
69
70
reserved_uart [4 ] = false;
70
71
MP_STATE_PORT (cpy_uart_obj_all )[4 ] = NULL ;
71
72
__HAL_RCC_UART5_CLK_DISABLE ();
72
- //HAL_NVIC_DisableIRQ(UART5_IRQn);
73
73
#endif
74
74
#ifdef USART6
75
75
reserved_uart [5 ] = false;
76
76
MP_STATE_PORT (cpy_uart_obj_all )[5 ] = NULL ;
77
77
__HAL_RCC_USART6_CLK_DISABLE ();
78
- //HAL_NVIC_DisableIRQ(USART6_IRQn);
79
78
#endif
80
79
//TODO: this technically needs to go to 10 to support F413. Any way to condense?
81
80
}
@@ -104,10 +103,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
104
103
__HAL_RCC_USART1_RELEASE_RESET ();
105
104
__HAL_RCC_USART1_CLK_ENABLE ();
106
105
self -> irq = USART1_IRQn ;
107
- //HAL_NVIC_SetPriority(USART1_IRQn, 2,1);
108
- NVIC_SetPriority (USART1_IRQn , 7 );
109
- NVIC_ClearPendingIRQ (USART1_IRQn );
110
- HAL_NVIC_EnableIRQ (USART1_IRQn );
111
106
}
112
107
#endif
113
108
#ifdef USART2
@@ -117,10 +112,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
117
112
__HAL_RCC_USART2_RELEASE_RESET ();
118
113
__HAL_RCC_USART2_CLK_ENABLE ();
119
114
self -> irq = USART2_IRQn ;
120
- //HAL_NVIC_SetPriority(USART2_IRQn, 2,1);
121
- NVIC_SetPriority (USART2_IRQn , 7 );
122
- NVIC_ClearPendingIRQ (USART2_IRQn );
123
- HAL_NVIC_EnableIRQ (USART2_IRQn );
124
115
}
125
116
#endif
126
117
#ifdef USART3
@@ -130,10 +121,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
130
121
__HAL_RCC_USART3_RELEASE_RESET ();
131
122
__HAL_RCC_USART3_CLK_ENABLE ();
132
123
self -> irq = USART3_IRQn ;
133
- //HAL_NVIC_SetPriority(USART3_IRQn, 2,1);
134
- NVIC_SetPriority (USART3_IRQn , 7 );
135
- NVIC_ClearPendingIRQ (USART3_IRQn );
136
- HAL_NVIC_EnableIRQ (USART3_IRQn );
137
124
}
138
125
#endif
139
126
#ifdef UART4
@@ -143,10 +130,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
143
130
__HAL_RCC_UART4_RELEASE_RESET ();
144
131
__HAL_RCC_UART4_CLK_ENABLE ();
145
132
self -> irq = UART4_IRQn ;
146
- //HAL_NVIC_SetPriority(UART4_IRQn, 2,1);
147
- NVIC_SetPriority (UART4_IRQn , 7 );
148
- NVIC_ClearPendingIRQ (UART4_IRQn );
149
- HAL_NVIC_EnableIRQ (UART4_IRQn );
150
133
}
151
134
#endif
152
135
#ifdef UART5
@@ -156,10 +139,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
156
139
__HAL_RCC_UART5_RELEASE_RESET ();
157
140
__HAL_RCC_UART5_CLK_ENABLE ();
158
141
self -> irq = UART5_IRQn ;
159
- //NVIC_SetPriority(UART5_IRQn, 7);
160
- NVIC_SetPriority (UART5_IRQn , 7 );
161
- NVIC_ClearPendingIRQ (UART5_IRQn );
162
- HAL_NVIC_EnableIRQ (UART5_IRQn );
163
142
}
164
143
#endif
165
144
#ifdef USART6
@@ -169,10 +148,6 @@ STATIC void uart_clk_irq_enable(busio_uart_obj_t *self, USART_TypeDef * USARTx)
169
148
__HAL_RCC_USART6_RELEASE_RESET ();
170
149
__HAL_RCC_USART6_CLK_ENABLE ();
171
150
self -> irq = USART6_IRQn ;
172
- //NVIC_SetPriority(USART6_IRQn, 7);
173
- NVIC_SetPriority (USART6_IRQn , 7 );
174
- NVIC_ClearPendingIRQ (USART6_IRQn );
175
- HAL_NVIC_EnableIRQ (USART6_IRQn );
176
151
}
177
152
#endif
178
153
}
@@ -308,20 +283,33 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
308
283
if (self -> tx != NULL ) {
309
284
claim_pin (tx );
310
285
}
311
-
312
286
self -> baudrate = baudrate ;
313
287
self -> timeout_ms = timeout * 1000 ;
314
288
315
- if (HAL_UART_Receive_IT (& self -> handle , & self -> rx_char , 1 ) != HAL_OK ) {
316
- mp_raise_ValueError (translate ("HAL recieve IT start error" ));
289
+ //start the interrupt series
290
+ if ((HAL_UART_GetState (& self -> handle ) & HAL_UART_STATE_BUSY_RX ) == HAL_UART_STATE_BUSY_RX ) {
291
+ mp_raise_ValueError (translate ("Could not start interrupt, RX busy" ));
317
292
}
293
+ HAL_NVIC_DisableIRQ (self -> irq ); //prevent handle lock contention
294
+
295
+ HAL_UART_Receive_IT (& self -> handle , & self -> rx_char , 1 );
296
+
297
+ HAL_NVIC_SetPriority (self -> irq , UART_IRQPRI , UART_IRQSUB_PRI );
298
+ HAL_NVIC_EnableIRQ (self -> irq );
299
+
300
+ mp_printf (& mp_plat_print , "Started and inited\n" );
301
+ iflag = 0 ;
302
+ errflag = 0 ;
303
+ rxflag = 0 ;
304
+ bsyflag = 0 ;
318
305
}
319
306
320
307
bool common_hal_busio_uart_deinited (busio_uart_obj_t * self ) {
321
308
return self -> tx -> pin == mp_const_none ;
322
309
}
323
310
324
311
void common_hal_busio_uart_deinit (busio_uart_obj_t * self ) {
312
+ mp_printf (& mp_plat_print , "De-init UART\n" );
325
313
reset_pin_number (self -> tx -> pin -> port ,self -> tx -> pin -> number );
326
314
reset_pin_number (self -> rx -> pin -> port ,self -> rx -> pin -> number );
327
315
self -> tx = mp_const_none ;
@@ -343,28 +331,34 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
343
331
// Wait for all bytes received or timeout, same as nrf
344
332
while ( (ringbuf_count (& self -> rbuf ) < len ) && (ticks_ms - start_ticks < self -> timeout_ms ) ) {
345
333
RUN_BACKGROUND_TASKS ;
334
+ //restart if it failed in the callback
335
+ if (errflag != HAL_OK ) {
336
+ errflag = HAL_UART_Receive_IT (& self -> handle , & self -> rx_char , 1 );
337
+ }
346
338
// Allow user to break out of a timeout with a KeyboardInterrupt.
347
339
if ( mp_hal_is_interrupted () ) {
348
340
return 0 ;
349
341
}
350
342
}
351
343
352
344
// Halt reception
353
- //HAL_UART_AbortReceive_IT(&self->handle);
354
- NVIC_DisableIRQ (self -> irq );
345
+ HAL_NVIC_DisableIRQ (self -> irq );
355
346
356
347
// copy received data
357
348
rx_bytes = ringbuf_count (& self -> rbuf );
349
+ //Used for debuggings
350
+ //mp_printf(&mp_plat_print, "Read: count:%d, buffer location%p, if:%der:%drx:%dbsy:%d\n", rx_bytes, &self->rbuf,iflag,errflag,rxflag,bsyflag);
351
+ iflag = 0 ;
352
+ errflag = 0 ;
353
+ rxflag = 0 ;
354
+ bsyflag = 0 ;
358
355
rx_bytes = MIN (rx_bytes , len );
359
356
for ( uint16_t i = 0 ; i < rx_bytes ; i ++ ) {
360
357
data [i ] = ringbuf_get (& self -> rbuf );
361
358
}
362
359
363
- NVIC_EnableIRQ (self -> irq );
364
- // if (HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1) != HAL_OK) {
365
- // mp_raise_ValueError(translate("HAL recieve IT re-start error"));
366
- // }
367
-
360
+ HAL_NVIC_EnableIRQ (self -> irq );
361
+
368
362
if (rx_bytes == 0 ) {
369
363
* errcode = EAGAIN ;
370
364
return MP_STREAM_ERROR ;
@@ -383,28 +377,50 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
383
377
} else {
384
378
mp_raise_ValueError (translate ("UART write error" ));
385
379
}
380
+ mp_printf (& mp_plat_print , "Send\n" );
386
381
return 0 ;
387
382
}
388
383
389
384
void HAL_UART_RxCpltCallback (UART_HandleTypeDef * handle )
390
385
{
386
+ rxflag = 1 ;
391
387
for (int i = 0 ; i < 7 ; i ++ ) {
392
388
//get context pointer and cast it as struct pointer
393
389
busio_uart_obj_t * context = (busio_uart_obj_t * )MP_STATE_PORT (cpy_uart_obj_all )[i ];
394
390
if (handle == & context -> handle ) {
395
- ringbuf_put_n ( & context -> rbuf , & context -> rx_char , 1 );
396
- HAL_StatusTypeDef result = HAL_UART_Receive_IT ( handle , & context -> rx_char , 1 );
397
- if ( result != HAL_OK ) {
398
- mp_raise_RuntimeError ( translate ( "UART rx restart error" )) ;
391
+ //check if transaction is ongoing
392
+ if (( HAL_UART_GetState ( handle ) & HAL_UART_STATE_BUSY_RX ) == HAL_UART_STATE_BUSY_RX ) {
393
+ bsyflag = 1 ;
394
+ return ;
399
395
}
400
- break ;
396
+ ringbuf_put_n (& context -> rbuf , & context -> rx_char , 1 );
397
+ errflag = HAL_UART_Receive_IT (handle , & context -> rx_char , 1 );
398
+
399
+ return ;
401
400
}
402
401
}
403
402
}
404
403
405
404
void HAL_UART_ErrorCallback (UART_HandleTypeDef * UartHandle )
406
405
{
407
- mp_raise_RuntimeError (translate ("UART Error Callback hit" ));
406
+ if (__HAL_UART_GET_FLAG (UartHandle , UART_FLAG_PE ) != RESET ) {
407
+ __HAL_UART_CLEAR_PEFLAG (UartHandle );
408
+ } else if (__HAL_UART_GET_FLAG (UartHandle , UART_FLAG_FE ) != RESET ) {
409
+ __HAL_UART_CLEAR_FEFLAG (UartHandle );
410
+ } else if (__HAL_UART_GET_FLAG (UartHandle , UART_FLAG_NE ) != RESET ) {
411
+ __HAL_UART_CLEAR_NEFLAG (UartHandle );
412
+ } else if (__HAL_UART_GET_FLAG (UartHandle , UART_FLAG_ORE ) != RESET ) {
413
+ __HAL_UART_CLEAR_OREFLAG (UartHandle );
414
+ }
415
+ //restart serial read after an error
416
+ for (int i = 0 ; i < 7 ; i ++ ) {
417
+ busio_uart_obj_t * context = (busio_uart_obj_t * )MP_STATE_PORT (cpy_uart_obj_all )[i ];
418
+ if (UartHandle == & context -> handle ) {
419
+ HAL_UART_Receive_IT (UartHandle , & context -> rx_char , 1 );
420
+ return ;
421
+ }
422
+ }
423
+
408
424
}
409
425
410
426
uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t * self ) {
@@ -432,25 +448,24 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
432
448
}
433
449
434
450
void common_hal_busio_uart_clear_rx_buffer (busio_uart_obj_t * self ) {
451
+ mp_printf (& mp_plat_print , "Clear RX Buffer\n" );
435
452
// Halt reception
436
- //HAL_UART_AbortReceive_IT(&self->handle);
437
- NVIC_DisableIRQ (self -> irq );
453
+ HAL_NVIC_DisableIRQ (self -> irq );
438
454
ringbuf_clear (& self -> rbuf );
439
- NVIC_EnableIRQ (self -> irq );
440
- //HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
455
+ HAL_NVIC_EnableIRQ (self -> irq );
441
456
}
442
457
443
458
bool common_hal_busio_uart_ready_to_tx (busio_uart_obj_t * self ) {
444
459
return true;
445
460
}
446
461
447
462
STATIC void call_hal_irq (int uart_num ) {
463
+ iflag = 1 ;
448
464
//Create casted context pointer
449
465
busio_uart_obj_t * context = (busio_uart_obj_t * )MP_STATE_PORT (cpy_uart_obj_all )[uart_num - 1 ];
450
466
if (context != NULL ) {
467
+ HAL_NVIC_ClearPendingIRQ (context -> irq );
451
468
HAL_UART_IRQHandler (& context -> handle );
452
- } else {
453
- mp_raise_ValueError (translate ("UART IRQ bad handle supplied" ));
454
469
}
455
470
}
456
471
0 commit comments