diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.c index 081c0ae8ac..8aba3ca9cb 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -34,6 +34,9 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag); #endif +/* Number of while blocking timeouts for the stm32_putc */ +#define TX_BLOCK_TIMEOUT 1000 + enum { #ifdef BSP_USING_UART1 @@ -230,6 +233,7 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c return -RT_ERROR; } uart->DR_mask = stm32_uart_get_mask(uart->handle.Init.WordLength, uart->handle.Init.Parity); + uart->tx_block_timeout = TX_BLOCK_TIMEOUT; return RT_EOK; } @@ -248,10 +252,15 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar { /* disable interrupt */ case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ + { + /* disable uart irq */ NVIC_DisableIRQ(uart->config->irq_type); - /* disable interrupt */ - __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_RXNE); + rt_uint32_t direction = (rt_uint32_t)arg; + if(direction == RT_DEVICE_FLAG_INT_RX) + { + /* disable interrupt */ + __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_RXNE); + } #ifdef RT_SERIAL_USING_DMA /* disable DMA */ @@ -278,29 +287,56 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar } #endif break; + } /* enable interrupt */ case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ + { + /* enable uart irq */ HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0); HAL_NVIC_EnableIRQ(uart->config->irq_type); - /* enable interrupt */ - __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_RXNE); + rt_uint32_t direction = (rt_uint32_t)arg; + if(direction == RT_DEVICE_FLAG_INT_RX) + { + /* enable interrupt */ + __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_RXNE); + } break; + } #ifdef RT_SERIAL_USING_DMA case RT_DEVICE_CTRL_CONFIG: + { stm32_dma_config(serial, ctrl_arg); break; + } #endif case RT_DEVICE_CTRL_CLOSE: + { if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK ) { RT_ASSERT(0) } break; + } + case UART_CTRL_SET_BLOCK_TIMEOUT: + { + rt_uint32_t block_timeout = (rt_uint32_t)arg; + if(block_timeout > 0) + { + uart->tx_block_timeout = block_timeout; + } + else + { + return -RT_ERROR; + } + break; + } + + default: + break; } return RT_EOK; } @@ -313,6 +349,7 @@ static int stm32_putc(struct rt_serial_device *serial, char c) RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct stm32_uart, serial); + rt_uint32_t block_timeout = uart->tx_block_timeout; UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC); #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \ || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L5) \ @@ -322,8 +359,8 @@ static int stm32_putc(struct rt_serial_device *serial, char c) #else uart->handle.Instance->DR = c; #endif - while (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) == RESET); - return 1; + while (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) == RESET && block_timeout--); + return (block_timeout != 0) ? 1 : -1; } static int stm32_getc(struct rt_serial_device *serial) @@ -439,13 +476,6 @@ static void uart_isr(struct rt_serial_device *serial) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } -#ifdef RT_SERIAL_USING_DMA - else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET) - && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET)) - { - dma_recv_isr(serial, UART_RX_DMA_IT_IDLE_FLAG); - __HAL_UART_CLEAR_IDLEFLAG(&uart->handle); - } else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TC) != RESET)) { @@ -453,8 +483,21 @@ static void uart_isr(struct rt_serial_device *serial) { HAL_UART_IRQHandler(&(uart->handle)); } + else + { + /* Transmission complete interrupt disable ( CR1 Register) */ + __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE); + } UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC); } +#ifdef RT_SERIAL_USING_DMA + else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET) + && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET)) + { + dma_recv_isr(serial, UART_RX_DMA_IT_IDLE_FLAG); + __HAL_UART_CLEAR_IDLEFLAG(&uart->handle); + } #endif else { diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.h index 1885d164b5..1d505b7d3a 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -43,6 +43,8 @@ int rt_hw_usart_init(void); #define UART_RX_DMA_IT_HT_FLAG 0x01 #define UART_RX_DMA_IT_TC_FLAG 0x02 +#define UART_CTRL_SET_BLOCK_TIMEOUT 0x20 + /* stm32 config class */ struct stm32_uart_config { @@ -59,6 +61,7 @@ struct stm32_uart UART_HandleTypeDef handle; struct stm32_uart_config *config; rt_uint32_t DR_mask; + rt_uint32_t tx_block_timeout; #ifdef RT_SERIAL_USING_DMA struct