@@ -97,19 +97,28 @@ typedef enum {
97
97
} uart_index_t;
98
98
99
99
static UART_HandleTypeDef *uart_handlers[UART_NUM] = {NULL};
100
- static void (*rx_callback[UART_NUM])(serial_t *);
101
- static serial_t *rx_callback_obj[UART_NUM];
102
- static int (*tx_callback[UART_NUM])(serial_t *);
103
- static serial_t *tx_callback_obj[UART_NUM];
104
100
105
101
static serial_t serial_debug = { .uart = NP, .index = UART_NUM };
106
102
103
+ /* Aim of the function is to get serial_s pointer using huart pointer */
104
+ /* Highly inspired from magical linux kernel's "container_of" */
105
+ serial_t *get_serial_obj(UART_HandleTypeDef *huart)
106
+ {
107
+ struct serial_s *obj_s;
108
+ serial_t *obj;
109
+
110
+ obj_s = (struct serial_s *)((char *)huart - offsetof(struct serial_s, handle));
111
+ obj = (serial_t *)((char *)obj_s - offsetof(serial_t, uart));
112
+
113
+ return (obj);
114
+ }
115
+
107
116
/**
108
117
* @brief Function called to initialize the uart interface
109
118
* @param obj : pointer to serial_t structure
110
119
* @retval None
111
120
*/
112
- void uart_init(serial_t *obj)
121
+ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits )
113
122
{
114
123
if (obj == NULL) {
115
124
return;
@@ -284,10 +293,10 @@ void uart_init(serial_t *obj)
284
293
/* Configure uart */
285
294
uart_handlers[obj->index] = huart;
286
295
huart->Instance = (USART_TypeDef *)(obj->uart);
287
- huart->Init.BaudRate = obj-> baudrate;
288
- huart->Init.WordLength = obj-> databits;
289
- huart->Init.StopBits = obj-> stopbits;
290
- huart->Init.Parity = obj-> parity;
296
+ huart->Init.BaudRate = baudrate;
297
+ huart->Init.WordLength = databits;
298
+ huart->Init.StopBits = stopbits;
299
+ huart->Init.Parity = parity;
291
300
huart->Init.Mode = UART_MODE_TX_RX;
292
301
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
293
302
huart->Init.OverSampling = UART_OVERSAMPLING_16;
@@ -306,7 +315,7 @@ void uart_init(serial_t *obj)
306
315
* check Reference Manual
307
316
*/
308
317
if (obj->uart == LPUART1) {
309
- if (obj-> baudrate <= 9600) {
318
+ if (baudrate <= 9600) {
310
319
#if defined(USART_CR3_UCESM)
311
320
HAL_UARTEx_EnableClockStopMode(huart);
312
321
#endif
@@ -323,7 +332,7 @@ void uart_init(serial_t *obj)
323
332
}
324
333
/* Trying to change LPUART clock source */
325
334
/* If baudrate is lower than or equal to 9600 try to change to LSE */
326
- if (obj-> baudrate <= 9600) {
335
+ if (baudrate <= 9600) {
327
336
/* Enable the clock if not already set by user */
328
337
enableClock(LSE_CLOCK);
329
338
@@ -468,6 +477,11 @@ void uart_deinit(serial_t *obj)
468
477
}
469
478
470
479
HAL_UART_DeInit(uart_handlers[obj->index]);
480
+
481
+ /* Release uart debug to ensure init */
482
+ if (serial_debug.index == obj->index) {
483
+ serial_debug.index = UART_NUM;
484
+ }
471
485
}
472
486
473
487
#if defined(HAL_PWR_MODULE_ENABLED) && defined(UART_IT_WUF)
@@ -564,12 +578,8 @@ void uart_debug_init(void)
564
578
#else
565
579
serial_debug.pin_tx = pinmap_pin(DEBUG_UART, PinMap_UART_TX);
566
580
#endif
567
- serial_debug.baudrate = DEBUG_UART_BAUDRATE;
568
- serial_debug.parity = UART_PARITY_NONE;
569
- serial_debug.databits = UART_WORDLENGTH_8B;
570
- serial_debug.stopbits = UART_STOPBITS_1;
571
581
572
- uart_init(&serial_debug);
582
+ uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1 );
573
583
}
574
584
}
575
585
@@ -581,38 +591,46 @@ void uart_debug_init(void)
581
591
*/
582
592
size_t uart_debug_write(uint8_t *data, uint32_t size)
583
593
{
584
- uint8_t index = 0;
585
594
uint32_t tickstart = HAL_GetTick();
586
595
587
596
if (DEBUG_UART == NP) {
588
597
return 0;
589
598
}
590
- /* Search if DEBUG_UART already initialized */
591
- for (index = 0; index < UART_NUM; index++) {
592
- if (uart_handlers[index] != NULL) {
593
- if (DEBUG_UART == uart_handlers[index]->Instance) {
594
- break;
599
+ if (serial_debug.index >= UART_NUM) {
600
+ /* Search if DEBUG_UART already initialized */
601
+ for (serial_debug.index = 0; serial_debug.index < UART_NUM; serial_debug.index++) {
602
+ if (uart_handlers[serial_debug.index] != NULL) {
603
+ if (DEBUG_UART == uart_handlers[serial_debug.index]->Instance) {
604
+ break;
605
+ }
595
606
}
596
607
}
597
- }
598
608
599
- if (index >= UART_NUM) {
600
- /* DEBUG_UART not initialized */
601
609
if (serial_debug.index >= UART_NUM) {
610
+ /* DEBUG_UART not initialized */
602
611
uart_debug_init();
603
612
if (serial_debug.index >= UART_NUM) {
604
613
return 0;
605
614
}
615
+ } else {
616
+ serial_t *obj = get_serial_obj(uart_handlers[serial_debug.index]);
617
+ if (obj) {
618
+ serial_debug.irq = obj->irq;
619
+ }
606
620
}
607
- index = serial_debug.index;
608
621
}
609
622
610
- while (HAL_UART_Transmit(uart_handlers[index], data, size, TX_TIMEOUT) != HAL_OK) {
623
+ HAL_NVIC_DisableIRQ(serial_debug.irq);
624
+
625
+ while (HAL_UART_Transmit(uart_handlers[serial_debug.index], data, size, TX_TIMEOUT) != HAL_OK) {
611
626
if ((HAL_GetTick() - tickstart) >= TX_TIMEOUT) {
612
- return 0;
627
+ size = 0;
628
+ break;
613
629
}
614
630
}
615
631
632
+ HAL_NVIC_EnableIRQ(serial_debug.irq);
633
+
616
634
return size;
617
635
}
618
636
@@ -655,8 +673,7 @@ int uart_getc(serial_t *obj, unsigned char *c)
655
673
656
674
*c = (unsigned char)(obj->recv);
657
675
/* Restart RX irq */
658
- UART_HandleTypeDef *huart = uart_handlers[obj->index];
659
- HAL_UART_Receive_IT(huart, &(obj->recv), 1);
676
+ HAL_UART_Receive_IT(uart_handlers[obj->index], &(obj->recv), 1);
660
677
661
678
return 0;
662
679
}
@@ -678,16 +695,16 @@ void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t *))
678
695
if (serial_rx_active(obj)) {
679
696
return;
680
697
}
698
+ obj->rx_callback = callback;
699
+
700
+ /* Must disable interrupt to prevent handle lock contention */
701
+ HAL_NVIC_DisableIRQ(obj->irq);
681
702
682
- rx_callback[obj->index] = callback;
683
- rx_callback_obj[obj->index] = obj;
703
+ HAL_UART_Receive_IT(uart_handlers[obj->index], &(obj->recv), 1);
684
704
705
+ /* Enable interrupt */
685
706
HAL_NVIC_SetPriority(obj->irq, 0, 1);
686
707
HAL_NVIC_EnableIRQ(obj->irq);
687
-
688
- if (HAL_UART_Receive_IT(uart_handlers[obj->index], &(obj->recv), 1) != HAL_OK) {
689
- return;
690
- }
691
708
}
692
709
693
710
/**
@@ -702,25 +719,25 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))
702
719
if (obj == NULL) {
703
720
return;
704
721
}
722
+ obj->tx_callback = callback;
705
723
706
- tx_callback[obj->index] = callback;
707
- tx_callback_obj[obj->index] = obj;
724
+ /* Must disable interrupt to prevent handle lock contention */
725
+ HAL_NVIC_DisableIRQ(obj->irq);
726
+
727
+ /* The following function will enable UART_IT_TXE and error interrupts */
728
+ HAL_UART_Transmit_IT(uart_handlers[obj->index], &obj->tx_buff[obj->tx_tail], 1);
708
729
709
730
/* Enable interrupt */
710
731
HAL_NVIC_SetPriority(obj->irq, 0, 2);
711
732
HAL_NVIC_EnableIRQ(obj->irq);
712
-
713
- /* The following function will enable UART_IT_TXE and error interrupts */
714
- if (HAL_UART_Transmit_IT(uart_handlers[obj->index], &obj->tx_buff[obj->tx_tail], 1) != HAL_OK) {
715
- return;
716
- }
717
733
}
718
734
719
735
/**
720
736
* @brief Return index of the serial handler
721
737
* @param UartHandle pointer on the uart reference
722
738
* @retval index
723
739
*/
740
+ /*
724
741
uint8_t uart_index(UART_HandleTypeDef *huart)
725
742
{
726
743
uint8_t i = 0;
@@ -736,6 +753,7 @@ uint8_t uart_index(UART_HandleTypeDef *huart)
736
753
737
754
return i;
738
755
}
756
+ */
739
757
740
758
/**
741
759
* @brief Rx Transfer completed callback
@@ -744,10 +762,9 @@ uint8_t uart_index(UART_HandleTypeDef *huart)
744
762
*/
745
763
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
746
764
{
747
- uint8_t index = uart_index(huart);
748
-
749
- if (index < UART_NUM) {
750
- rx_callback[index](rx_callback_obj[index]);
765
+ serial_t *obj = get_serial_obj(huart);
766
+ if (obj) {
767
+ obj->rx_callback(obj);
751
768
}
752
769
}
753
770
@@ -758,14 +775,11 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
758
775
*/
759
776
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
760
777
{
761
- uint8_t index = uart_index(huart);
762
- serial_t *obj = tx_callback_obj[index];
778
+ serial_t *obj = get_serial_obj(huart);
763
779
764
- if (index < UART_NUM) {
765
- if (tx_callback[index](obj) != -1) {
766
- if (HAL_UART_Transmit_IT(uart_handlers[obj->index], &obj->tx_buff[obj->tx_tail], 1) != HAL_OK) {
767
- return;
768
- }
780
+ if (obj && obj->tx_callback(obj) != -1) {
781
+ if (HAL_UART_Transmit_IT(huart, &obj->tx_buff[obj->tx_tail], 1) != HAL_OK) {
782
+ return;
769
783
}
770
784
}
771
785
}
@@ -777,30 +791,32 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
777
791
*/
778
792
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
779
793
{
780
- volatile uint32_t tmpval;
781
794
#if defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32L1xx)
782
795
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
783
- tmpval = huart->Instance->DR ; /* Clear PE flag */
796
+ __HAL_UART_CLEAR_PEFLAG( huart) ; /* Clear PE flag */
784
797
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
785
- tmpval = huart->Instance->DR ; /* Clear FE flag */
798
+ __HAL_UART_CLEAR_FEFLAG( huart) ; /* Clear FE flag */
786
799
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) {
787
- tmpval = huart->Instance->DR ; /* Clear NE flag */
800
+ __HAL_UART_CLEAR_NEFLAG( huart) ; /* Clear NE flag */
788
801
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
789
- tmpval = huart->Instance->DR ; /* Clear ORE flag */
802
+ __HAL_UART_CLEAR_OREFLAG( huart) ; /* Clear ORE flag */
790
803
}
791
804
#else
792
805
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) {
793
- tmpval = huart->Instance->RDR ; /* Clear PE flag */
806
+ __HAL_UART_CLEAR_FLAG( huart, UART_CLEAR_PEF) ; /* Clear PE flag */
794
807
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) {
795
- tmpval = huart->Instance->RDR ; /* Clear FE flag */
808
+ __HAL_UART_CLEAR_FLAG( huart, UART_CLEAR_FEF) ; /* Clear FE flag */
796
809
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) {
797
- tmpval = huart->Instance->RDR ; /* Clear NE flag */
810
+ __HAL_UART_CLEAR_FLAG( huart, UART_CLEAR_NEF) ; /* Clear NE flag */
798
811
} else if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
799
- tmpval = huart->Instance->RDR ; /* Clear ORE flag */
812
+ __HAL_UART_CLEAR_FLAG( huart, UART_CLEAR_OREF) ; /* Clear ORE flag */
800
813
}
801
814
#endif
802
-
803
- UNUSED(tmpval);
815
+ /* Restart receive interrupt after any error */
816
+ serial_t *obj = get_serial_obj(huart);
817
+ if (obj && !serial_rx_active(obj)) {
818
+ HAL_UART_Receive_IT(huart, &(obj->recv), 1);
819
+ }
804
820
}
805
821
806
822
/**
@@ -1010,9 +1026,7 @@ void UART10_IRQHandler(void)
1010
1026
*/
1011
1027
void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
1012
1028
{
1013
- uint8_t index = uart_index(huart);
1014
- serial_t *obj = rx_callback_obj[index];
1015
-
1029
+ serial_t *obj = get_serial_obj(huart);
1016
1030
HAL_UART_Receive_IT(huart, &(obj->recv), 1);
1017
1031
}
1018
1032
#endif /* HAL_UART_MODULE_ENABLED */
0 commit comments