@@ -97,19 +97,28 @@ typedef enum {
9797} uart_index_t ;
9898
9999static 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 ];
104100
105101static serial_t serial_debug = { .uart = NP , .index = UART_NUM };
106102
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+
107116/**
108117 * @brief Function called to initialize the uart interface
109118 * @param obj : pointer to serial_t structure
110119 * @retval None
111120 */
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 )
113122{
114123 if (obj == NULL ) {
115124 return ;
@@ -284,10 +293,10 @@ void uart_init(serial_t *obj)
284293 /* Configure uart */
285294 uart_handlers [obj -> index ] = huart ;
286295 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 ;
291300 huart -> Init .Mode = UART_MODE_TX_RX ;
292301 huart -> Init .HwFlowCtl = UART_HWCONTROL_NONE ;
293302 huart -> Init .OverSampling = UART_OVERSAMPLING_16 ;
@@ -306,7 +315,7 @@ void uart_init(serial_t *obj)
306315 * check Reference Manual
307316 */
308317 if (obj -> uart == LPUART1 ) {
309- if (obj -> baudrate <= 9600 ) {
318+ if (baudrate <= 9600 ) {
310319#if defined(USART_CR3_UCESM )
311320 HAL_UARTEx_EnableClockStopMode (huart );
312321#endif
@@ -323,7 +332,7 @@ void uart_init(serial_t *obj)
323332 }
324333 /* Trying to change LPUART clock source */
325334 /* If baudrate is lower than or equal to 9600 try to change to LSE */
326- if (obj -> baudrate <= 9600 ) {
335+ if (baudrate <= 9600 ) {
327336 /* Enable the clock if not already set by user */
328337 enableClock (LSE_CLOCK );
329338
@@ -468,6 +477,11 @@ void uart_deinit(serial_t *obj)
468477 }
469478
470479 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+ }
471485}
472486
473487#if defined(HAL_PWR_MODULE_ENABLED ) && defined(UART_IT_WUF )
@@ -564,12 +578,8 @@ void uart_debug_init(void)
564578#else
565579 serial_debug .pin_tx = pinmap_pin (DEBUG_UART , PinMap_UART_TX );
566580#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 ;
571581
572- uart_init (& serial_debug );
582+ uart_init (& serial_debug , DEBUG_UART_BAUDRATE , UART_WORDLENGTH_8B , UART_PARITY_NONE , UART_STOPBITS_1 );
573583 }
574584}
575585
@@ -581,38 +591,46 @@ void uart_debug_init(void)
581591 */
582592size_t uart_debug_write (uint8_t * data , uint32_t size )
583593{
584- uint8_t index = 0 ;
585594 uint32_t tickstart = HAL_GetTick ();
586595
587596 if (DEBUG_UART == NP ) {
588597 return 0 ;
589598 }
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+ }
595606 }
596607 }
597- }
598608
599- if (index >= UART_NUM ) {
600- /* DEBUG_UART not initialized */
601609 if (serial_debug .index >= UART_NUM ) {
610+ /* DEBUG_UART not initialized */
602611 uart_debug_init ();
603612 if (serial_debug .index >= UART_NUM ) {
604613 return 0 ;
605614 }
615+ } else {
616+ serial_t * obj = get_serial_obj (uart_handlers [serial_debug .index ]);
617+ if (obj ) {
618+ serial_debug .irq = obj -> irq ;
619+ }
606620 }
607- index = serial_debug .index ;
608621 }
609622
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 ) {
611626 if ((HAL_GetTick () - tickstart ) >= TX_TIMEOUT ) {
612- return 0 ;
627+ size = 0 ;
628+ break ;
613629 }
614630 }
615631
632+ HAL_NVIC_EnableIRQ (serial_debug .irq );
633+
616634 return size ;
617635}
618636
@@ -655,8 +673,7 @@ int uart_getc(serial_t *obj, unsigned char *c)
655673
656674 * c = (unsigned char )(obj -> recv );
657675 /* 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 );
660677
661678 return 0 ;
662679}
@@ -678,16 +695,16 @@ void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t *))
678695 if (serial_rx_active (obj )) {
679696 return ;
680697 }
698+ obj -> rx_callback = callback ;
699+
700+ /* Must disable interrupt to prevent handle lock contention */
701+ HAL_NVIC_DisableIRQ (obj -> irq );
681702
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 );
684704
705+ /* Enable interrupt */
685706 HAL_NVIC_SetPriority (obj -> irq , 0 , 1 );
686707 HAL_NVIC_EnableIRQ (obj -> irq );
687-
688- if (HAL_UART_Receive_IT (uart_handlers [obj -> index ], & (obj -> recv ), 1 ) != HAL_OK ) {
689- return ;
690- }
691708}
692709
693710/**
@@ -702,25 +719,25 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))
702719 if (obj == NULL ) {
703720 return ;
704721 }
722+ obj -> tx_callback = callback ;
705723
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 );
708729
709730 /* Enable interrupt */
710731 HAL_NVIC_SetPriority (obj -> irq , 0 , 2 );
711732 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- }
717733}
718734
719735/**
720736 * @brief Return index of the serial handler
721737 * @param UartHandle pointer on the uart reference
722738 * @retval index
723739 */
740+ /*
724741uint8_t uart_index(UART_HandleTypeDef *huart)
725742{
726743 uint8_t i = 0;
@@ -736,6 +753,7 @@ uint8_t uart_index(UART_HandleTypeDef *huart)
736753
737754 return i;
738755}
756+ */
739757
740758/**
741759 * @brief Rx Transfer completed callback
@@ -744,10 +762,9 @@ uint8_t uart_index(UART_HandleTypeDef *huart)
744762 */
745763void HAL_UART_RxCpltCallback (UART_HandleTypeDef * huart )
746764{
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 );
751768 }
752769}
753770
@@ -758,14 +775,11 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
758775 */
759776void HAL_UART_TxCpltCallback (UART_HandleTypeDef * huart )
760777{
761- uint8_t index = uart_index (huart );
762- serial_t * obj = tx_callback_obj [index ];
778+ serial_t * obj = get_serial_obj (huart );
763779
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 ;
769783 }
770784 }
771785}
@@ -777,30 +791,32 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
777791 */
778792void HAL_UART_ErrorCallback (UART_HandleTypeDef * huart )
779793{
780- volatile uint32_t tmpval ;
781794#if defined(STM32F1xx ) || defined(STM32F2xx ) || defined(STM32F4xx ) || defined(STM32L1xx )
782795 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 */
784797 } 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 */
786799 } 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 */
788801 } 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 */
790803 }
791804#else
792805 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 */
794807 } 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 */
796809 } 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 */
798811 } 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 */
800813 }
801814#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+ }
804820}
805821
806822/**
@@ -1010,9 +1026,7 @@ void UART10_IRQHandler(void)
10101026 */
10111027void HAL_UARTEx_WakeupCallback (UART_HandleTypeDef * huart )
10121028{
1013- uint8_t index = uart_index (huart );
1014- serial_t * obj = rx_callback_obj [index ];
1015-
1029+ serial_t * obj = get_serial_obj (huart );
10161030 HAL_UART_Receive_IT (huart , & (obj -> recv ), 1 );
10171031}
10181032#endif /* HAL_UART_MODULE_ENABLED */
0 commit comments