@@ -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