diff --git a/bsp/at32/at32a403a-start/board/Kconfig b/bsp/at32/at32a403a-start/board/Kconfig index 018b0815bc5..bae96053cc0 100644 --- a/bsp/at32/at32a403a-start/board/Kconfig +++ b/bsp/at32/at32a403a-start/board/Kconfig @@ -80,6 +80,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -107,6 +113,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -134,6 +146,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32a423-start/board/Kconfig b/bsp/at32/at32a423-start/board/Kconfig index ea24f1513f1..29d51887585 100644 --- a/bsp/at32/at32a423-start/board/Kconfig +++ b/bsp/at32/at32a423-start/board/Kconfig @@ -95,6 +95,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -122,6 +128,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -149,6 +161,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f402-start/board/Kconfig b/bsp/at32/at32f402-start/board/Kconfig index b83b21f2616..ae21e7e68e6 100644 --- a/bsp/at32/at32f402-start/board/Kconfig +++ b/bsp/at32/at32f402-start/board/Kconfig @@ -106,6 +106,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -133,6 +139,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -160,6 +172,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f403a-start/board/Kconfig b/bsp/at32/at32f403a-start/board/Kconfig index b0dade514b4..b905e52b7c8 100644 --- a/bsp/at32/at32f403a-start/board/Kconfig +++ b/bsp/at32/at32f403a-start/board/Kconfig @@ -80,6 +80,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -107,6 +113,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -134,6 +146,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f405-start/board/Kconfig b/bsp/at32/at32f405-start/board/Kconfig index 5de191fc0f6..edd92e93208 100644 --- a/bsp/at32/at32f405-start/board/Kconfig +++ b/bsp/at32/at32f405-start/board/Kconfig @@ -125,6 +125,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -152,6 +158,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -179,6 +191,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f407-start/board/Kconfig b/bsp/at32/at32f407-start/board/Kconfig index b672271c649..037d736049a 100644 --- a/bsp/at32/at32f407-start/board/Kconfig +++ b/bsp/at32/at32f407-start/board/Kconfig @@ -103,6 +103,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -130,6 +136,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -157,6 +169,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f413-start/board/Kconfig b/bsp/at32/at32f413-start/board/Kconfig index 19b148f6f84..eb784abc99d 100644 --- a/bsp/at32/at32f413-start/board/Kconfig +++ b/bsp/at32/at32f413-start/board/Kconfig @@ -80,6 +80,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -107,6 +113,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -134,6 +146,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f415-start/board/Kconfig b/bsp/at32/at32f415-start/board/Kconfig index e7861dc72da..b6f1375c83e 100644 --- a/bsp/at32/at32f415-start/board/Kconfig +++ b/bsp/at32/at32f415-start/board/Kconfig @@ -95,6 +95,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -122,6 +128,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -149,6 +161,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f421-start/board/Kconfig b/bsp/at32/at32f421-start/board/Kconfig index 16abb900116..982750fdbdf 100644 --- a/bsp/at32/at32f421-start/board/Kconfig +++ b/bsp/at32/at32f421-start/board/Kconfig @@ -75,6 +75,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -102,8 +108,13 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif - endif menuconfig BSP_USING_PWM bool "Enable PWM" diff --git a/bsp/at32/at32f423-start/board/Kconfig b/bsp/at32/at32f423-start/board/Kconfig index 13d3a8b173b..a272271c690 100644 --- a/bsp/at32/at32f423-start/board/Kconfig +++ b/bsp/at32/at32f423-start/board/Kconfig @@ -95,6 +95,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -122,6 +128,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -149,6 +161,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f425-start/board/Kconfig b/bsp/at32/at32f425-start/board/Kconfig index 4a517ac6f59..2aa0bd44306 100644 --- a/bsp/at32/at32f425-start/board/Kconfig +++ b/bsp/at32/at32f425-start/board/Kconfig @@ -95,6 +95,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -122,6 +128,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -149,6 +161,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f435-start/board/Kconfig b/bsp/at32/at32f435-start/board/Kconfig index 828d66eba43..25a75ce5305 100644 --- a/bsp/at32/at32f435-start/board/Kconfig +++ b/bsp/at32/at32f435-start/board/Kconfig @@ -129,6 +129,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -156,6 +162,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -183,6 +195,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32f437-start/board/Kconfig b/bsp/at32/at32f437-start/board/Kconfig index 07a9e6f7783..5e215329fc6 100644 --- a/bsp/at32/at32f437-start/board/Kconfig +++ b/bsp/at32/at32f437-start/board/Kconfig @@ -152,6 +152,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -179,6 +185,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -206,6 +218,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif endif diff --git a/bsp/at32/at32m412-start/board/Kconfig b/bsp/at32/at32m412-start/board/Kconfig index 078e537778b..4bb310d92b8 100644 --- a/bsp/at32/at32m412-start/board/Kconfig +++ b/bsp/at32/at32m412-start/board/Kconfig @@ -75,6 +75,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -102,8 +108,13 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif - endif menuconfig BSP_USING_PWM bool "Enable PWM" diff --git a/bsp/at32/at32m416-start/board/Kconfig b/bsp/at32/at32m416-start/board/Kconfig index c80e07023a8..1601313f4a0 100644 --- a/bsp/at32/at32m416-start/board/Kconfig +++ b/bsp/at32/at32m416-start/board/Kconfig @@ -75,6 +75,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -102,8 +108,13 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif - endif menuconfig BSP_USING_PWM bool "Enable PWM" diff --git a/bsp/at32/libraries/rt_drivers/drv_usart_v2.c b/bsp/at32/libraries/rt_drivers/drv_usart_v2.c index e7a33d59d34..68dcf60ccd5 100644 --- a/bsp/at32/libraries/rt_drivers/drv_usart_v2.c +++ b/bsp/at32/libraries/rt_drivers/drv_usart_v2.c @@ -153,7 +153,7 @@ static rt_err_t at32_configure(struct rt_serial_device *serial, } #ifdef RT_SERIAL_USING_DMA if (!(serial->parent.open_flag & RT_DEVICE_OFLAG_OPEN)) { - instance->last_index = serial->config.rx_bufsz; + instance->last_index = serial->config.dma_ping_bufsz; } #endif usart_hardware_flow_control_set(instance->uart_x, flow_control); @@ -321,7 +321,6 @@ static void at32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) { dma_init_type dma_init_struct; dma_channel_type *dma_channel = NULL; - struct rt_serial_rx_fifo *rx_fifo; struct at32_uart *instance; struct dma_config *dma_config; @@ -380,9 +379,11 @@ static void at32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) /* enable interrupt */ if (flag == RT_DEVICE_FLAG_DMA_RX) { - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); + /* start dma transfer */ - _uart_dma_receive(instance, rx_fifo->buffer, serial->config.rx_bufsz); + _uart_dma_receive(instance, ptr, serial->config.dma_ping_bufsz); } /* dma irq should set in dma tx mode */ @@ -441,7 +442,7 @@ void dma_rx_isr(struct rt_serial_device *serial) if (counter <= instance->last_index) recv_len = instance->last_index - counter; else - recv_len = serial->config.rx_bufsz + instance->last_index - counter; + recv_len = serial->config.dma_ping_bufsz + instance->last_index - counter; if (recv_len) { @@ -492,22 +493,14 @@ static void usart_isr(struct rt_serial_device *serial) if (usart_flag_get(instance->uart_x, USART_RDBF_FLAG) != RESET) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), usart_data_receive(instance->uart_x)); - + char chr = usart_data_receive(instance->uart_x); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } else if ((usart_flag_get(instance->uart_x, USART_TDBE_FLAG) != RESET) && (instance->uart_x->ctrl1_bit.tdbeien)) { - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - rt_uint8_t put_char = 0; - if (rt_ringbuffer_getchar(&(tx_fifo->rb), &put_char)) + if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK) { usart_data_transmit(instance->uart_x, put_char); } @@ -927,6 +920,7 @@ static void at32_uart_get_config(void) uart_config[UART1_INDEX].serial.config.rx_bufsz = BSP_UART1_RX_BUFSIZE; uart_config[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE; #ifdef BSP_UART1_RX_USING_DMA + uart_config[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE; uart_config[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart1_dma_rx = UART1_RX_DMA_CONFIG; uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx; @@ -944,6 +938,7 @@ static void at32_uart_get_config(void) uart_config[UART2_INDEX].serial.config.rx_bufsz = BSP_UART2_RX_BUFSIZE; uart_config[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE; #ifdef BSP_UART2_RX_USING_DMA + uart_config[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE; uart_config[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart2_dma_rx = UART2_RX_DMA_CONFIG; uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx; @@ -961,6 +956,7 @@ static void at32_uart_get_config(void) uart_config[UART3_INDEX].serial.config.rx_bufsz = BSP_UART3_RX_BUFSIZE; uart_config[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE; #ifdef BSP_UART3_RX_USING_DMA + uart_config[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE; uart_config[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart3_dma_rx = UART3_RX_DMA_CONFIG; uart_config[UART3_INDEX].dma_rx = &uart3_dma_rx; @@ -978,6 +974,7 @@ static void at32_uart_get_config(void) uart_config[UART4_INDEX].serial.config.rx_bufsz = BSP_UART4_RX_BUFSIZE; uart_config[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE; #ifdef BSP_UART4_RX_USING_DMA + uart_config[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE; uart_config[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart4_dma_rx = UART4_RX_DMA_CONFIG; uart_config[UART4_INDEX].dma_rx = &uart4_dma_rx; @@ -995,6 +992,7 @@ static void at32_uart_get_config(void) uart_config[UART5_INDEX].serial.config.rx_bufsz = BSP_UART5_RX_BUFSIZE; uart_config[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE; #ifdef BSP_UART5_RX_USING_DMA + uart_config[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE; uart_config[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart5_dma_rx = UART5_RX_DMA_CONFIG; uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx; @@ -1012,6 +1010,7 @@ static void at32_uart_get_config(void) uart_config[UART6_INDEX].serial.config.rx_bufsz = BSP_UART6_RX_BUFSIZE; uart_config[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE; #ifdef BSP_UART6_RX_USING_DMA + uart_config[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE; uart_config[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart6_dma_rx = UART6_RX_DMA_CONFIG; uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx; @@ -1029,6 +1028,7 @@ static void at32_uart_get_config(void) uart_config[UART7_INDEX].serial.config.rx_bufsz = BSP_UART7_RX_BUFSIZE; uart_config[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE; #ifdef BSP_UART7_RX_USING_DMA + uart_config[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE; uart_config[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart7_dma_rx = UART7_RX_DMA_CONFIG; uart_config[UART7_INDEX].dma_rx = &uart7_dma_rx; @@ -1046,6 +1046,7 @@ static void at32_uart_get_config(void) uart_config[UART8_INDEX].serial.config.rx_bufsz = BSP_UART8_RX_BUFSIZE; uart_config[UART8_INDEX].serial.config.tx_bufsz = BSP_UART8_TX_BUFSIZE; #ifdef BSP_UART8_RX_USING_DMA + uart_config[UART8_INDEX].serial.config.dma_ping_bufsz = BSP_UART8_DMA_PING_BUFSIZE; uart_config[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart8_dma_rx = UART8_RX_DMA_CONFIG; uart_config[UART8_INDEX].dma_rx = &uart8_dma_rx; diff --git a/bsp/gd32/arm/gd32407v-lckfb/board/Kconfig b/bsp/gd32/arm/gd32407v-lckfb/board/Kconfig index 1f8efefec34..c7096bc7078 100644 --- a/bsp/gd32/arm/gd32407v-lckfb/board/Kconfig +++ b/bsp/gd32/arm/gd32407v-lckfb/board/Kconfig @@ -75,6 +75,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 default 0 + config BSP_UART0_DMA_PING_BUFSIZE + int "Set UART0 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART0_RX_USING_DMA + default 32 + config BSP_USING_UART1 bool "Enable UART1" default y @@ -103,6 +109,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 32 + config BSP_USING_UART2 bool "Enable UART2" default n @@ -131,6 +143,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 default 0 + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 32 + config BSP_USING_UART3 bool "Enable UART3" default n @@ -159,6 +177,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 default 0 + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 32 + config BSP_USING_UART4 bool "Enable UART4" default n @@ -187,6 +211,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 default 0 + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 32 + config BSP_USING_UART5 bool "Enable UART5" default n @@ -214,6 +244,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 default 0 + + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 32 endif menuconfig BSP_USING_SPI diff --git a/bsp/gd32/arm/gd32407v-start/board/Kconfig b/bsp/gd32/arm/gd32407v-start/board/Kconfig index 67d46c96d63..9eae9dc7257 100644 --- a/bsp/gd32/arm/gd32407v-start/board/Kconfig +++ b/bsp/gd32/arm/gd32407v-start/board/Kconfig @@ -55,6 +55,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 default 0 + config BSP_UART0_DMA_PING_BUFSIZE + int "Set UART0 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART0_RX_USING_DMA + default 32 + config BSP_USING_UART1 bool "Enable UART1" default y @@ -83,6 +89,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 32 + config BSP_USING_UART2 bool "Enable UART2" default n @@ -111,6 +123,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 default 0 + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 32 + config BSP_USING_UART3 bool "Enable UART3" default n @@ -139,6 +157,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 default 0 + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 32 + config BSP_USING_UART4 bool "Enable UART4" default n @@ -167,6 +191,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 default 0 + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 32 + config BSP_USING_UART5 bool "Enable UART5" default n @@ -194,6 +224,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 default 0 + + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 32 endif menuconfig BSP_USING_SPI diff --git a/bsp/gd32/arm/gd32450z-eval/board/Kconfig b/bsp/gd32/arm/gd32450z-eval/board/Kconfig index b630c5364a0..b1d47c38902 100644 --- a/bsp/gd32/arm/gd32450z-eval/board/Kconfig +++ b/bsp/gd32/arm/gd32450z-eval/board/Kconfig @@ -29,7 +29,7 @@ menu "On-chip Peripheral Drivers" if BSP_USING_UART config BSP_USING_UART0 bool "Enable UART0" - default y + default n config BSP_UART0_RX_USING_DMA bool "Enable UART0 RX DMA" @@ -55,9 +55,15 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 default 0 + config BSP_UART0_DMA_PING_BUFSIZE + int "Set UART0 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART0_RX_USING_DMA + default 32 + config BSP_USING_UART1 bool "Enable UART1" - default n + default y config BSP_UART1_RX_USING_DMA bool "Enable UART1 RX DMA" @@ -83,6 +89,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 32 + config BSP_USING_UART2 bool "Enable UART2" default n @@ -111,6 +123,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 default 0 + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 32 + config BSP_USING_UART3 bool "Enable UART3" default n @@ -139,6 +157,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 default 0 + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 32 + config BSP_USING_UART4 bool "Enable UART4" default n @@ -167,6 +191,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 default 0 + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 32 + config BSP_USING_UART5 bool "Enable UART5" default n @@ -195,6 +225,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 default 0 + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 32 + config BSP_USING_UART6 bool "Enable UART6" default n @@ -223,6 +259,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART6 && RT_USING_SERIAL_V2 default 0 + config BSP_UART6_DMA_PING_BUFSIZE + int "Set UART6 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA + default 32 + config BSP_USING_UART7 bool "Enable UART7" default n @@ -250,6 +292,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on BSP_USING_UART7 && RT_USING_SERIAL_V2 default 0 + + config BSP_UART7_DMA_PING_BUFSIZE + int "Set UART7 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA + default 32 endif menuconfig BSP_USING_SPI diff --git a/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig b/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig index d27146d7352..843690f0800 100644 --- a/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig +++ b/bsp/gd32/arm/gd32470z-lckfb/board/Kconfig @@ -29,7 +29,7 @@ menu "On-chip Peripheral Drivers" if BSP_USING_UART config BSP_USING_UART0 bool "Enable UART0" - default y + default n config BSP_UART0_RX_USING_DMA bool "Enable UART0 RX DMA" @@ -55,9 +55,15 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART0 && RT_USING_SERIAL_V2 default 0 + config BSP_UART0_DMA_PING_BUFSIZE + int "Set UART0 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART0_RX_USING_DMA + default 32 + config BSP_USING_UART1 bool "Enable UART1" - default n + default y config BSP_UART1_RX_USING_DMA bool "Enable UART1 RX DMA" @@ -83,6 +89,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 && RT_USING_SERIAL_V2 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 32 + config BSP_USING_UART2 bool "Enable UART2" default n @@ -111,6 +123,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART2 && RT_USING_SERIAL_V2 default 0 + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 32 + config BSP_USING_UART3 bool "Enable UART3" default n @@ -139,6 +157,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART3 && RT_USING_SERIAL_V2 default 0 + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 32 + config BSP_USING_UART4 bool "Enable UART4" default n @@ -167,6 +191,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART4 && RT_USING_SERIAL_V2 default 0 + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 32 + config BSP_USING_UART5 bool "Enable UART5" default n @@ -195,6 +225,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART5 && RT_USING_SERIAL_V2 default 0 + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 32 + config BSP_USING_UART6 bool "Enable UART6" default n @@ -223,6 +259,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART6 && RT_USING_SERIAL_V2 default 0 + config BSP_UART6_DMA_PING_BUFSIZE + int "Set UART6 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA + default 32 + config BSP_USING_UART7 bool "Enable UART7" default n @@ -250,6 +292,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on BSP_USING_UART7 && RT_USING_SERIAL_V2 default 0 + + config BSP_UART7_DMA_PING_BUFSIZE + int "Set UART7 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA + default 32 endif menuconfig BSP_USING_SPI diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_usart_v2.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_usart_v2.c index 4412875a8eb..ee0dfffd574 100644 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_usart_v2.c +++ b/bsp/gd32/arm/libraries/gd32_drivers/drv_usart_v2.c @@ -247,7 +247,7 @@ static void dma_recv_isr (struct rt_serial_device *serial) } else { - recv_len = serial->config.rx_bufsz + uart->dma.last_index - counter; + recv_len = serial->config.dma_ping_bufsz + uart->dma.last_index - counter; } uart->dma.last_index = counter; rt_hw_interrupt_enable(level); @@ -272,8 +272,8 @@ static void usart_isr (struct rt_serial_device *serial) rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_putchar(&(rx_fifo->rb), usart_data_receive(uart->periph)); - + char chr = usart_data_receive(uart->periph); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); /* Clear RXNE interrupt flag */ @@ -281,12 +281,8 @@ static void usart_isr (struct rt_serial_device *serial) } else if (usart_interrupt_flag_get(uart->periph, USART_INT_FLAG_TBE) != RESET) { - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - rt_uint8_t put_char = 0; - if (rt_ringbuffer_getchar(&(tx_fifo->rb), &put_char)) + if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK) { usart_data_transmit(uart->periph, put_char); } @@ -709,7 +705,7 @@ static rt_err_t gd32_uart_configure (struct rt_serial_device *serial, struct ser uart = rt_container_of(serial, struct gd32_uart, serial); #ifdef RT_SERIAL_USING_DMA - uart->dma.last_index = serial->config.rx_bufsz; + uart->dma.last_index = serial->config.dma_ping_bufsz; #endif gd32_uart_gpio_init(uart); @@ -818,7 +814,6 @@ static void _uart_dma_transmit (struct gd32_uart *uart, rt_uint8_t *buffer, rt_u static void gd32_dma_config (struct rt_serial_device *serial, rt_ubase_t flag) { struct gd32_uart *uart; - struct rt_serial_rx_fifo *rx_fifo; dma_single_data_parameter_struct dma_init_struct = { 0 }; RT_ASSERT(serial != RT_NULL); @@ -862,9 +857,11 @@ static void gd32_dma_config (struct rt_serial_device *serial, rt_ubase_t flag) /* enable rx dma */ if (flag == RT_DEVICE_FLAG_DMA_RX) { - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); + /* start dma transfer */ - _uart_dma_receive(uart, rx_fifo->buffer, serial->config.rx_bufsz); + _uart_dma_receive(uart, ptr, serial->config.dma_ping_bufsz); } } @@ -1055,6 +1052,7 @@ static void gd32_uart_get_config (void) uart_obj[UART0_INDEX].serial.config.rx_bufsz = BSP_UART0_RX_BUFSIZE; uart_obj[UART0_INDEX].serial.config.tx_bufsz = BSP_UART0_TX_BUFSIZE; #ifdef BSP_UART0_RX_USING_DMA + uart_obj[UART0_INDEX].serial.config.dma_ping_bufsz = BSP_UART0_DMA_PING_BUFSIZE; uart_obj[UART0_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART0_TX_USING_DMA @@ -1068,6 +1066,7 @@ static void gd32_uart_get_config (void) uart_obj[UART1_INDEX].serial.config.rx_bufsz = BSP_UART1_RX_BUFSIZE; uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE; #ifdef BSP_UART1_RX_USING_DMA + uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE; uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART1_TX_USING_DMA @@ -1081,6 +1080,7 @@ static void gd32_uart_get_config (void) uart_obj[UART2_INDEX].serial.config.rx_bufsz = BSP_UART2_RX_BUFSIZE; uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE; #ifdef BSP_UART2_RX_USING_DMA + uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE; uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART2_TX_USING_DMA @@ -1094,6 +1094,7 @@ static void gd32_uart_get_config (void) uart_obj[UART3_INDEX].serial.config.rx_bufsz = BSP_UART3_RX_BUFSIZE; uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE; #ifdef BSP_UART3_RX_USING_DMA + uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE; uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART3_TX_USING_DMA @@ -1107,6 +1108,7 @@ static void gd32_uart_get_config (void) uart_obj[UART4_INDEX].serial.config.rx_bufsz = BSP_UART4_RX_BUFSIZE; uart_obj[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE; #ifdef BSP_UART4_RX_USING_DMA + uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE; uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART4_TX_USING_DMA @@ -1120,6 +1122,7 @@ static void gd32_uart_get_config (void) uart_obj[UART5_INDEX].serial.config.rx_bufsz = BSP_UART5_RX_BUFSIZE; uart_obj[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE; #ifdef BSP_UART5_RX_USING_DMA + uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE; uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART5_TX_USING_DMA @@ -1133,6 +1136,7 @@ static void gd32_uart_get_config (void) uart_obj[UART6_INDEX].serial.config.rx_bufsz = BSP_UART6_RX_BUFSIZE; uart_obj[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE; #ifdef BSP_UART6_RX_USING_DMA + uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE; uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART6_TX_USING_DMA @@ -1146,6 +1150,7 @@ static void gd32_uart_get_config (void) uart_obj[UART7_INDEX].serial.config.rx_bufsz = BSP_UART7_RX_BUFSIZE; uart_obj[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE; #ifdef BSP_UART7_RX_USING_DMA + uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE; uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; #endif #ifdef BSP_UART7_TX_USING_DMA diff --git a/bsp/hc32/ev_hc32f448_lqfp80/board/Kconfig b/bsp/hc32/ev_hc32f448_lqfp80/board/Kconfig index b8b97d7c755..6a543d53b8d 100644 --- a/bsp/hc32/ev_hc32f448_lqfp80/board/Kconfig +++ b/bsp/hc32/ev_hc32f448_lqfp80/board/Kconfig @@ -85,6 +85,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -112,6 +118,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -156,6 +168,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART5 @@ -183,6 +201,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART6 diff --git a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig index dee41e9f7aa..7a431c98b7d 100644 --- a/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig +++ b/bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig @@ -63,6 +63,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -90,6 +96,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -117,6 +129,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART4 @@ -144,6 +162,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 64 endif endif diff --git a/bsp/hc32/ev_hc32f472_lqfp100/board/Kconfig b/bsp/hc32/ev_hc32f472_lqfp100/board/Kconfig index 9fc9dfd3ea9..a9d4656da4e 100644 --- a/bsp/hc32/ev_hc32f472_lqfp100/board/Kconfig +++ b/bsp/hc32/ev_hc32f472_lqfp100/board/Kconfig @@ -85,6 +85,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -112,6 +118,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -156,6 +168,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART5 @@ -183,6 +201,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART6 diff --git a/bsp/hc32/ev_hc32f4a0_lqfp176/board/Kconfig b/bsp/hc32/ev_hc32f4a0_lqfp176/board/Kconfig index 8b066884551..afeee7e418c 100644 --- a/bsp/hc32/ev_hc32f4a0_lqfp176/board/Kconfig +++ b/bsp/hc32/ev_hc32f4a0_lqfp176/board/Kconfig @@ -141,6 +141,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -168,6 +174,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -246,6 +258,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART6_DMA_PING_BUFSIZE + int "Set UART6 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART7 @@ -273,6 +291,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART7_DMA_PING_BUFSIZE + int "Set UART7 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA + default 64 endif diff --git a/bsp/hc32/lckfb-hc32f4a0-lqfp100/board/Kconfig b/bsp/hc32/lckfb-hc32f4a0-lqfp100/board/Kconfig index 0ef934f24c7..d5e9a6bbaac 100644 --- a/bsp/hc32/lckfb-hc32f4a0-lqfp100/board/Kconfig +++ b/bsp/hc32/lckfb-hc32f4a0-lqfp100/board/Kconfig @@ -137,6 +137,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -164,6 +170,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -242,6 +254,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART6_DMA_PING_BUFSIZE + int "Set UART6 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART7 @@ -269,6 +287,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART7_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA + default 64 endif diff --git a/bsp/hc32/libraries/hc32_drivers/drv_usart_v2.c b/bsp/hc32/libraries/hc32_drivers/drv_usart_v2.c index eee7d309a19..243e312422b 100644 --- a/bsp/hc32/libraries/hc32_drivers/drv_usart_v2.c +++ b/bsp/hc32/libraries/hc32_drivers/drv_usart_v2.c @@ -242,7 +242,7 @@ static rt_err_t hc32_configure(struct rt_serial_device *serial, struct serial_co #endif #ifdef RT_SERIAL_USING_DMA - uart->dma_rx_remaining_cnt = (serial->config.rx_bufsz <= 1UL) ? serial->config.rx_bufsz : serial->config.rx_bufsz / 2UL; + uart->dma_rx_remaining_cnt = (serial->config.dma_ping_bufsz <= 1UL) ? serial->config.dma_ping_bufsz : serial->config.dma_ping_bufsz / 2UL; #endif /* Enable USART clock */ FCG_USART_CLK(uart->config->clock, ENABLE); @@ -501,22 +501,20 @@ static rt_ssize_t hc32_transmit(struct rt_serial_device *serial, static void hc32_uart_rx_irq_handler(struct hc32_uart *uart) { RT_ASSERT(RT_NULL != uart); - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *)uart->serial.serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)USART_ReadData(uart->config->Instance)); + struct rt_serial_device *serial = &uart->serial; + + char chr = USART_ReadData(uart->config->Instance); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(&uart->serial, RT_SERIAL_EVENT_RX_IND); } static void hc32_uart_tx_irq_handler(struct hc32_uart *uart) { RT_ASSERT(RT_NULL != uart); - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *)uart->serial.serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); + struct rt_serial_device *serial = &uart->serial; rt_uint8_t put_char = 0; - if (rt_ringbuffer_getchar(&(tx_fifo->rb), &put_char)) + if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK) { USART_WriteData(uart->config->Instance, put_char); } @@ -673,24 +671,25 @@ static void hc32_uart_rx_timeout(struct rt_serial_device *serial) static void hc32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) { - rt_uint32_t trans_count = (serial->config.rx_bufsz <= 1UL) ? serial->config.rx_bufsz : serial->config.rx_bufsz / 2UL; + rt_uint32_t trans_count = (serial->config.dma_ping_bufsz <= 1UL) ? serial->config.dma_ping_bufsz : serial->config.dma_ping_bufsz / 2UL; struct hc32_uart *uart; stc_dma_init_t dma_init; struct dma_config *uart_dma; RT_ASSERT(RT_NULL != serial); - RT_ASSERT(RT_NULL == ((serial->config.rx_bufsz) & ((RT_ALIGN_SIZE) - 1))); + RT_ASSERT(RT_NULL == ((serial->config.dma_ping_bufsz) & ((RT_ALIGN_SIZE) - 1))); uart = rt_container_of(serial, struct hc32_uart, serial); RT_ASSERT(RT_NULL != uart->config->Instance); if (RT_DEVICE_FLAG_DMA_RX == flag) { stc_dma_llp_init_t llp_init; - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); RT_ASSERT(RT_NULL != uart->config->rx_timeout->TMR0_Instance); RT_ASSERT(RT_NULL != uart->config->dma_rx->Instance); - RT_ASSERT(RT_NULL != rx_fifo); + RT_ASSERT(RT_NULL != ptr); #if defined (HC32F448) || defined (HC32F472) INTC_IntSrcCmd(uart->config->rx_int_src, DISABLE); @@ -707,7 +706,7 @@ static void hc32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) DMA_StructInit(&dma_init); dma_init.u32IntEn = DMA_INT_ENABLE; dma_init.u32SrcAddr = (uint32_t)(&uart->config->Instance->RDR); - dma_init.u32DestAddr = (uint32_t)rx_fifo->buffer; + dma_init.u32DestAddr = (uint32_t)ptr; dma_init.u32DataWidth = DMA_DATAWIDTH_8BIT; dma_init.u32BlockSize = 1UL; dma_init.u32TransCount = trans_count; @@ -723,14 +722,14 @@ static void hc32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) /* Configure LLP descriptor */ uart->config->llp_desc[0U].SARx = dma_init.u32SrcAddr; - uart->config->llp_desc[0U].DARx = dma_init.u32DestAddr + ((serial->config.rx_bufsz <= 1UL) ? 0UL : dma_init.u32TransCount); - uart->config->llp_desc[0U].DTCTLx = (((serial->config.rx_bufsz <= 1U) ? dma_init.u32TransCount : (serial->config.rx_bufsz - dma_init.u32TransCount)) << DMA_DTCTL_CNT_POS) | \ + uart->config->llp_desc[0U].DARx = dma_init.u32DestAddr + ((serial->config.dma_ping_bufsz <= 1UL) ? 0UL : dma_init.u32TransCount); + uart->config->llp_desc[0U].DTCTLx = (((serial->config.dma_ping_bufsz <= 1U) ? dma_init.u32TransCount : (serial->config.dma_ping_bufsz - dma_init.u32TransCount)) << DMA_DTCTL_CNT_POS) | \ (dma_init.u32BlockSize << DMA_DTCTL_BLKSIZE_POS); - uart->config->llp_desc[0U].LLPx = (serial->config.rx_bufsz <= 1U) ? (uint32_t)&uart->config->llp_desc[0U] : (uint32_t)&uart->config->llp_desc[1U]; + uart->config->llp_desc[0U].LLPx = (serial->config.dma_ping_bufsz <= 1U) ? (uint32_t)&uart->config->llp_desc[0U] : (uint32_t)&uart->config->llp_desc[1U]; uart->config->llp_desc[0U].CHCTLx = (dma_init.u32SrcAddrInc | dma_init.u32DestAddrInc | dma_init.u32DataWidth | \ llp_init.u32State | llp_init.u32Mode | dma_init.u32IntEn); - if (serial->config.rx_bufsz > 1UL) + if (serial->config.dma_ping_bufsz > 1UL) { uart->config->llp_desc[1U].SARx = dma_init.u32SrcAddr; uart->config->llp_desc[1U].DARx = dma_init.u32DestAddr; @@ -1705,6 +1704,7 @@ static void hc32_uart_get_info(void) uart_obj[UART1_INDEX].serial.config.rx_bufsz = BSP_UART1_RX_BUFSIZE; uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE; #ifdef BSP_UART1_RX_USING_DMA + uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE; uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG; static struct hc32_uart_rxto uart1_rx_timeout = UART1_RXTO_CONFIG; @@ -1728,6 +1728,7 @@ static void hc32_uart_get_info(void) uart_obj[UART2_INDEX].serial.config.rx_bufsz = BSP_UART2_RX_BUFSIZE; uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE; #ifdef BSP_UART2_RX_USING_DMA + uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE; uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG; static struct hc32_uart_rxto uart2_rx_timeout = UART2_RXTO_CONFIG; @@ -1752,6 +1753,7 @@ static void hc32_uart_get_info(void) uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE; #if defined (HC32F460) || defined (HC32F4A8) #ifdef BSP_UART3_RX_USING_DMA + uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE; uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart3_dma_rx = UART3_DMA_RX_CONFIG; static struct hc32_uart_rxto uart3_rx_timeout = UART3_RXTO_CONFIG; @@ -1775,6 +1777,7 @@ static void hc32_uart_get_info(void) uart_obj[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE; #if defined (HC32F460) || defined (HC32F448) || defined (HC32F472) #ifdef BSP_UART4_RX_USING_DMA + uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE; uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart4_dma_rx = UART4_DMA_RX_CONFIG; static struct hc32_uart_rxto uart4_rx_timeout = UART4_RXTO_CONFIG; @@ -1800,6 +1803,7 @@ static void hc32_uart_get_info(void) uart_obj[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE; #if defined (HC32F448) || defined (HC32F472) #ifdef BSP_UART5_RX_USING_DMA + uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE; uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart5_dma_rx = UART5_DMA_RX_CONFIG; static struct hc32_uart_rxto uart5_rx_timeout = UART5_RXTO_CONFIG; @@ -1825,6 +1829,7 @@ static void hc32_uart_get_info(void) uart_obj[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE; #if defined (HC32F4A0) #ifdef BSP_UART6_RX_USING_DMA + uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE; uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart6_dma_rx = UART6_DMA_RX_CONFIG; static struct hc32_uart_rxto uart6_rx_timeout = UART6_RXTO_CONFIG; @@ -1848,6 +1853,7 @@ static void hc32_uart_get_info(void) uart_obj[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE; #if defined (HC32F4A0) #ifdef BSP_UART7_RX_USING_DMA + uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE; uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart7_dma_rx = UART7_DMA_RX_CONFIG; static struct hc32_uart_rxto uart7_rx_timeout = UART7_RXTO_CONFIG; diff --git a/bsp/hpmicro/libraries/drivers/drv_uart_v2.c b/bsp/hpmicro/libraries/drivers/drv_uart_v2.c index 09db6189b9b..70a4203b5ed 100644 --- a/bsp/hpmicro/libraries/drivers/drv_uart_v2.c +++ b/bsp/hpmicro/libraries/drivers/drv_uart_v2.c @@ -644,8 +644,8 @@ static void hpm_uart_isr(struct rt_serial_device *serial) if (irq_id == uart_intr_id_rx_data_avail) { while (uart_check_status(uart->uart_base, uart_stat_data_ready)) { count++; - put_char = uart_read_byte(uart->uart_base); - rt_ringbuffer_putchar(&(rx_fifo->rb), put_char); + char chr = uart_read_byte(uart->uart_base); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); /*in order to ensure rx fifo there are remaining bytes*/ if (count > 12) { break; @@ -655,8 +655,8 @@ static void hpm_uart_isr(struct rt_serial_device *serial) if (irq_id == uart_intr_id_rx_timeout) { while ((uart_check_status(uart->uart_base, uart_stat_data_ready)) || (uart_check_status(uart->uart_base, uart_stat_overrun_error))) { - put_char= uart_read_byte(uart->uart_base); - rt_ringbuffer_putchar(&(rx_fifo->rb), put_char); + char chr = uart_read_byte(uart->uart_base); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); } rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } diff --git a/bsp/microchip/common/board/serial.c b/bsp/microchip/common/board/serial.c index 793d1198644..adc6c69ed1b 100644 --- a/bsp/microchip/common/board/serial.c +++ b/bsp/microchip/common/board/serial.c @@ -34,7 +34,7 @@ static void serial_rxcallback(const struct usart_async_descriptor *const io_desc do { ringbuffer_get((struct ringbuffer *const)&io_descr->rx, &data); - rt_ringbuffer_putchar(&(rx_fifo->rb), data); + rt_ringbuffer_putchar_force(&rx_fifo->rb, data); } while (0); // maybe not only one byte #endif diff --git a/bsp/n32/libraries/n32_drivers/drv_usart_v2.c b/bsp/n32/libraries/n32_drivers/drv_usart_v2.c index 7f70b2c7192..0129a9a0239 100644 --- a/bsp/n32/libraries/n32_drivers/drv_usart_v2.c +++ b/bsp/n32/libraries/n32_drivers/drv_usart_v2.c @@ -777,7 +777,7 @@ static rt_err_t n32_configure(struct rt_serial_device *serial, struct serial_con USART_Init(uart->handle.Instance, &uart->handle.Init); USART_Enable(uart->handle.Instance, ENABLE); #ifdef RT_SERIAL_USING_DMA - uart->dma_rx.remaining_cnt = serial->config.rx_bufsz; + uart->dma_rx.remaining_cnt = serial->config.dma_ping_bufsz; #endif return RT_EOK; @@ -964,7 +964,7 @@ static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag) if (counter <= uart->dma_rx.remaining_cnt) recv_len = uart->dma_rx.remaining_cnt - counter; else - recv_len = serial->config.rx_bufsz + uart->dma_rx.remaining_cnt - counter; + recv_len = serial->config.dma_ping_bufsz + uart->dma_rx.remaining_cnt - counter; break; case UART_RX_DMA_IT_HT_FLAG: @@ -974,7 +974,7 @@ static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag) case UART_RX_DMA_IT_TC_FLAG: if (counter >= uart->dma_rx.remaining_cnt) - recv_len = serial->config.rx_bufsz + uart->dma_rx.remaining_cnt - counter; + recv_len = serial->config.dma_ping_bufsz + uart->dma_rx.remaining_cnt - counter; default: break; @@ -1003,22 +1003,15 @@ static void uart_isr(struct rt_serial_device *serial) /* If the Read data register is not empty and the RXNE interrupt is enabled (RDR) */ if (USART_GetIntStatus(uart->handle.Instance, USART_INT_RXDNE) != RESET && USART_GetFlagStatus(uart->handle.Instance, USART_FLAG_RXDNE) != RESET) { - struct rt_serial_rx_fifo *rx_fifo; - - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)(uart->handle.Instance->DAT & (rt_uint16_t)0x01FF)); + char chr = uart->handle.Instance->DAT & (rt_uint16_t)0x01FF; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } /* If the Transmit data register is empty and the TXE interrupt enable is enabled (TDR)*/ else if (USART_GetIntStatus(uart->handle.Instance, USART_INT_TXDE) != RESET && USART_GetFlagStatus(uart->handle.Instance, USART_FLAG_TXDE) != RESET) { - struct rt_serial_tx_fifo *tx_fifo; - - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); rt_uint8_t put_char = 0; - if (rt_ringbuffer_getchar(&(tx_fifo->rb), &put_char)) + if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK) { USART_SendData(uart->handle.Instance, put_char); } @@ -1380,6 +1373,7 @@ static void n32_uart_get_config(void) uart_obj[UART1_INDEX].uart_dma_flag = 0; #ifdef BSP_UART1_RX_USING_DMA uart_obj[UART1_INDEX].handle.HDMA_Rx = &uart_obj[UART1_INDEX].dma_rx.handle; + uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE; uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART1_INDEX].dma_rx.handle.Parent = &uart_obj[UART1_INDEX].handle; uart_obj[UART1_INDEX].dma_rx.handle.Instance = DMA1_CH5; @@ -1404,6 +1398,7 @@ static void n32_uart_get_config(void) uart_obj[UART2_INDEX].uart_dma_flag = 0; #ifdef BSP_UART2_RX_USING_DMA uart_obj[UART2_INDEX].handle.HDMA_Rx = &uart_obj[UART2_INDEX].dma_rx.handle; + uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE; uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART2_INDEX].dma_rx.handle.Parent = &uart_obj[UART2_INDEX].handle; uart_obj[UART2_INDEX].dma_rx.handle.Instance = DMA1_CH6; @@ -1428,6 +1423,7 @@ static void n32_uart_get_config(void) uart_obj[UART3_INDEX].uart_dma_flag = 0; #ifdef BSP_UART3_RX_USING_DMA uart_obj[UART3_INDEX].handle.HDMA_Rx = &uart_obj[UART3_INDEX].dma_rx.handle; + uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE; uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART3_INDEX].dma_rx.handle.Parent = &uart_obj[UART3_INDEX].handle; uart_obj[UART3_INDEX].dma_rx.handle.Instance = DMA1_CH3; @@ -1452,6 +1448,7 @@ static void n32_uart_get_config(void) uart_obj[UART4_INDEX].uart_dma_flag = 0; #ifdef BSP_UART4_RX_USING_DMA uart_obj[UART4_INDEX].handle.HDMA_Rx = &uart_obj[UART4_INDEX].dma_rx.handle; + uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE; uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART4_INDEX].dma_rx.handle.Parent = &uart_obj[UART4_INDEX].handle; uart_obj[UART4_INDEX].dma_rx.handle.Instance = DMA2_CH3; @@ -1476,6 +1473,7 @@ static void n32_uart_get_config(void) uart_obj[UART5_INDEX].uart_dma_flag = 0; #ifdef BSP_UART5_RX_USING_DMA uart_obj[UART5_INDEX].handle.HDMA_Rx = &uart_obj[UART5_INDEX].dma_rx.handle; + uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE; uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART5_INDEX].dma_rx.handle.Parent = &uart_obj[UART5_INDEX].handle; uart_obj[UART5_INDEX].dma_rx.handle.Instance = DMA1_CH8; @@ -1500,6 +1498,7 @@ static void n32_uart_get_config(void) uart_obj[UART6_INDEX].uart_dma_flag = 0; #ifdef BSP_UART6_RX_USING_DMA uart_obj[UART6_INDEX].handle.HDMA_Rx = &uart_obj[UART6_INDEX].dma_rx.handle; + uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE; uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART6_INDEX].dma_rx.handle.Parent = &uart_obj[UART6_INDEX].handle; uart_obj[UART6_INDEX].dma_rx.handle.Instance = DMA2_CH1; @@ -1524,6 +1523,7 @@ static void n32_uart_get_config(void) uart_obj[UART7_INDEX].uart_dma_flag = 0; #ifdef BSP_UART7_RX_USING_DMA uart_obj[UART7_INDEX].handle.HDMA_Rx = &uart_obj[UART7_INDEX].dma_rx.handle; + uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE; uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; uart_obj[UART7_INDEX].dma_rx.handle.Parent = &uart_obj[UART7_INDEX].handle; uart_obj[UART7_INDEX].dma_rx.handle.Instance = DMA2_CH6; @@ -1544,7 +1544,6 @@ static void n32_uart_get_config(void) #ifdef RT_SERIAL_USING_DMA static void n32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) { - struct rt_serial_rx_fifo *rx_fifo; struct DMA_HandleTypeDef *DMA_Handle; struct n32_uart *uart; @@ -1555,7 +1554,6 @@ static void n32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag if (RT_DEVICE_FLAG_DMA_RX == flag) { DMA_Handle = &uart->dma_rx.handle; - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; } else /* RT_DEVICE_FLAG_DMA_TX == flag */ { @@ -1572,9 +1570,11 @@ static void n32_uart_dma_config(struct rt_serial_device *serial, rt_ubase_t flag DMA_Handle->Init.Mem2Mem = DMA_M2M_DISABLE; if (RT_DEVICE_FLAG_DMA_RX == flag) { + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); DMA_Handle->Init.Direction = DMA_DIR_PERIPH_SRC; - DMA_Handle->Init.MemAddr = (unsigned int)rx_fifo->buffer; - DMA_Handle->Init.BufSize = serial->config.rx_bufsz; + DMA_Handle->Init.MemAddr = (unsigned int)ptr; + DMA_Handle->Init.BufSize = serial->config.dma_ping_bufsz; DMA_Handle->Init.CircularMode = DMA_MODE_CIRCULAR; DMA_Handle->Init.Priority = DMA_PRIORITY_VERY_HIGH; } diff --git a/bsp/n32/n32g45xvl-stb/board/Kconfig b/bsp/n32/n32g45xvl-stb/board/Kconfig index 185679e2387..5df1f9fc3a8 100644 --- a/bsp/n32/n32g45xvl-stb/board/Kconfig +++ b/bsp/n32/n32g45xvl-stb/board/Kconfig @@ -54,6 +54,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_USART1 && RT_SERIAL_USING_DMA default n + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 32 + config BSP_UART1_RX_BUFSIZE int "Set rx buffer size" range 0 16384 @@ -102,6 +108,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_USART2 && RT_SERIAL_USING_DMA default n + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 32 + config BSP_UART2_RX_BUFSIZE int "Set rx buffer size" range 256 16384 @@ -146,6 +158,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_USART3 && RT_SERIAL_USING_DMA default n + config BSP_UART3_DMA_PING_BUFSIZE + int "Set UART3 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART3_RX_USING_DMA + default 32 + config BSP_UART3_RX_BUFSIZE int "Set rx buffer size" range 256 16384 @@ -194,6 +212,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA default n + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 32 + config BSP_UART4_RX_BUFSIZE int "Set rx buffer size" range 256 16384 @@ -242,6 +266,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART5 && RT_SERIAL_USING_DMA default n + config BSP_UART5_DMA_PING_BUFSIZE + int "Set UART5 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART5_RX_USING_DMA + default 32 + config BSP_UART5_RX_BUFSIZE int "Set rx buffer size" range 256 16384 @@ -286,6 +316,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA default n + config BSP_UART6_DMA_PING_BUFSIZE + int "Set UART6 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART6_RX_USING_DMA + default 32 + config BSP_UART6_RX_BUFSIZE int "Set rx buffer size" range 256 16384 @@ -330,6 +366,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART7 && RT_SERIAL_USING_DMA default n + config BSP_UART7_DMA_PING_BUFSIZE + int "Set UART7 RX DMA ping-pong buffer size" + range 16 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART7_RX_USING_DMA + default 32 + config BSP_UART7_RX_BUFSIZE int "Set rx buffer size" range 256 16384 diff --git a/bsp/qemu-vexpress-a9/drivers/Kconfig b/bsp/qemu-vexpress-a9/drivers/Kconfig index 2ccbaa0d84a..8a4610d488d 100644 --- a/bsp/qemu-vexpress-a9/drivers/Kconfig +++ b/bsp/qemu-vexpress-a9/drivers/Kconfig @@ -24,7 +24,7 @@ menu "Onboard Peripheral Drivers" int "Set UART0 RX buffer size" range 64 65535 depends on RT_USING_SERIAL_V2 - default 10240 + default 1024 config BSP_UART0_TX_BUFSIZE int "Set UART0 TX buffer size" @@ -41,7 +41,7 @@ menu "Onboard Peripheral Drivers" int "Set UART1 RX buffer size" range 64 65535 depends on RT_USING_SERIAL_V2 - default 10240 + default 1024 config BSP_UART1_TX_BUFSIZE int "Set UART1 TX buffer size" @@ -58,7 +58,7 @@ menu "Onboard Peripheral Drivers" int "Set UART2 RX buffer size" range 64 65535 depends on RT_USING_SERIAL_V2 - default 10240 + default 1024 config BSP_UART2_TX_BUFSIZE int "Set UART2 TX buffer size" @@ -75,7 +75,7 @@ menu "Onboard Peripheral Drivers" int "Set UART3 RX buffer size" range 64 65535 depends on RT_USING_SERIAL_V2 - default 10240 + default 1024 config BSP_UART3_TX_BUFSIZE int "Set UART3 TX buffer size" diff --git a/bsp/qemu-vexpress-a9/drivers/drv_uart_v2.c b/bsp/qemu-vexpress-a9/drivers/drv_uart_v2.c index b0e549a7f21..96b95f7630c 100644 --- a/bsp/qemu-vexpress-a9/drivers/drv_uart_v2.c +++ b/bsp/qemu-vexpress-a9/drivers/drv_uart_v2.c @@ -134,7 +134,7 @@ static void rt_hw_uart_isr(int irqno, void *param) RT_ASSERT(uart != RT_NULL); - if(!(UART_FR(uart->hw_base) & UARTFR_RXFE) && (UART_IMSC(uart->hw_base) & UARTIMSC_RXIM)) + if((UART_FR(uart->hw_base) & UARTFR_RXFF) && (UART_IMSC(uart->hw_base) & UARTIMSC_RXIM)) { struct rt_serial_rx_fifo *rx_fifo; @@ -143,10 +143,32 @@ static void rt_hw_uart_isr(int irqno, void *param) RT_ASSERT(rx_fifo != RT_NULL); - char rec_ch = UART_DR(uart->hw_base) & 0xff; + char rec_ch; + while (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) + { + rec_ch = UART_DR(uart->hw_base) & 0xff; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &rec_ch); + + } + rt_hw_serial_isr(serial,RT_SERIAL_EVENT_RX_IND); + + } + else if(UART_IMSC(uart->hw_base) & UARTIMSC_RTIM) + { + struct rt_serial_rx_fifo *rx_fifo; + + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + + RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_putchar(&(rx_fifo->rb),rec_ch); + char rec_ch; + + while (!(UART_FR(uart->hw_base) & UARTFR_RXFE)) + { + rec_ch = UART_DR(uart->hw_base) & 0xff; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &rec_ch); + } rt_hw_serial_isr(serial,RT_SERIAL_EVENT_RX_IND); } else if((UART_IMSC(uart->hw_base) & UARTIMSC_TXIM)) @@ -188,6 +210,7 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg { /* disable rx irq */ UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM; + UART_IMSC(uart->hw_base) &= ~UARTIMSC_RTIM; } else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) { @@ -201,6 +224,7 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg { /* enable rx irq */ UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM; + UART_IMSC(uart->hw_base) |= UARTIMSC_RTIM; rt_hw_interrupt_umask(uart->irqno); } else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX) @@ -256,7 +280,6 @@ static rt_ssize_t uart_transmit(struct rt_serial_device *serial, RT_ASSERT(serial != RT_NULL); RT_ASSERT(buf != RT_NULL); RT_ASSERT(size); - uint32_t fifo_size = 0, tx_size = 0; struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data; struct rt_serial_tx_fifo *tx_fifo; tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; @@ -342,7 +365,12 @@ int rt_hw_uart_init(void) rt_hw_interrupt_install(_uart_device[i].irqno, rt_hw_uart_isr, _uart_device[i].serial, _uart_device[i].device_name); /* enable Rx and Tx of UART */ UART_CR(_uart_device[i].hw_base) = (1 << 0) | (1 << 8) | (1 << 9); + UART_LCR_H(_uart_device[i].hw_base) =(1 << 4); + + UART_IFLS(_uart_device[i].hw_base) =0; + UART_IFLS(_uart_device[i].hw_base) =(1 << 3); + } return err; diff --git a/bsp/renesas/libraries/HAL_Drivers/drv_usart_v2.c b/bsp/renesas/libraries/HAL_Drivers/drv_usart_v2.c index a9e3e039659..8abbd917f84 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drv_usart_v2.c +++ b/bsp/renesas/libraries/HAL_Drivers/drv_usart_v2.c @@ -286,11 +286,8 @@ void user_uart0_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -309,12 +306,8 @@ void user_uart1_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -332,12 +325,8 @@ void user_uart2_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -355,12 +344,8 @@ void user_uart3_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -378,12 +363,8 @@ void user_uart4_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -401,12 +382,8 @@ void user_uart5_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -424,12 +401,8 @@ void user_uart6_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -447,12 +420,8 @@ void user_uart7_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -470,12 +439,8 @@ void user_uart8_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } @@ -493,12 +458,8 @@ void user_uart9_callback(uart_callback_args_t *p_args) if (UART_EVENT_RX_CHAR == p_args->event) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data); - + char chr = p_args->data; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c index 8bf94f00e72..085189658c5 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.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 * @@ -13,7 +13,7 @@ #ifdef RT_USING_SERIAL_V2 -//#define DRV_DEBUG +// #define DRV_DEBUG #define DBG_TAG "drv.usart" #ifdef DRV_DEBUG #define DBG_LVL DBG_LOG @@ -189,7 +189,7 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c } #ifdef RT_SERIAL_USING_DMA - uart->dma_rx.remaining_cnt = serial->config.rx_bufsz; + uart->dma_rx.remaining_cnt = serial->config.dma_ping_bufsz; #endif if (HAL_UART_Init(&uart->handle) != HAL_OK) @@ -255,6 +255,9 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC); HAL_NVIC_DisableIRQ(uart->config->dma_tx->dma_irq); + + HAL_DMA_Abort(&(uart->dma_tx.handle)); + if (HAL_DMA_DeInit(&(uart->dma_tx.handle)) != HAL_OK) { RT_ASSERT(0); @@ -414,12 +417,13 @@ static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag) if (counter <= uart->dma_rx.remaining_cnt) recv_len = uart->dma_rx.remaining_cnt - counter; else - recv_len = serial->config.rx_bufsz + uart->dma_rx.remaining_cnt - counter; + recv_len = serial->config.dma_ping_bufsz + uart->dma_rx.remaining_cnt - counter; if (recv_len) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - SCB_InvalidateDCache_by_Addr((uint32_t *)rx_fifo->buffer, serial->config.rx_bufsz); + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); + SCB_InvalidateDCache_by_Addr((uint32_t *)ptr, serial->config.dma_ping_bufsz); #endif uart->dma_rx.remaining_cnt = counter; rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); @@ -442,24 +446,16 @@ static void uart_isr(struct rt_serial_device *serial) if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET)) { - struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_ringbuffer_putchar(&(rx_fifo->rb), UART_GET_RDR(&uart->handle, stm32_uart_get_mask(uart->handle.Init.WordLength, uart->handle.Init.Parity))); - + char chr = UART_GET_RDR(&uart->handle, stm32_uart_get_mask(uart->handle.Init.WordLength, uart->handle.Init.Parity)); + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } /* If the Transmit data register is empty and the TXE interrupt enable is enabled (TDR) */ else if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TXE)) != RESET) { - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - rt_uint8_t put_char = 0; - if (rt_ringbuffer_getchar(&(tx_fifo->rb), &put_char)) + if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK) { UART_SET_TDR(&uart->handle, put_char); } @@ -931,6 +927,7 @@ static void stm32_uart_get_config(void) uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE; #ifdef BSP_UART1_RX_USING_DMA + uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE; uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG; uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx; @@ -951,6 +948,7 @@ static void stm32_uart_get_config(void) uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE; #ifdef BSP_UART2_RX_USING_DMA + uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE; uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG; uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx; @@ -971,6 +969,7 @@ static void stm32_uart_get_config(void) uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE; #ifdef BSP_UART3_RX_USING_DMA + uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE; uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart3_dma_rx = UART3_DMA_RX_CONFIG; uart_config[UART3_INDEX].dma_rx = &uart3_dma_rx; @@ -991,6 +990,7 @@ static void stm32_uart_get_config(void) uart_obj[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE; #ifdef BSP_UART4_RX_USING_DMA + uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE; uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart4_dma_rx = UART4_DMA_RX_CONFIG; uart_config[UART4_INDEX].dma_rx = &uart4_dma_rx; @@ -1011,6 +1011,7 @@ static void stm32_uart_get_config(void) uart_obj[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE; #ifdef BSP_UART5_RX_USING_DMA + uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE; uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart5_dma_rx = UART5_DMA_RX_CONFIG; uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx; @@ -1031,6 +1032,7 @@ static void stm32_uart_get_config(void) uart_obj[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE; #ifdef BSP_UART6_RX_USING_DMA + uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE; uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart6_dma_rx = UART6_DMA_RX_CONFIG; uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx; @@ -1051,6 +1053,7 @@ static void stm32_uart_get_config(void) uart_obj[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE; #ifdef BSP_UART7_RX_USING_DMA + uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE; uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config uart7_dma_rx = UART7_DMA_RX_CONFIG; uart_config[UART7_INDEX].dma_rx = &uart7_dma_rx; @@ -1077,6 +1080,7 @@ static void stm32_uart_get_config(void) #endif #ifdef BSP_UART8_TX_USING_DMA + uart_obj[UART8_INDEX].serial.config.dma_ping_bufsz = BSP_UART8_DMA_PING_BUFSIZE; uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX; static struct dma_config uart8_dma_tx = UART8_DMA_TX_CONFIG; uart_config[UART8_INDEX].dma_tx = &uart8_dma_tx; @@ -1091,6 +1095,7 @@ static void stm32_uart_get_config(void) uart_obj[LPUART1_INDEX].serial.config.tx_bufsz = BSP_LPUART1_TX_BUFSIZE; #ifdef BSP_LPUART1_RX_USING_DMA + uart_obj[LPUART1_INDEX].serial.config.dma_ping_bufsz = BSP_LPUART1_DMA_PING_BUFSIZE; uart_obj[LPUART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX; static struct dma_config lpuart1_dma_rx = LPUART1_DMA_CONFIG; uart_config[LPUART1_INDEX].dma_rx = &lpuart1_dma_rx; @@ -1101,7 +1106,6 @@ static void stm32_uart_get_config(void) #ifdef RT_SERIAL_USING_DMA static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) { - struct rt_serial_rx_fifo *rx_fifo; DMA_HandleTypeDef *DMA_Handle; struct dma_config *dma_config; struct stm32_uart *uart; @@ -1202,10 +1206,11 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) /* enable interrupt */ if (flag == RT_DEVICE_FLAG_DMA_RX) { - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); + rt_uint8_t *ptr = NULL; + rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr); + /* Start DMA transfer */ - if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.rx_bufsz) != HAL_OK) + if (HAL_UART_Receive_DMA(&(uart->handle), ptr, serial->config.dma_ping_bufsz) != HAL_OK) { /* Transfer error in reception process */ RT_ASSERT(0); diff --git a/bsp/stm32/stm32g071-st-nucleo/board/Kconfig b/bsp/stm32/stm32g071-st-nucleo/board/Kconfig index 9dca47975f5..2f18269e648 100644 --- a/bsp/stm32/stm32g071-st-nucleo/board/Kconfig +++ b/bsp/stm32/stm32g071-st-nucleo/board/Kconfig @@ -47,6 +47,12 @@ menu "On-chip Peripheral Drivers" depends on RT_USING_SERIAL_V2 default 256 + config BSP_LPUART1_DMA_PING_BUFSIZE + int "Set LPUART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_LPUART1_RX_USING_DMA + default 64 + config BSP_USING_UART1 bool "Enable UART1" default n @@ -73,6 +79,12 @@ menu "On-chip Peripheral Drivers" depends on RT_USING_SERIAL_V2 default 256 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 + config BSP_USING_UART2 bool "Enable UART2" default n @@ -98,6 +110,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif menuconfig BSP_USING_TIM diff --git a/bsp/stm32/stm32h750-artpi/board/Kconfig b/bsp/stm32/stm32h750-artpi/board/Kconfig index 89a24ecc8c0..54f1c97c05a 100644 --- a/bsp/stm32/stm32h750-artpi/board/Kconfig +++ b/bsp/stm32/stm32h750-artpi/board/Kconfig @@ -177,6 +177,12 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 + endif menuconfig BSP_USING_UART3 diff --git a/bsp/stm32/stm32h7s7-st-disco/board/Kconfig b/bsp/stm32/stm32h7s7-st-disco/board/Kconfig index f93f06baff1..43ee16e9560 100644 --- a/bsp/stm32/stm32h7s7-st-disco/board/Kconfig +++ b/bsp/stm32/stm32h7s7-st-disco/board/Kconfig @@ -73,6 +73,11 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_UART1 default 0 + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART3 @@ -117,6 +122,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on BSP_USING_UART4 default 0 + + config BSP_UART4_DMA_PING_BUFSIZE + int "Set UART4 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART4_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART6 diff --git a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig index e809128a4eb..6e1e98c75d5 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig +++ b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig @@ -317,6 +317,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 0 + + config BSP_UART1_DMA_PING_BUFSIZE + int "Set UART1 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA + default 64 endif menuconfig BSP_USING_UART2 @@ -344,6 +350,12 @@ menu "On-chip Peripheral Drivers" range 0 65535 depends on RT_USING_SERIAL_V2 default 256 + + config BSP_UART2_DMA_PING_BUFSIZE + int "Set UART2 RX DMA ping-pong buffer size" + range 32 65535 + depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA + default 64 endif endif diff --git a/components/drivers/include/drivers/dev_serial_v2.h b/components/drivers/include/drivers/dev_serial_v2.h index ef163dff0cd..d1b116ab1c9 100644 --- a/components/drivers/include/drivers/dev_serial_v2.h +++ b/components/drivers/include/drivers/dev_serial_v2.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 * @@ -12,8 +12,7 @@ #define __DEV_SERIAL_V2_H__ #include - - +#include /** * @addtogroup group_Drivers RTTHREAD Driver * @defgroup group_Serial_v2 Serial v2 @@ -169,6 +168,9 @@ #define NRZ_NORMAL 0 /* Non Return to Zero : normal mode */ #define NRZ_INVERTED 1 /* Non Return to Zero : inverted mode */ +/** + * device flag + */ #define RT_DEVICE_FLAG_RX_BLOCKING 0x1000 #define RT_DEVICE_FLAG_RX_NON_BLOCKING 0x2000 @@ -180,21 +182,42 @@ #define RT_SERIAL_TX_BLOCKING RT_DEVICE_FLAG_TX_BLOCKING #define RT_SERIAL_TX_NON_BLOCKING RT_DEVICE_FLAG_TX_NON_BLOCKING +/** + * hw device control commands + */ #define RT_DEVICE_CHECK_OPTMODE 0x20 +/** + * hw serial control commands + */ +#define RT_HW_SERIAL_CTRL_GETC 0x01 /* Tx irq get char */ +#define RT_HW_SERIAL_CTRL_PUTC 0x02 /* Rx irq put char */ +#define RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF 0x03 /* Get DMA ping-pong buffer */ + +/** + * hw isr event + */ #define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */ #define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */ #define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */ #define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */ -#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ + +/** + * device commands + * 0x40 - special device control commands + */ +#define RT_SERIAL_CTRL_SET_RX_TIMEOUT 0x41 /* set Rx timeout. Call before rt_device_read. not supported in poll mode */ +#define RT_SERIAL_CTRL_SET_TX_TIMEOUT 0x42 /* set Tx timeout. Call before rt_device_write. not supported in poll mode */ +#define RT_SERIAL_CTRL_GET_RX_TIMEOUT 0x43 /* get Rx timeout. not supported in poll mode */ +#define RT_SERIAL_CTRL_GET_TX_TIMEOUT 0x44 /* get Tx timeout. not supported in poll mode */ +#define RT_SERIAL_CTRL_RX_FLUSH 0x45 /* clear rx buffer. Discard all data */ +#define RT_SERIAL_CTRL_TX_FLUSH 0x46 /* clear tx buffer. Blocking and wait for the send buffer data to be sent. not supported in poll mode */ +#define RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT 0x47 /* get unread bytes count. not supported in poll mode */ #define RT_SERIAL_ERR_OVERRUN 0x01 #define RT_SERIAL_ERR_FRAMING 0x02 #define RT_SERIAL_ERR_PARITY 0x03 -#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048 -#define RT_SERIAL_TX_DATAQUEUE_LWM 30 - #define RT_SERIAL_RX_MINBUFSZ 64 #define RT_SERIAL_TX_MINBUFSZ 64 @@ -216,7 +239,8 @@ RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \ RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \ RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \ - 0 \ + 0, /* reserved */ \ + 0, /* dma_ping_bufsz */ \ } /** @@ -239,6 +263,10 @@ struct serial_configure rt_uint32_t tx_bufsz :16; rt_uint32_t flowcontrol :1; rt_uint32_t reserved :5; + +#ifdef RT_SERIAL_USING_DMA + rt_uint32_t dma_ping_bufsz :16; +#endif }; /** @@ -248,12 +276,15 @@ struct rt_serial_rx_fifo { struct rt_ringbuffer rb; +#ifdef RT_SERIAL_USING_DMA + struct rt_ringbuffer dma_ping_rb; +#endif + struct rt_completion rx_cpt; - rt_uint16_t rx_cpt_index; + rt_size_t rx_cpt_index; - /* software fifo */ - rt_uint8_t buffer[]; + rt_atomic_t rx_timeout; }; /** @@ -264,14 +295,13 @@ struct rt_serial_tx_fifo { struct rt_ringbuffer rb; - rt_size_t put_size; + struct rt_completion tx_cpt; - rt_bool_t activated; + rt_size_t put_size; - struct rt_completion tx_cpt; + rt_atomic_t tx_timeout; - /* software fifo */ - rt_uint8_t buffer[]; + rt_atomic_t activated; }; /** @@ -288,6 +318,8 @@ struct rt_serial_device void *serial_rx; void *serial_tx; + struct rt_spinlock spinlock; + struct rt_device_notify rx_notify; }; @@ -321,6 +353,7 @@ struct rt_uart_ops */ void rt_hw_serial_isr(struct rt_serial_device *serial, int event); +rt_err_t rt_hw_serial_control_isr(struct rt_serial_device *serial, int cmd, void *args); /** * @brief Register a serial device to device list diff --git a/components/drivers/serial/Kconfig b/components/drivers/serial/Kconfig index 349aaeab2f2..cd6cf3f3592 100644 --- a/components/drivers/serial/Kconfig +++ b/components/drivers/serial/Kconfig @@ -13,6 +13,17 @@ menuconfig RT_USING_SERIAL config RT_USING_SERIAL_V2 bool "RT_USING_SERIAL_V2" endchoice + + choice + prompt "Choice Serial version" + depends on RT_USING_SERIAL_V2 + default RT_SERIAL_BUF_STRATEGY_OVERWRITE + config RT_SERIAL_BUF_STRATEGY_DROP + bool "drop new incoming data when the buffer is full" + config RT_SERIAL_BUF_STRATEGY_OVERWRITE + bool "overwrite old data when the buffer is full" + endchoice + config RT_SERIAL_USING_DMA bool "Enable serial DMA mode" default y diff --git a/components/drivers/serial/dev_serial_v2.c b/components/drivers/serial/dev_serial_v2.c index 18f9c8970e6..bf51d3fb4ff 100644 --- a/components/drivers/serial/dev_serial_v2.c +++ b/components/drivers/serial/dev_serial_v2.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 * @@ -12,10 +12,22 @@ #include #include -#define DBG_TAG "Serial" -#define DBG_LVL DBG_INFO +#define DBG_TAG "Serial" +#define DBG_LVL DBG_INFO #include +#ifdef RT_SERIAL_BUF_STRATEGY_DROP +#define RT_SERIAL_FIFO_LOCK(spinlock) ((rt_base_t)0) +#define RT_SERIAL_FIFO_UNLOCK(spinlock, level) \ + do { \ + RT_UNUSED(spinlock); \ + RT_UNUSED(level); \ + } while (0) +#else +#define RT_SERIAL_FIFO_LOCK(spinlock) rt_spin_lock_irqsave(spinlock) +#define RT_SERIAL_FIFO_UNLOCK(spinlock, level) rt_spin_unlock_irqrestore(spinlock, level) +#endif /* RT_SERIAL_BUF_STRATEGY_DROP */ + #ifdef RT_USING_POSIX_STDIO #include #include @@ -39,7 +51,7 @@ RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind); static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) { - rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); + rt_wqueue_wakeup(&dev->wait_queue, (void *)POLLIN); RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size)); @@ -49,7 +61,7 @@ static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) /* fops for serial */ static int serial_fops_open(struct dfs_file *fd) { - rt_err_t ret = 0; + rt_err_t ret = 0; rt_uint16_t flags = 0; rt_device_t device; @@ -77,7 +89,7 @@ static int serial_fops_open(struct dfs_file *fd) if ((fd->flags & O_ACCMODE) != O_WRONLY) rt_device_set_rx_indicate(device, serial_fops_rx_ind); - ret = rt_device_open(device, flags); + ret = rt_device_open(device, flags | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING); if (ret == RT_EOK) return 0; return ret; @@ -98,8 +110,8 @@ static int serial_fops_close(struct dfs_file *fd) static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args) { rt_device_t device; - int flags = (int)(rt_base_t)args; - int mask = O_NONBLOCK | O_APPEND; + int flags = (int)(rt_base_t)args; + int mask = O_NONBLOCK | O_APPEND; device = (rt_device_t)fd->vnode->data; switch (cmd) @@ -109,7 +121,7 @@ static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args) case FIONWRITE: break; case F_SETFL: - flags &= mask; + flags &= mask; fd->flags &= ~mask; fd->flags |= flags; break; @@ -124,25 +136,35 @@ static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count, of static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count) #endif { - int size = 0; + ssize_t size = 0; rt_device_t device; + rt_int32_t rx_timout; + + if (count == 0) return 0; + RT_ASSERT(fd != RT_NULL && buf != RT_NULL); device = (rt_device_t)fd->vnode->data; + RT_ASSERT(device != RT_NULL); - do + /* nonblock mode */ + if (fd->flags & O_NONBLOCK) { - size = rt_device_read(device, -1, buf, count); + rx_timout = RT_WAITING_NO; + rt_device_control(device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timout); + size = rt_device_read(device, -1, buf, count); if (size <= 0) { - if (fd->flags & O_NONBLOCK) - { - size = -EAGAIN; - break; - } - - rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER); + size = -1; + rt_set_errno(EAGAIN); } - }while (size <= 0); + } + else + { + rx_timout = RT_WAITING_FOREVER; + rt_device_control(device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timout); + size = rt_device_read(device, -1, buf, count); + } + return size; } @@ -153,17 +175,53 @@ static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t co static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count) #endif { + ssize_t size = 0; rt_device_t device; + rt_int32_t tx_timeout; + + device = (rt_device_t)fd->vnode->data; + + if (fd->flags & O_NONBLOCK) + { + tx_timeout = RT_WAITING_NO; + rt_device_control(device, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout); + size = rt_device_write(device, -1, buf, count); + if (size <= 0) + { + size = -1; + rt_set_errno(EAGAIN); + } + } + else + { + tx_timeout = RT_WAITING_FOREVER; + rt_device_control(device, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout); + size = rt_device_write(device, -1, buf, count); + } + + return size; +} + +static int serial_fops_flush(struct dfs_file *fd) +{ + rt_device_t device; + struct rt_serial_device *serial; device = (rt_device_t)fd->vnode->data; - return rt_device_write(device, -1, buf, count); + RT_ASSERT(device != RT_NULL); + + serial = (struct rt_serial_device *)device; + rt_device_control(device, RT_SERIAL_CTRL_TX_FLUSH, (void *)RT_NULL); + rt_device_control(device, RT_SERIAL_CTRL_RX_FLUSH, (void *)RT_NULL); + + return 0; } static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req) { - int mask = 0; - int flags = 0; - rt_device_t device; + int mask = 0; + int flags = 0; + rt_device_t device; struct rt_serial_device *serial; device = (rt_device_t)fd->vnode->data; @@ -175,43 +233,41 @@ static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req) flags = fd->flags & O_ACCMODE; if (flags == O_RDONLY || flags == O_RDWR) { - rt_base_t level; - struct rt_serial_rx_fifo* rx_fifo; - - rt_poll_add(&(device->wait_queue), req); + rt_base_t level; + struct rt_serial_rx_fifo *rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; + rt_poll_add(&device->wait_queue, req); - level = rt_hw_interrupt_disable(); + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); if (rt_ringbuffer_data_len(&rx_fifo->rb)) mask |= POLLIN; - rt_hw_interrupt_enable(level); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); } - // mask|=POLLOUT; - return mask; + /* mask|=POLLOUT; */ + return mask; } const static struct dfs_file_ops _serial_fops = -{ - .open = serial_fops_open, - .close = serial_fops_close, - .ioctl = serial_fops_ioctl, - .read = serial_fops_read, - .write = serial_fops_write, - .poll = serial_fops_poll, + { + .open = serial_fops_open, + .close = serial_fops_close, + .ioctl = serial_fops_ioctl, + .read = serial_fops_read, + .write = serial_fops_write, + .flush = serial_fops_flush, + .poll = serial_fops_poll, }; #endif /* RT_USING_POSIX_STDIO */ -static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb, - rt_uint8_t **ptr) +static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb, + rt_uint8_t **ptr) { rt_size_t size; RT_ASSERT(rb != RT_NULL); - *ptr = RT_NULL; - /* whether has enough data */ size = rt_ringbuffer_data_len(rb); @@ -221,7 +277,7 @@ static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb, *ptr = &rb->buffer_ptr[rb->read_index]; - if(rb->buffer_size - rb->read_index > size) + if (rb->buffer_size - rb->read_index > size) { return size; } @@ -229,8 +285,9 @@ static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb, return rb->buffer_size - rb->read_index; } -static rt_ssize_t rt_serial_update_read_index(struct rt_ringbuffer *rb, - rt_uint16_t read_index) +#ifdef RT_SERIAL_USING_DMA +static void rt_serial_update_read_index(struct rt_ringbuffer *rb, + rt_uint16_t length) { rt_size_t size; @@ -241,60 +298,98 @@ static rt_ssize_t rt_serial_update_read_index(struct rt_ringbuffer *rb, /* no data */ if (size == 0) - return 0; + return; /* less data */ - if(size < read_index) - read_index = size; + if (size < length) + length = size; - if(rb->buffer_size - rb->read_index > read_index) + if (rb->buffer_size - rb->read_index > length) { - rb->read_index += read_index; - return read_index; + rb->read_index += length; + return; } - read_index = rb->buffer_size - rb->read_index; - /* we are going into the other side of the mirror */ rb->read_mirror = ~rb->read_mirror; - rb->read_index = 0; + rb->read_index = length - (rb->buffer_size - rb->read_index); - return read_index; + return; } -static rt_ssize_t rt_serial_update_write_index(struct rt_ringbuffer *rb, - rt_uint16_t write_size) +static void rt_serial_update_write_index(struct rt_ringbuffer *rb, + rt_uint16_t length) { - rt_uint16_t size; +#ifdef RT_SERIAL_BUF_STRATEGY_DROP + rt_uint16_t space_length; + + RT_ASSERT(rb != RT_NULL); + + /* whether has enough space */ + space_length = rt_ringbuffer_space_len(rb); + + /* no space */ + if (space_length == 0) + return; + + /* drop some data */ + if (space_length < length) + length = space_length; + + if (rb->buffer_size - rb->write_index > length) + { + /* this should not cause overflow because there is enough space for + * length of data in current mirror */ + rb->write_index += length; + return; + } + + /* we are going into the other side of the mirror */ + rb->write_mirror = ~rb->write_mirror; + rb->write_index = length - (rb->buffer_size - rb->write_index); + return; + +#else + rt_uint16_t space_length; RT_ASSERT(rb != RT_NULL); /* whether has enough space */ - size = rt_ringbuffer_space_len(rb); + space_length = rt_ringbuffer_space_len(rb); - /* no space, drop some data */ - if (size < write_size) + if (length > rb->buffer_size) { - write_size = size; + length = rb->buffer_size; #if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG) LOG_W("The serial buffer (len %d) is overflow.", rb->buffer_size); #endif } - if (rb->buffer_size - rb->write_index > write_size) + if (rb->buffer_size - rb->write_index > length) { /* this should not cause overflow because there is enough space for * length of data in current mirror */ - rb->write_index += write_size; - return write_size; + rb->write_index += length; + + if (length > space_length) + rb->read_index = rb->write_index; + + return; } /* we are going into the other side of the mirror */ rb->write_mirror = ~rb->write_mirror; - rb->write_index = write_size - (rb->buffer_size - rb->write_index); + rb->write_index = length - (rb->buffer_size - rb->write_index); - return write_size; + if (length > space_length) + { + if (rb->write_index <= rb->read_index) + rb->read_mirror = ~rb->read_mirror; + rb->read_index = rb->write_index; + } + return; +#endif /* RT_SERIAL_BUF_STRATEGY_DROP */ } - +#endif /* RT_SERIAL_USING_DMA */ /** * @brief Serial polling receive data routine, This function will receive data @@ -305,32 +400,32 @@ static rt_ssize_t rt_serial_update_write_index(struct rt_ringbuffer *rb, * @param size Receive data buffer length. * @return Return the final length of data received. */ -rt_ssize_t _serial_poll_rx(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) +rt_ssize_t _serial_poll_rx(struct rt_device *dev, + rt_off_t pos, + void *buffer, + rt_size_t size) { struct rt_serial_device *serial; - rt_size_t getc_size; - int getc_element; /* Gets one byte of data received */ - rt_uint8_t *getc_buffer; /* Pointer to the receive data buffer */ + rt_size_t getc_size; + int getc_element; /* Gets one byte of data received */ + rt_uint8_t *getc_buffer; /* Pointer to the receive data buffer */ - RT_ASSERT(dev != RT_NULL); + if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT(serial != RT_NULL); + serial = (struct rt_serial_device *)dev; getc_buffer = (rt_uint8_t *)buffer; - getc_size = size; + getc_size = size; - while(size) + while (size) { getc_element = serial->ops->getc(serial); if (getc_element == -1) break; *getc_buffer = getc_element; - ++ getc_buffer; - -- size; + ++getc_buffer; + --size; if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM) { @@ -340,7 +435,7 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev, } } - return getc_size - size; + return getc_size - size; } /** @@ -350,23 +445,23 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev, * @param pos Empty parameter. * @param buffer Transmit data buffer. * @param size Transmit data buffer length. - * @return Return the final length of data received. + * @return Return the final length of data transmit. */ -rt_ssize_t _serial_poll_tx(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) +rt_ssize_t _serial_poll_tx(struct rt_device *dev, + rt_off_t pos, + const void *buffer, + rt_size_t size) { struct rt_serial_device *serial; - rt_size_t putc_size; - rt_uint8_t *putc_buffer; /* Pointer to the transmit data buffer */ - RT_ASSERT(dev != RT_NULL); + rt_size_t putc_size; + rt_uint8_t *putc_buffer; /* Pointer to the transmit data buffer */ - serial = (struct rt_serial_device *)dev; - RT_ASSERT(serial != RT_NULL); + if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); + serial = (struct rt_serial_device *)dev; putc_buffer = (rt_uint8_t *)buffer; - putc_size = size; + putc_size = size; while (size) { @@ -379,73 +474,109 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev, } serial->ops->putc(serial, *putc_buffer); - ++ putc_buffer; - -- size; + ++putc_buffer; + --size; } - return putc_size - size; + return putc_size - size; } /** * @brief Serial receive data routines, This function will receive * data by using fifo + * + * @note In blocking mode, the function will wait until the specified amount of data is received or until a timeout occurs. + * In non-blocking mode, the function will immediately attempt to retrieve as much data as possible from the ring buffer and return. + * * @param dev The pointer of device driver structure * @param pos Empty parameter. * @param buffer Receive data buffer. * @param size Receive data buffer length. - * @return Return the final length of data received. + * @return Returns the actual length of data received. If a timeout occurs in blocking mode, it returns -RT_ETIMEOUT. */ -static rt_ssize_t _serial_fifo_rx(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) +static rt_ssize_t _serial_fifo_rx(struct rt_device *dev, + rt_off_t pos, + void *buffer, + rt_size_t size) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_rx_fifo *rx_fifo; - rt_base_t level; - rt_size_t recv_len; /* The length of data from the ringbuffer */ + rt_base_t level; + rt_size_t recv_size = 0; - RT_ASSERT(dev != RT_NULL); if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); - serial = (struct rt_serial_device *)dev; - - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; + serial = (struct rt_serial_device *)dev; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; if (dev->open_flag & RT_SERIAL_RX_BLOCKING) { - if (size > serial->config.rx_bufsz) + rt_size_t data_len = 0; + rt_size_t rx_bufsz_third = serial->config.rx_bufsz / 2; + rt_int32_t base_rx_timeout = rt_atomic_load(&rx_fifo->rx_timeout); + rt_int32_t rx_timeout = base_rx_timeout; + rt_tick_t now_tick = 0; + rt_tick_t begin_tick = rt_tick_get(); + + while (1) { - LOG_W("(%s) serial device received data:[%d] larger than " - "rx_bufsz:[%d], please increase the BSP_UARTx_RX_BUFSIZE option", - dev->parent.name, size, serial->config.rx_bufsz); + if (rx_timeout != RT_WAITING_NO) + { + level = rt_spin_lock_irqsave(&serial->spinlock); + data_len = rt_ringbuffer_data_len(&rx_fifo->rb); + if (data_len < size - recv_size) + { + if (size - (recv_size + data_len) >= rx_bufsz_third) + { + rx_fifo->rx_cpt_index = rx_bufsz_third; + } + else + { + rx_fifo->rx_cpt_index = size - (recv_size + data_len); + } + rt_completion_wait(&rx_fifo->rx_cpt, 0); + } + rt_spin_unlock_irqrestore(&serial->spinlock, level); + } - return 0; - } - /* Get the length of the data from the ringbuffer */ - recv_len = rt_ringbuffer_data_len(&(rx_fifo->rb)); + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); + recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); + if (recv_size == size || rx_timeout == RT_WAITING_NO) + { + break; + } - if (recv_len < size) - { - /* When recv_len is less than size, rx_cpt_index is updated to the size - * and rt_current_thread is suspend until rx_cpt_index is equal to 0 */ - rx_fifo->rx_cpt_index = size; - rt_completion_wait(&(rx_fifo->rx_cpt), RT_WAITING_FOREVER); + + rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout); + if (rx_timeout != RT_WAITING_FOREVER) + { + now_tick = rt_tick_get(); + if (now_tick - begin_tick >= base_rx_timeout) + { + return -RT_ETIMEOUT; + } + else + { + if (now_tick > begin_tick) + rx_timeout = base_rx_timeout - (now_tick - begin_tick); + else + rx_timeout = begin_tick + base_rx_timeout - now_tick + 1; + } + } } } + else if (dev->open_flag & RT_SERIAL_RX_NON_BLOCKING) + { + /* When open_flag is RT_SERIAL_RX_NON_BLOCKING, + * the data is retrieved directly from the ringbuffer and returned */ + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); + recv_size = rt_ringbuffer_get(&rx_fifo->rb, buffer, size); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); + } - /* This part of the code is open_flag as RT_SERIAL_RX_NON_BLOCKING */ - - level = rt_hw_interrupt_disable(); - /* When open_flag is RT_SERIAL_RX_NON_BLOCKING, - * the data is retrieved directly from the ringbuffer and returned */ - recv_len = rt_ringbuffer_get(&(rx_fifo->rb), buffer, size); - - rt_hw_interrupt_enable(level); - - return recv_len; + return recv_size; } /** @@ -455,23 +586,23 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev, * @param pos Empty parameter. * @param buffer Transmit data buffer. * @param size Transmit data buffer length. - * @return Return the final length of data transmit. + * @return Returns the actual length of data transmitted. If a timeout occurs, it returns -RT_ETIMEOUT. */ -static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) +static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev, + rt_off_t pos, + const void *buffer, + rt_size_t size) { - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo = RT_NULL; - rt_ssize_t rst; + struct rt_serial_device *serial; + struct rt_serial_tx_fifo *tx_fifo; + rt_ssize_t send_size; + rt_err_t ret; - RT_ASSERT(dev != RT_NULL); if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; + serial = (struct rt_serial_device *)dev; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; RT_ASSERT(tx_fifo != RT_NULL); if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) @@ -482,19 +613,42 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev, /* When serial transmit in tx_blocking mode, * if the activated mode is RT_TRUE, it will return directly */ - if (tx_fifo->activated == RT_TRUE) return 0; + if (rt_atomic_flag_test_and_set(&tx_fifo->activated)) + { + return 0; + } + + /* clear tx_cpt flag */ + rt_completion_wait(&tx_fifo->tx_cpt, 0); - tx_fifo->activated = RT_TRUE; /* Call the transmit interface for transmission */ - rst = serial->ops->transmit(serial, - (rt_uint8_t *)buffer, - size, - RT_SERIAL_TX_BLOCKING); + send_size = serial->ops->transmit(serial, + (rt_uint8_t *)buffer, + size, + RT_SERIAL_TX_BLOCKING); + + if (rt_atomic_load(&tx_fifo->tx_timeout) == RT_WAITING_NO) + { + return send_size; + } + /* Waiting for the transmission to complete */ - rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER); + ret = rt_completion_wait(&tx_fifo->tx_cpt, rt_atomic_load(&tx_fifo->tx_timeout)); + if (ret != RT_EOK) + { + if (ret == -RT_ETIMEOUT) + { + return ret; + } + else + { + return 0; + } + } + /* Inactive tx mode flag */ - tx_fifo->activated = RT_FALSE; - return rst; + rt_atomic_flag_clear(&tx_fifo->activated); + return send_size; } /** @@ -504,25 +658,23 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev, * @param pos Empty parameter. * @param buffer Transmit data buffer. * @param size Transmit data buffer length. - * @return Return the final length of data transmit. + * @return Returns the final length of data transmitted. If not all data can be sent within the timeout period, returns -RT_ETIMEOUT. */ -static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) +static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev, + rt_off_t pos, + const void *buffer, + rt_size_t size) { - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo = RT_NULL; - rt_size_t length = size; - rt_size_t offset = 0; + struct rt_serial_device *serial; + struct rt_serial_tx_fifo *tx_fifo; + rt_base_t level; + rt_size_t send_size = 0; if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; + serial = (struct rt_serial_device *)dev; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; RT_ASSERT(tx_fifo != RT_NULL); if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) @@ -530,34 +682,70 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev, /* using poll tx when the scheduler not startup or in stream mode */ return _serial_poll_tx(dev, pos, buffer, size); } + /* When serial transmit in tx_blocking mode, * if the activated mode is RT_TRUE, it will return directly */ - if (tx_fifo->activated == RT_TRUE) return 0; - tx_fifo->activated = RT_TRUE; + if (rt_atomic_flag_test_and_set(&tx_fifo->activated)) + { + return 0; + } - while (size) + rt_int32_t base_tx_timeout = rt_atomic_load(&tx_fifo->tx_timeout); + rt_int32_t tx_timeout = base_tx_timeout; + rt_tick_t now_tick = 0; + rt_tick_t begin_tick = rt_tick_get(); + + while (send_size != size) { /* Copy one piece of data into the ringbuffer at a time * until the length of the data is equal to size */ - tx_fifo->put_size = rt_ringbuffer_put(&(tx_fifo->rb), - (rt_uint8_t *)buffer + offset, - size); - - /* Call the transmit interface for transmission */ + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); + tx_fifo->put_size = rt_ringbuffer_put(&tx_fifo->rb, + (rt_uint8_t *)buffer + send_size, + size - send_size); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); + + /* clear tx_cpt flag */ + rt_completion_wait(&tx_fifo->tx_cpt, 0); + + /* Call the transmit interface for transmission again */ + /* Note that in interrupt mode, buffer and tx_fifo->put_size + * are inactive parameters */ serial->ops->transmit(serial, - (rt_uint8_t *)buffer + offset, - tx_fifo->put_size, - RT_SERIAL_TX_BLOCKING); + (rt_uint8_t *)buffer + send_size, + tx_fifo->put_size, + RT_SERIAL_TX_BLOCKING); + + send_size += tx_fifo->put_size; + + if (tx_timeout == RT_WAITING_NO) + { + break; + } - offset += tx_fifo->put_size; - size -= tx_fifo->put_size; /* Waiting for the transmission to complete */ - rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER); + rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout); + if (tx_timeout != RT_WAITING_FOREVER) + { + now_tick = rt_tick_get(); + if (now_tick - begin_tick >= base_tx_timeout) + { + return -RT_ETIMEOUT; + } + else + { + if (now_tick > begin_tick) + tx_timeout = base_tx_timeout - (now_tick - begin_tick); + else + tx_timeout = begin_tick + base_tx_timeout - now_tick + 1; + } + } } + /* Finally Inactivate the tx->fifo */ - tx_fifo->activated = RT_FALSE; + rt_atomic_flag_clear(&tx_fifo->activated); - return length; + return send_size; } /** @@ -569,46 +757,49 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev, * @param size Transmit data buffer length. * @return Return the final length of data transmit. */ -static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) +static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev, + rt_off_t pos, + const void *buffer, + rt_size_t size) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_tx_fifo *tx_fifo; - rt_base_t level; - rt_size_t length; + rt_uint8_t *put_ptr; + rt_base_t level; + rt_size_t send_size = 0; - RT_ASSERT(dev != RT_NULL); if (size == 0) return 0; + RT_ASSERT(dev != RT_NULL && buffer != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - - level = rt_hw_interrupt_disable(); + serial = (struct rt_serial_device *)dev; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); - if (tx_fifo->activated == RT_FALSE) - { - /* When serial transmit in tx_non_blocking mode, if the activated mode is RT_FALSE, + /* When serial transmit in tx_non_blocking mode, if the activated mode is RT_FALSE, * start copying data into the ringbuffer */ - tx_fifo->activated = RT_TRUE; + if (!rt_atomic_flag_test_and_set(&tx_fifo->activated)) + { + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); /* Copying data into the ringbuffer */ - length = rt_ringbuffer_put(&(tx_fifo->rb), buffer, size); + send_size = rt_ringbuffer_put(&tx_fifo->rb, buffer, size); - rt_hw_interrupt_enable(level); - - rt_uint8_t *put_ptr = RT_NULL; /* Get the linear length buffer from ringbuffer */ - tx_fifo->put_size = rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr); - /* Call the transmit interface for transmission */ + tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); + + /* clear tx_cpt flag */ + rt_completion_wait(&tx_fifo->tx_cpt, 0); + + /* Call the transmit interface for transmission again */ + /* Note that in interrupt mode, put_ptr and tx_fifo->put_size + * are inactive parameters */ serial->ops->transmit(serial, put_ptr, tx_fifo->put_size, RT_SERIAL_TX_NON_BLOCKING); /* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait * for the rt_current_thread to resume */ - return length; + return send_size; } /* If the activated mode is RT_TRUE, it means that serial device is transmitting, @@ -616,12 +807,12 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev, * Note that this part of the code requires disable interrupts * to prevent multi thread reentrant */ + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); /* Copying data into the ringbuffer */ - length = rt_ringbuffer_put(&(tx_fifo->rb), buffer, size); - - rt_hw_interrupt_enable(level); + send_size = rt_ringbuffer_put(&tx_fifo->rb, buffer, size); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); - return length; + return send_size; } @@ -631,10 +822,10 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev, * @param rx_oflag The flag of that the serial port opens. * @return Return the status of the operation. */ -static rt_err_t rt_serial_tx_enable(struct rt_device *dev, - rt_uint16_t tx_oflag) +static rt_err_t rt_serial_tx_enable(struct rt_device *dev, + rt_uint16_t tx_oflag) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_tx_fifo *tx_fifo = RT_NULL; RT_ASSERT(dev != RT_NULL); @@ -646,7 +837,7 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING) { LOG_E("(%s) serial device with misconfigure: tx_bufsz = 0", - dev->parent.name); + dev->parent.name); return -RT_EINVAL; } @@ -665,7 +856,7 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, { /* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine * whether serial device needs to use buffer */ - rt_err_t optmode; /* The operating mode used by serial device */ + rt_err_t optmode; /* The operating mode used by serial device */ /* Call the Control() API to get the operating mode */ optmode = serial->ops->control(serial, RT_DEVICE_CHECK_OPTMODE, @@ -673,13 +864,12 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, if (optmode == RT_SERIAL_TX_BLOCKING_BUFFER) { /* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */ - tx_fifo = (struct rt_serial_tx_fifo *) rt_malloc - (sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); + tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); RT_ASSERT(tx_fifo != RT_NULL); - - rt_ringbuffer_init(&(tx_fifo->rb), - tx_fifo->buffer, - serial->config.tx_bufsz); + rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); + rt_ringbuffer_init(&tx_fifo->rb, + (rt_uint8_t *)tx_fifo + sizeof(struct rt_serial_tx_fifo), + serial->config.tx_bufsz); serial->serial_tx = tx_fifo; #ifndef RT_USING_DEVICE_OPS @@ -690,13 +880,11 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, { /* If not use RT_SERIAL_TX_BLOCKING_BUFFER, * the control() API is called to configure the serial device */ - tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc - (sizeof(struct rt_serial_tx_fifo)); + tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo)); RT_ASSERT(tx_fifo != RT_NULL); - + rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo)); /* Init rb.buffer_ptr to RT_NULL, in rt_serial_write() need check it * otherwise buffer_ptr maybe a random value, as rt_malloc not init memory */ - tx_fifo->rb.buffer_ptr = RT_NULL; serial->serial_tx = tx_fifo; #ifndef RT_USING_DEVICE_OPS @@ -705,41 +893,45 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, /* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/ serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *)RT_SERIAL_TX_BLOCKING); - rt_memset(&tx_fifo->rb, RT_NULL, sizeof(tx_fifo->rb)); + RT_DEVICE_CTRL_CONFIG, + (void *)RT_SERIAL_TX_BLOCKING); } - - tx_fifo->activated = RT_FALSE; + rt_atomic_flag_clear(&tx_fifo->activated); tx_fifo->put_size = 0; - rt_completion_init(&(tx_fifo->tx_cpt)); + rt_atomic_store(&tx_fifo->tx_timeout, RT_WAITING_FOREVER); + + rt_completion_init(&tx_fifo->tx_cpt); dev->open_flag |= RT_SERIAL_TX_BLOCKING; return RT_EOK; } + /* When using RT_SERIAL_TX_NON_BLOCKING, ringbuffer needs to be initialized, * and initialize the tx_fifo->activated value is RT_FALSE. */ - tx_fifo = (struct rt_serial_tx_fifo *) rt_malloc - (sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); + tx_fifo = (struct rt_serial_tx_fifo *)rt_malloc(sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); RT_ASSERT(tx_fifo != RT_NULL); + rt_memset(tx_fifo, RT_NULL, sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); - tx_fifo->activated = RT_FALSE; - tx_fifo->put_size = 0; - rt_ringbuffer_init(&(tx_fifo->rb), - tx_fifo->buffer, - serial->config.tx_bufsz); + rt_ringbuffer_init(&tx_fifo->rb, + (rt_uint8_t *)tx_fifo + sizeof(struct rt_serial_tx_fifo), + serial->config.tx_bufsz); serial->serial_tx = tx_fifo; + rt_atomic_flag_clear(&tx_fifo->activated); + tx_fifo->put_size = 0; + #ifndef RT_USING_DEVICE_OPS dev->write = _serial_fifo_tx_nonblocking; #endif + rt_completion_init(&tx_fifo->tx_cpt); dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING; + /* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/ serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *)RT_SERIAL_TX_NON_BLOCKING); + RT_DEVICE_CTRL_CONFIG, + (void *)RT_SERIAL_TX_NON_BLOCKING); return RT_EOK; } @@ -751,11 +943,12 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev, * @param rx_oflag The flag of that the serial port opens. * @return Return the status of the operation. */ -static rt_err_t rt_serial_rx_enable(struct rt_device *dev, - rt_uint16_t rx_oflag) +static rt_err_t rt_serial_rx_enable(struct rt_device *dev, + rt_uint16_t rx_oflag) { - struct rt_serial_device *serial; - struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + struct rt_serial_device *serial; + struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + rt_size_t rx_fifo_size = 0; RT_ASSERT(dev != RT_NULL); serial = (struct rt_serial_device *)dev; @@ -766,7 +959,7 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev, if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) { LOG_E("(%s) serial device with misconfigure: rx_bufsz = 0", - dev->parent.name); + dev->parent.name); return -RT_EINVAL; } @@ -781,11 +974,30 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev, if (serial->config.rx_bufsz < RT_SERIAL_RX_MINBUFSZ) serial->config.rx_bufsz = RT_SERIAL_RX_MINBUFSZ; - rx_fifo = (struct rt_serial_rx_fifo *) rt_malloc - (sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz); +#ifdef RT_SERIAL_USING_DMA + if (serial->config.dma_ping_bufsz > 0 && serial->config.dma_ping_bufsz < RT_SERIAL_RX_MINBUFSZ / 2) + serial->config.dma_ping_bufsz = RT_SERIAL_RX_MINBUFSZ / 2; + rx_fifo_size = sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz + serial->config.dma_ping_bufsz; +#else + rx_fifo_size = sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz; +#endif + rx_fifo = (struct rt_serial_rx_fifo *)rt_malloc(rx_fifo_size); RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_init(&(rx_fifo->rb), rx_fifo->buffer, serial->config.rx_bufsz); + rt_memset(rx_fifo, RT_NULL, rx_fifo_size); + + rt_ringbuffer_init(&rx_fifo->rb, + (rt_uint8_t *)rx_fifo + sizeof(struct rt_serial_rx_fifo), + serial->config.rx_bufsz); + +#ifdef RT_SERIAL_USING_DMA + if (serial->config.dma_ping_bufsz > 0) + { + rt_ringbuffer_init(&rx_fifo->dma_ping_rb, + (rt_uint8_t *)rx_fifo + sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz, + serial->config.dma_ping_bufsz); + } +#endif serial->serial_rx = rx_fifo; @@ -798,19 +1010,22 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev, dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING; /* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/ serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *) RT_SERIAL_RX_NON_BLOCKING); + RT_DEVICE_CTRL_CONFIG, + (void *)RT_SERIAL_RX_NON_BLOCKING); return RT_EOK; } + /* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */ rx_fifo->rx_cpt_index = 0; - rt_completion_init(&(rx_fifo->rx_cpt)); + rt_atomic_store(&rx_fifo->rx_timeout, RT_WAITING_FOREVER); + + rt_completion_init(&rx_fifo->rx_cpt); dev->open_flag |= RT_SERIAL_RX_BLOCKING; /* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/ serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *) RT_SERIAL_RX_BLOCKING); + RT_DEVICE_CTRL_CONFIG, + (void *)RT_SERIAL_RX_BLOCKING); return RT_EOK; } @@ -821,10 +1036,10 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev, * @param rx_oflag The flag of that the serial port opens. * @return Return the status of the operation. */ -static rt_err_t rt_serial_rx_disable(struct rt_device *dev, - rt_uint16_t rx_oflag) +static rt_err_t rt_serial_rx_disable(struct rt_device *dev, + rt_uint16_t rx_oflag) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_rx_fifo *rx_fifo; RT_ASSERT(dev != RT_NULL); @@ -836,22 +1051,20 @@ static rt_err_t rt_serial_rx_disable(struct rt_device *dev, if (serial->serial_rx == RT_NULL) return RT_EOK; - do + if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) { - if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) - { - dev->open_flag &= ~ RT_SERIAL_RX_NON_BLOCKING; - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_RX_NON_BLOCKING); - break; - } - - dev->open_flag &= ~ RT_SERIAL_RX_BLOCKING; + dev->open_flag &= ~RT_SERIAL_RX_NON_BLOCKING; serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_RX_BLOCKING); - } while (0); + RT_DEVICE_CTRL_CLR_INT, + (void *)RT_SERIAL_RX_NON_BLOCKING); + } + else + { + dev->open_flag &= ~RT_SERIAL_RX_BLOCKING; + serial->ops->control(serial, + RT_DEVICE_CTRL_CLR_INT, + (void *)RT_SERIAL_RX_BLOCKING); + } rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); @@ -867,10 +1080,10 @@ static rt_err_t rt_serial_rx_disable(struct rt_device *dev, * @param rx_oflag The flag of that the serial port opens. * @return Return the status of the operation. */ -static rt_err_t rt_serial_tx_disable(struct rt_device *dev, - rt_uint16_t tx_oflag) +static rt_err_t rt_serial_tx_disable(struct rt_device *dev, + rt_uint16_t tx_oflag) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_tx_fifo *tx_fifo; RT_ASSERT(dev != RT_NULL); @@ -885,30 +1098,26 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev, tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; RT_ASSERT(tx_fifo != RT_NULL); - do + if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING) { - if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING) - { - dev->open_flag &= ~ RT_SERIAL_TX_NON_BLOCKING; + dev->open_flag &= ~RT_SERIAL_TX_NON_BLOCKING; - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_TX_NON_BLOCKING); - break; - } - - rt_completion_done(&(tx_fifo->tx_cpt)); - dev->open_flag &= ~ RT_SERIAL_TX_BLOCKING; serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_TX_BLOCKING); - } while (0); + RT_DEVICE_CTRL_CLR_INT, + (void *)RT_SERIAL_TX_NON_BLOCKING); + } + else + { + rt_completion_done(&tx_fifo->tx_cpt); + dev->open_flag &= ~RT_SERIAL_TX_BLOCKING; + serial->ops->control(serial, + RT_DEVICE_CTRL_CLR_INT, + (void *)RT_SERIAL_TX_BLOCKING); + } + rt_free(tx_fifo); serial->serial_tx = RT_NULL; - - rt_memset(&serial->rx_notify, 0, sizeof(struct rt_device_notify)); - return RT_EOK; } @@ -919,7 +1128,7 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev, */ static rt_err_t rt_serial_init(struct rt_device *dev) { - rt_err_t result = RT_EOK; + rt_err_t result = RT_EOK; struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); @@ -958,7 +1167,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) } LOG_D("open serial device: 0x%08x with open flag: 0x%04x", - dev, oflag); + dev, oflag); /* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */ if ((oflag & RT_SERIAL_RX_BLOCKING) == RT_SERIAL_RX_BLOCKING) @@ -973,19 +1182,16 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) dev->open_flag |= RT_SERIAL_TX_BLOCKING; /* set steam flag */ - if ((oflag & RT_DEVICE_FLAG_STREAM) || - (dev->open_flag & RT_DEVICE_FLAG_STREAM)) + if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM)) dev->open_flag |= RT_DEVICE_FLAG_STREAM; /* initialize the Rx structure according to open flag */ if (serial->serial_rx == RT_NULL) - rt_serial_rx_enable(dev, dev->open_flag & - (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); + rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); /* initialize the Tx structure according to open flag */ if (serial->serial_tx == RT_NULL) - rt_serial_tx_enable(dev, dev->open_flag & - (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); + rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); return RT_EOK; } @@ -1006,16 +1212,16 @@ static rt_err_t rt_serial_close(struct rt_device *dev) /* this device has more reference count */ if (dev->ref_count > 1) return -RT_ERROR; /* Disable serial receive mode. */ - rt_serial_rx_disable(dev, dev->open_flag & - (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); + rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); /* Disable serial tranmit mode. */ - rt_serial_tx_disable(dev, dev->open_flag & - (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); + rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); /* Clear the callback function */ serial->parent.rx_indicate = RT_NULL; serial->parent.tx_complete = RT_NULL; + rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify)); + /* Call the control() API to close the serial device */ serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL); dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED; @@ -1023,48 +1229,121 @@ static rt_err_t rt_serial_close(struct rt_device *dev) return RT_EOK; } -#ifdef RT_USING_POSIX_TERMIOS -struct speed_baudrate_item -{ - speed_t speed; - int baudrate; -}; - -const static struct speed_baudrate_item _tbl[] = -{ - {B2400, BAUD_RATE_2400}, - {B4800, BAUD_RATE_4800}, - {B9600, BAUD_RATE_9600}, - {B19200, BAUD_RATE_19200}, - {B38400, BAUD_RATE_38400}, - {B57600, BAUD_RATE_57600}, - {B115200, BAUD_RATE_115200}, - {B230400, BAUD_RATE_230400}, - {B460800, BAUD_RATE_460800}, - {B500000, BAUD_RATE_500000}, - {B921600, BAUD_RATE_921600}, - {B2000000, BAUD_RATE_2000000}, - {B3000000, BAUD_RATE_3000000}, -}; - -static speed_t _get_speed(int baudrate) +static void _serial_rx_flush(struct rt_serial_device *serial) { - int index; + rt_base_t level; + struct rt_serial_rx_fifo *rx_fifo; + RT_ASSERT(serial != RT_NULL); - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) + if (serial->config.rx_bufsz == 0) { - if (_tbl[index].baudrate == baudrate) - return _tbl[index].speed; + while (serial->ops->getc(serial) != -1) + { + } + } + else + { + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + level = rt_spin_lock_irqsave(&serial->spinlock); + rt_completion_wait(&rx_fifo->rx_cpt, 0); + rt_ringbuffer_reset(&rx_fifo->rb); + rx_fifo->rx_cpt_index = 0; +#ifdef RT_SERIAL_USING_DMA + if (serial->config.dma_ping_bufsz > 0) + { + rt_ringbuffer_reset(&rx_fifo->dma_ping_rb); + } +#endif + rt_spin_unlock_irqrestore(&serial->spinlock, level); } - - return B0; +} + +static void _serial_tx_flush(struct rt_serial_device *serial) +{ + struct rt_serial_tx_fifo *tx_fifo; + RT_ASSERT(serial != RT_NULL); + + if (serial->config.tx_bufsz != 0) + { + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); + + if (rt_atomic_load(&tx_fifo->activated)) + { + rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER); + return; + } + } +} + +static rt_err_t _serial_get_unread_bytes_count(struct rt_serial_device *serial, rt_ssize_t *unread_bytes) +{ + rt_base_t level; + struct rt_serial_rx_fifo *rx_fifo; + RT_ASSERT(serial != RT_NULL); + + if (serial->config.rx_bufsz == 0) + { + LOG_W("get unread bytes count not support in poll mode."); + *unread_bytes = -1; + return -RT_EPERM; + } + else + { + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + level = RT_SERIAL_FIFO_LOCK(&serial->spinlock); + *unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb); + RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level); + } + return RT_EOK; +} + +#ifdef RT_USING_POSIX_TERMIOS +struct speed_baudrate_item +{ + speed_t speed; + int baudrate; +}; + +const static struct speed_baudrate_item _tbl[] = + { + { B2400, BAUD_RATE_2400}, + { B4800, BAUD_RATE_4800}, + { B9600, BAUD_RATE_9600}, + { B19200, BAUD_RATE_19200}, + { B38400, BAUD_RATE_38400}, + { B57600, BAUD_RATE_57600}, + { B115200, BAUD_RATE_115200}, + { B230400, BAUD_RATE_230400}, + { B460800, BAUD_RATE_460800}, + { B500000, BAUD_RATE_500000}, + { B921600, BAUD_RATE_921600}, + {B2000000, BAUD_RATE_2000000}, + {B3000000, BAUD_RATE_3000000}, +}; + +static speed_t _get_speed(int baudrate) +{ + int index; + + for (index = 0; index < sizeof(_tbl) / sizeof(_tbl[0]); index++) + { + if (_tbl[index].baudrate == baudrate) + return _tbl[index].speed; + } + + return B0; } static int _get_baudrate(speed_t speed) { int index; - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) + for (index = 0; index < sizeof(_tbl) / sizeof(_tbl[0]); index++) { if (_tbl[index].speed == speed) return _tbl[index].baudrate; @@ -1075,44 +1354,17 @@ static int _get_baudrate(speed_t speed) static void _tc_flush(struct rt_serial_device *serial, int queue) { - rt_base_t level; - int ch = -1; - struct rt_serial_rx_fifo *rx_fifo = RT_NULL; - struct rt_device *device = RT_NULL; - RT_ASSERT(serial != RT_NULL); - device = &(serial->parent); - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - switch(queue) + if (queue == TCIFLUSH || queue == TCIOFLUSH) { - case TCIFLUSH: - case TCIOFLUSH: - RT_ASSERT(rx_fifo != RT_NULL); - - if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX)) - { - RT_ASSERT(RT_NULL != rx_fifo); - level = rt_hw_interrupt_disable(); - rx_fifo->rx_cpt_index = 0; - rt_hw_interrupt_enable(level); - } - else - { - while (1) - { - ch = serial->ops->getc(serial); - if (ch == -1) break; - } - } - - break; - - case TCOFLUSH: - break; + _serial_rx_flush(serial); } + if (queue == TCOFLUSH || queue == TCIOFLUSH) + { + _serial_tx_flush(serial); + } } #endif /* RT_USING_POSIX_TERMIOS */ @@ -1127,7 +1379,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev, int cmd, void *args) { - rt_err_t ret = RT_EOK; + rt_err_t ret = RT_EOK; struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); @@ -1135,254 +1387,381 @@ static rt_err_t rt_serial_control(struct rt_device *dev, switch (cmd) { - case RT_DEVICE_CTRL_SUSPEND: - /* suspend device */ - dev->flag |= RT_DEVICE_FLAG_SUSPENDED; - break; + case RT_DEVICE_CTRL_SUSPEND: + /* suspend device */ + dev->flag |= RT_DEVICE_FLAG_SUSPENDED; + break; - case RT_DEVICE_CTRL_RESUME: - /* resume device */ - dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; - break; + case RT_DEVICE_CTRL_RESUME: + /* resume device */ + dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; + break; - case RT_DEVICE_CTRL_CONFIG: - if (args != RT_NULL) + case RT_DEVICE_CTRL_CONFIG: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + struct serial_configure *pconfig = (struct serial_configure *)args; + if (((pconfig->rx_bufsz != serial->config.rx_bufsz) + || (pconfig->tx_bufsz != serial->config.tx_bufsz) +#ifdef RT_SERIAL_USING_DMA + || (pconfig->dma_ping_bufsz != serial->config.dma_ping_bufsz) +#endif + ) + && serial->parent.ref_count != 0) { - struct serial_configure *pconfig = (struct serial_configure *) args; - if (((pconfig->rx_bufsz != serial->config.rx_bufsz) || (pconfig->tx_bufsz != serial->config.tx_bufsz)) - && serial->parent.ref_count) - { - /*can not change buffer size*/ - return -RT_EBUSY; - } - /* set serial configure */ - serial->config = *pconfig; - serial->ops->configure(serial, (struct serial_configure *) args); + /*can not change buffer size*/ + ret = -RT_EBUSY; + break; } - break; - case RT_DEVICE_CTRL_NOTIFY_SET: - if (args) + /* set serial configure */ + serial->config = *pconfig; + serial->ops->configure(serial, (struct serial_configure *)args); + } + break; + case RT_DEVICE_CTRL_NOTIFY_SET: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify)); + } + break; + + case RT_DEVICE_CTRL_CONSOLE_OFLAG: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + *(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM; + } + break; + + /* Call before rt_device_read */ + case RT_SERIAL_CTRL_SET_RX_TIMEOUT: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + if (serial->config.rx_bufsz == 0) { - rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify)); + ret = -RT_EPERM; } - break; - case RT_DEVICE_CTRL_CONSOLE_OFLAG: - if (args) + struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + rt_atomic_store(&rx_fifo->rx_timeout, *(rt_int32_t *)args); + } + break; + + /* Call before rt_device_write */ + case RT_SERIAL_CTRL_SET_TX_TIMEOUT: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + if (serial->config.tx_bufsz == 0) { - *(rt_uint16_t*)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM; + ret = -RT_EPERM; } - break; -#ifdef RT_USING_POSIX_STDIO -#ifdef RT_USING_POSIX_TERMIOS - case TCGETA: + + struct rt_serial_tx_fifo *tx_fifo = RT_NULL; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); + + rt_atomic_store(&tx_fifo->tx_timeout, *(rt_int32_t *)args); + } + break; + + case RT_SERIAL_CTRL_GET_RX_TIMEOUT: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + if (serial->config.rx_bufsz == 0) { - struct termios *tio = (struct termios*)args; - if (tio == RT_NULL) return -RT_EINVAL; - - tio->c_iflag = 0; - tio->c_oflag = 0; - tio->c_lflag = 0; - - /* update oflag for console device */ - if (rt_console_get_device() == dev) - tio->c_oflag = OPOST | ONLCR; - - /* set cflag */ - tio->c_cflag = 0; - if (serial->config.data_bits == DATA_BITS_5) - tio->c_cflag = CS5; - else if (serial->config.data_bits == DATA_BITS_6) - tio->c_cflag = CS6; - else if (serial->config.data_bits == DATA_BITS_7) - tio->c_cflag = CS7; - else if (serial->config.data_bits == DATA_BITS_8) - tio->c_cflag = CS8; - - if (serial->config.stop_bits == STOP_BITS_2) - tio->c_cflag |= CSTOPB; - - if (serial->config.parity == PARITY_EVEN) - tio->c_cflag |= PARENB; - else if (serial->config.parity == PARITY_ODD) - tio->c_cflag |= (PARODD | PARENB); - - if (serial->config.flowcontrol == RT_SERIAL_FLOWCONTROL_CTSRTS) - tio->c_cflag |= CRTSCTS; - - cfsetospeed(tio, _get_speed(serial->config.baud_rate)); + ret = -RT_EPERM; } - break; - case TCSETAW: - case TCSETAF: - case TCSETA: + struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + *(rt_int32_t *)args = rt_atomic_load(&rx_fifo->rx_timeout); + } + break; + + case RT_SERIAL_CTRL_GET_TX_TIMEOUT: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + if (serial->config.tx_bufsz == 0) { - int baudrate; - struct serial_configure config; + ret = -RT_EPERM; + } - struct termios *tio = (struct termios*)args; - if (tio == RT_NULL) return -RT_EINVAL; + struct rt_serial_tx_fifo *tx_fifo = RT_NULL; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); - config = serial->config; + *(rt_int32_t *)args = rt_atomic_load(&tx_fifo->tx_timeout); + } + break; - baudrate = _get_baudrate(cfgetospeed(tio)); - config.baud_rate = baudrate; + /* Discard all data */ + case RT_SERIAL_CTRL_RX_FLUSH: + _serial_rx_flush(serial); + break; - switch (tio->c_cflag & CSIZE) - { - case CS5: - config.data_bits = DATA_BITS_5; - break; - case CS6: - config.data_bits = DATA_BITS_6; - break; - case CS7: - config.data_bits = DATA_BITS_7; - break; - default: - config.data_bits = DATA_BITS_8; - break; - } + /* Blocking and wait for the send buffer data to be sent. */ + case RT_SERIAL_CTRL_TX_FLUSH: + _serial_tx_flush(serial); + break; - if (tio->c_cflag & CSTOPB) config.stop_bits = STOP_BITS_2; - else config.stop_bits = STOP_BITS_1; + /* get unread bytes count. */ + case RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + ret = _serial_get_unread_bytes_count(serial, (rt_ssize_t *)args); + } + break; - if (tio->c_cflag & PARENB) - { - if (tio->c_cflag & PARODD) config.parity = PARITY_ODD; - else config.parity = PARITY_EVEN; - } - else config.parity = PARITY_NONE; +#ifdef RT_USING_POSIX_STDIO +#ifdef RT_USING_POSIX_TERMIOS + case TCGETA: { + struct termios *tio = (struct termios *)args; + if (tio == RT_NULL) return -RT_EINVAL; + + tio->c_iflag = 0; + tio->c_oflag = 0; + tio->c_lflag = 0; + + /* update oflag for console device */ + if (rt_console_get_device() == dev) + tio->c_oflag = OPOST | ONLCR; + + /* set cflag */ + tio->c_cflag = 0; + if (serial->config.data_bits == DATA_BITS_5) + tio->c_cflag = CS5; + else if (serial->config.data_bits == DATA_BITS_6) + tio->c_cflag = CS6; + else if (serial->config.data_bits == DATA_BITS_7) + tio->c_cflag = CS7; + else if (serial->config.data_bits == DATA_BITS_8) + tio->c_cflag = CS8; + + if (serial->config.stop_bits == STOP_BITS_2) + tio->c_cflag |= CSTOPB; + + if (serial->config.parity == PARITY_EVEN) + tio->c_cflag |= PARENB; + else if (serial->config.parity == PARITY_ODD) + tio->c_cflag |= (PARODD | PARENB); + + if (serial->config.flowcontrol == RT_SERIAL_FLOWCONTROL_CTSRTS) + tio->c_cflag |= CRTSCTS; + + cfsetospeed(tio, _get_speed(serial->config.baud_rate)); + } + break; - if (tio->c_cflag & CRTSCTS) config.flowcontrol = RT_SERIAL_FLOWCONTROL_CTSRTS; - else config.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE; + case TCSETAW: + case TCSETAF: + case TCSETA: { + int baudrate; + struct serial_configure config; - /* set serial configure */ - serial->config = config; - serial->ops->configure(serial, &config); - } - break; - case TCFLSH: - { - int queue = (int)args; + struct termios *tio = (struct termios *)args; + if (tio == RT_NULL) return -RT_EINVAL; - _tc_flush(serial, queue); - } + config = serial->config; + baudrate = _get_baudrate(cfgetospeed(tio)); + config.baud_rate = baudrate; + + switch (tio->c_cflag & CSIZE) + { + case CS5: + config.data_bits = DATA_BITS_5; break; - case TCXONC: + case CS6: + config.data_bits = DATA_BITS_6; break; -#endif /*RT_USING_POSIX_TERMIOS*/ - case TIOCSWINSZ: - { - struct winsize* p_winsize; - - p_winsize = (struct winsize*)args; - rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row); - } + case CS7: + config.data_bits = DATA_BITS_7; break; - case TIOCGWINSZ: - { - struct winsize* p_winsize; - p_winsize = (struct winsize*)args; + default: + config.data_bits = DATA_BITS_8; + break; + } - if(rt_thread_self() != rt_thread_find(FINSH_THREAD_NAME)) - { - /* only can be used in tshell thread; otherwise, return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - } - else - { - #include - #define _TIO_BUFLEN 20 - char _tio_buf[_TIO_BUFLEN]; - unsigned char cnt1, cnt2, cnt3, i; - char row_s[4], col_s[4]; - char *p; + if (tio->c_cflag & CSTOPB) + config.stop_bits = STOP_BITS_2; + else + config.stop_bits = STOP_BITS_1; - rt_memset(_tio_buf, 0, _TIO_BUFLEN); + if (tio->c_cflag & PARENB) + { + if (tio->c_cflag & PARODD) + config.parity = PARITY_ODD; + else + config.parity = PARITY_EVEN; + } + else + config.parity = PARITY_NONE; - /* send the command to terminal for getting the window size of the terminal */ - rt_kprintf("\033[18t"); + if (tio->c_cflag & CRTSCTS) + config.flowcontrol = RT_SERIAL_FLOWCONTROL_CTSRTS; + else + config.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE; - /* waiting for the response from the terminal */ - i = 0; - while(i < _TIO_BUFLEN) - { - _tio_buf[i] = finsh_getchar(); - if(_tio_buf[i] != 't') - { - i ++; - } - else - { - break; - } - } - if(i == _TIO_BUFLEN) - { - /* buffer overloaded, and return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - break; - } + /* set serial configure */ + serial->config = config; + serial->ops->configure(serial, &config); + } + break; + case TCFLSH: { + int queue = (int)args; - /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */ - rt_memset(row_s,0,4); - rt_memset(col_s,0,4); - cnt1 = 0; - while(cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';') - { - cnt1++; - } - cnt2 = ++cnt1; - while(cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';') - { - cnt2++; - } - p = row_s; - while(cnt1 < cnt2) - { - *p++ = _tio_buf[cnt1++]; - } - p = col_s; - cnt2++; - cnt3 = rt_strlen(_tio_buf) - 1; - while(cnt2 < cnt3) - { - *p++ = _tio_buf[cnt2++]; - } + _tc_flush(serial, queue); + } + + break; + case TCXONC: + break; +#endif /*RT_USING_POSIX_TERMIOS*/ + case TIOCSWINSZ: { + struct winsize *p_winsize; - /* load the window size date */ - p_winsize->ws_col = atoi(col_s); - p_winsize->ws_row = atoi(row_s); - #undef _TIO_BUFLEN + p_winsize = (struct winsize *)args; + rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row); + } + break; + case TIOCGWINSZ: { + struct winsize *p_winsize; + p_winsize = (struct winsize *)args; + + if (rt_thread_self() != rt_thread_find(FINSH_THREAD_NAME)) + { + /* only can be used in tshell thread; otherwise, return default size */ + p_winsize->ws_col = 80; + p_winsize->ws_row = 24; + } + else + { +#include +#define _TIO_BUFLEN 20 + char _tio_buf[_TIO_BUFLEN]; + unsigned char cnt1, cnt2, cnt3, i; + char row_s[4], col_s[4]; + char *p; + + rt_memset(_tio_buf, 0, _TIO_BUFLEN); + + /* send the command to terminal for getting the window size of the terminal */ + rt_kprintf("\033[18t"); + + /* waiting for the response from the terminal */ + i = 0; + while (i < _TIO_BUFLEN) + { + _tio_buf[i] = finsh_getchar(); + if (_tio_buf[i] != 't') + { + i++; } + else + { + break; + } + } + if (i == _TIO_BUFLEN) + { + /* buffer overloaded, and return default size */ + p_winsize->ws_col = 80; + p_winsize->ws_row = 24; + break; + } - p_winsize->ws_xpixel = 0;/* unused */ - p_winsize->ws_ypixel = 0;/* unused */ + /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */ + rt_memset(row_s, 0, 4); + rt_memset(col_s, 0, 4); + cnt1 = 0; + while (cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';') + { + cnt1++; } - break; - case FIONREAD: + cnt2 = ++cnt1; + while (cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';') + { + cnt2++; + } + p = row_s; + while (cnt1 < cnt2) { - rt_size_t recved = 0; - rt_base_t level; - struct rt_serial_rx_fifo * rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; + *p++ = _tio_buf[cnt1++]; + } + p = col_s; + cnt2++; + cnt3 = rt_strlen(_tio_buf) - 1; + while (cnt2 < cnt3) + { + *p++ = _tio_buf[cnt2++]; + } - level = rt_hw_interrupt_disable(); - recved = rt_ringbuffer_data_len(&(rx_fifo->rb)); - rt_hw_interrupt_enable(level); + /* load the window size date */ + p_winsize->ws_col = atoi(col_s); + p_winsize->ws_row = atoi(row_s); +#undef _TIO_BUFLEN + } - *(rt_size_t *)args = recved; - } - break; + p_winsize->ws_xpixel = 0; /* unused */ + p_winsize->ws_ypixel = 0; /* unused */ + } + break; + case FIONREAD: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + rt_ssize_t unread_bytes = 0; + ret = _serial_get_unread_bytes_count(serial, &unread_bytes); + if (ret == RT_EOK) + *(rt_size_t *)args = (rt_size_t)unread_bytes; + else + *(rt_size_t *)args = 0; + } + break; #endif /* RT_USING_POSIX_STDIO */ - default : - /* control device */ - ret = serial->ops->control(serial, cmd, args); - break; + default: + /* control device */ + ret = serial->ops->control(serial, cmd, args); + break; } return ret; @@ -1390,9 +1769,9 @@ static rt_err_t rt_serial_control(struct rt_device *dev, #ifdef RT_USING_DEVICE_OPS static rt_ssize_t rt_serial_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) + rt_off_t pos, + void *buffer, + rt_size_t size) { struct rt_serial_device *serial; @@ -1411,11 +1790,11 @@ static rt_ssize_t rt_serial_read(struct rt_device *dev, static rt_ssize_t rt_serial_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) + rt_off_t pos, + const void *buffer, + rt_size_t size) { - struct rt_serial_device *serial; + struct rt_serial_device *serial; struct rt_serial_tx_fifo *tx_fifo; RT_ASSERT(dev != RT_NULL); @@ -1423,7 +1802,7 @@ static rt_ssize_t rt_serial_write(struct rt_device *dev, serial = (struct rt_serial_device *)dev; RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; if (serial->config.tx_bufsz == 0) { @@ -1432,6 +1811,7 @@ static rt_ssize_t rt_serial_write(struct rt_device *dev, if (dev->open_flag & RT_SERIAL_TX_BLOCKING) { + RT_ASSERT(tx_fifo != RT_NULL); if ((tx_fifo->rb.buffer_ptr) == RT_NULL) { return _serial_fifo_tx_blocking_nbuf(dev, pos, buffer, size); @@ -1444,14 +1824,13 @@ static rt_ssize_t rt_serial_write(struct rt_device *dev, } const static struct rt_device_ops serial_ops = -{ - rt_serial_init, - rt_serial_open, - rt_serial_close, - rt_serial_read, - rt_serial_write, - rt_serial_control -}; + { + rt_serial_init, + rt_serial_open, + rt_serial_close, + rt_serial_read, + rt_serial_write, + rt_serial_control}; #endif /** @@ -1467,34 +1846,36 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, rt_uint32_t flag, void *data) { - rt_err_t ret; + rt_err_t ret; struct rt_device *device; RT_ASSERT(serial != RT_NULL); - device = &(serial->parent); + rt_spin_lock_init(&serial->spinlock); + + device = &serial->parent; device->type = RT_Device_Class_Char; device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; #ifdef RT_USING_DEVICE_OPS - device->ops = &serial_ops; + device->ops = &serial_ops; #else - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = RT_NULL; - device->write = RT_NULL; - device->control = rt_serial_control; + device->init = rt_serial_init; + device->open = rt_serial_open; + device->close = rt_serial_close; + device->read = RT_NULL; + device->write = RT_NULL; + device->control = rt_serial_control; #endif - device->user_data = data; + device->user_data = data; /* register a character device */ ret = rt_device_register(device, name, flag); #ifdef RT_USING_POSIX_STDIO /* set fops */ - device->fops = &_serial_fops; + device->fops = &_serial_fops; #endif return ret; } @@ -1504,139 +1885,266 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, * @param serial RT-thread serial device. * @param event ISR event type. */ -void rt_hw_serial_isr(struct rt_serial_device *serial, int event) +rt_err_t rt_hw_serial_control_isr(struct rt_serial_device *serial, int cmd, void *args) { RT_ASSERT(serial != RT_NULL); + rt_err_t ret = RT_EOK; - switch (event & 0xff) + switch (cmd) { - /* Interrupt receive event */ - case RT_SERIAL_EVENT_RX_IND: - case RT_SERIAL_EVENT_RX_DMADONE: + case RT_HW_SERIAL_CTRL_PUTC: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else { - struct rt_serial_rx_fifo *rx_fifo; - rt_size_t rx_length = 0; - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - rt_base_t level; + struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); - /* If the event is RT_SERIAL_EVENT_RX_IND, rx_length is equal to 0 */ - rx_length = (event & (~0xff)) >> 8; +#ifdef RT_SERIAL_BUF_STRATEGY_DROP + rt_ringbuffer_putchar(&rx_fifo->rb, *(rt_uint8_t *)args); +#else + rt_ringbuffer_putchar_force(&rx_fifo->rb, *(rt_uint8_t *)args); +#endif /* RT_SERIAL_BUF_STRATEGY_DROP */ + } + break; - if (rx_length) - { /* RT_SERIAL_EVENT_RX_DMADONE MODE */ - level = rt_hw_interrupt_disable(); - rt_serial_update_write_index(&(rx_fifo->rb), rx_length); - rt_hw_interrupt_enable(level); + case RT_HW_SERIAL_CTRL_GETC: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + struct rt_serial_tx_fifo *tx_fifo = RT_NULL; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); + if (rt_ringbuffer_getchar(&tx_fifo->rb, (rt_uint8_t *)args) == 0) + { + ret = -RT_EEMPTY; } + } + break; - /* Get the length of the data from the ringbuffer */ - rx_length = rt_ringbuffer_data_len(&rx_fifo->rb); - if (rx_length == 0) break; +#ifdef RT_SERIAL_USING_DMA + case RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF: + if (args == RT_NULL) + { + ret = -RT_EINVAL; + } + else + { + struct rt_serial_rx_fifo *rx_fifo = RT_NULL; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + *(rt_uint8_t **)args = rx_fifo->dma_ping_rb.buffer_ptr; + } + break; +#endif - if (serial->parent.open_flag & RT_SERIAL_RX_BLOCKING) + default: + ret = -RT_EINVAL; + break; + } + + return ret; +} + +/** + * @brief ISR for serial interrupt + * @param serial RT-thread serial device. + * @param event ISR event type. + */ +void rt_hw_serial_isr(struct rt_serial_device *serial, int event) +{ + RT_ASSERT(serial != RT_NULL); + + switch (event & 0xff) + { + /* Interrupt receive event */ + case RT_SERIAL_EVENT_RX_IND: + case RT_SERIAL_EVENT_RX_DMADONE: { + struct rt_serial_rx_fifo *rx_fifo; + rt_size_t rx_length = 0; + rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + +#ifdef RT_SERIAL_USING_DMA + rt_base_t level; + /* If the event is RT_SERIAL_EVENT_RX_IND, rx_length is equal to 0 */ + rx_length = event >> 8; + + /* RT_SERIAL_EVENT_RX_DMADONE MODE */ + if (rx_length != 0) + { +#ifdef RT_SERIAL_BUF_STRATEGY_DROP + rt_uint8_t *ptr; + rt_size_t size; + rt_size_t space_len; + /* UART_IT_IDLE and dma isr */ + level = rt_spin_lock_irqsave(&serial->spinlock); + rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length); + do { - if (rx_fifo->rx_cpt_index && rx_length >= rx_fifo->rx_cpt_index ) - { - rx_fifo->rx_cpt_index = 0; - rt_completion_done(&(rx_fifo->rx_cpt)); - } - } - /* Trigger the receiving completion callback */ - if (serial->parent.rx_indicate != RT_NULL) - serial->parent.rx_indicate(&(serial->parent), rx_length); + space_len = rt_ringbuffer_space_len(&rx_fifo->rb); + if (space_len == 0) + break; - if (serial->rx_notify.notify) + size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr); + if (size == 0) + break; + + space_len -= rt_ringbuffer_put(&rx_fifo->rb, ptr, size); + if (space_len == 0) + break; + + size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr); + if (size == 0) + break; + + rt_ringbuffer_put(&rx_fifo->rb, ptr, size); + } while (0); + if (space_len == 0) + rt_serial_update_read_index(&rx_fifo->dma_ping_rb, rt_ringbuffer_get_size(&rx_fifo->dma_ping_rb)); + rt_spin_unlock_irqrestore(&serial->spinlock, level); +#else + rt_uint8_t *ptr; + rt_size_t size; + /* UART_IT_IDLE and dma isr */ + level = rt_spin_lock_irqsave(&serial->spinlock); + rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length); + do { - serial->rx_notify.notify(serial->rx_notify.dev); - } - break; + size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr); + if (size == 0) + break; + + rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size); + + size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr); + if (size == 0) + break; + + rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size); + } while (0); + rt_spin_unlock_irqrestore(&serial->spinlock, level); +#endif /* RT_SERIAL_BUF_STRATEGY_DROP */ } +#endif /* RT_SERIAL_USING_DMA */ - /* Interrupt transmit event */ - case RT_SERIAL_EVENT_TX_DONE: + rx_length = rt_ringbuffer_data_len(&rx_fifo->rb); + if (rx_length == 0) { - struct rt_serial_tx_fifo *tx_fifo; - rt_size_t tx_length = 0; - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); + break; + } - /* Get the length of the data from the ringbuffer */ - tx_length = rt_ringbuffer_data_len(&tx_fifo->rb); - /* If there is no data in tx_ringbuffer, - * then the transmit completion callback is triggered*/ - if (tx_length == 0) + if (serial->parent.open_flag & RT_SERIAL_RX_BLOCKING) + { + if (rx_fifo->rx_cpt_index && rx_length >= rx_fifo->rx_cpt_index) { - /* Trigger the transmit completion callback */ - if (serial->parent.tx_complete != RT_NULL) - serial->parent.tx_complete(&serial->parent, RT_NULL); - - /* Maybe some datas left in the buffer still need to be sent in block mode, - * so tx_fifo->activated should be RT_TRUE */ - if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) - { - rt_completion_done(&(tx_fifo->tx_cpt)); - } - else - { - tx_fifo->activated = RT_FALSE; - } - - break; + rx_fifo->rx_cpt_index = 0; + rt_completion_done(&rx_fifo->rx_cpt); } + } - /* Call the transmit interface for transmission again */ - /* Note that in interrupt mode, tx_fifo->buffer and tx_length - * are inactive parameters */ - serial->ops->transmit(serial, - tx_fifo->buffer, - tx_length, - serial->parent.open_flag & ( \ - RT_SERIAL_TX_BLOCKING | \ - RT_SERIAL_TX_NON_BLOCKING)); - break; + /* Trigger the receiving completion callback */ + if (serial->parent.rx_indicate != RT_NULL) + { + serial->parent.rx_indicate(&serial->parent, rx_length); } - case RT_SERIAL_EVENT_TX_DMADONE: + if (serial->rx_notify.notify != RT_NULL) { - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); + serial->rx_notify.notify(serial->rx_notify.dev); + } + break; + } + + /* Interrupt transmit event */ + case RT_SERIAL_EVENT_TX_DONE: { + struct rt_serial_tx_fifo *tx_fifo; + rt_size_t tx_length = 0; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); + + /* Get the length of the data from the ringbuffer */ + tx_length = rt_ringbuffer_data_len(&tx_fifo->rb); - tx_fifo->activated = RT_FALSE; + /* If there is no data in tx_ringbuffer, + * then the transmit completion callback is triggered*/ + if (tx_length == 0) + { + rt_completion_done(&tx_fifo->tx_cpt); /* Trigger the transmit completion callback */ if (serial->parent.tx_complete != RT_NULL) - serial->parent.tx_complete(&serial->parent, RT_NULL); - - if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) { - rt_completion_done(&(tx_fifo->tx_cpt)); - break; + serial->parent.tx_complete(&serial->parent, RT_NULL); } + rt_atomic_flag_clear(&tx_fifo->activated); + break; + } + + rt_atomic_flag_test_and_set(&tx_fifo->activated); + /* Call the transmit interface for transmission again */ + /* Note that in interrupt mode, tx_fifo->buffer and tx_length + * are inactive parameters */ + serial->ops->transmit(serial, + tx_fifo->rb.buffer_ptr, + tx_length, + serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); + break; + } + +#ifdef RT_SERIAL_USING_DMA + case RT_SERIAL_EVENT_TX_DMADONE: { + struct rt_serial_tx_fifo *tx_fifo; + rt_size_t tx_length = 0; + tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; + RT_ASSERT(tx_fifo != RT_NULL); + if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING || rt_ringbuffer_get_size(&tx_fifo->rb) != 0) + { + // 每次进来中断就说明之前的put_size已经被发送完毕了 rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size); - /* Get the length of the data from the ringbuffer. - * If there is some data in tx_ringbuffer, - * then call the transmit interface for transmission again */ - if (rt_ringbuffer_data_len(&tx_fifo->rb)) + + /* Get the length of the data from the ringbuffer */ + tx_length = rt_ringbuffer_data_len(&tx_fifo->rb); + + if (tx_length != 0) { - tx_fifo->activated = RT_TRUE; + /* If there is some data in tx_ringbuffer, + * then call the transmit interface for transmission again */ + rt_atomic_flag_test_and_set(&tx_fifo->activated); - rt_uint8_t *put_ptr = RT_NULL; + rt_uint8_t *put_ptr = RT_NULL; /* Get the linear length buffer from ringbuffer */ - tx_fifo->put_size = rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr); + tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr); + /* Call the transmit interface for transmission again */ serial->ops->transmit(serial, - put_ptr, - tx_fifo->put_size, - RT_SERIAL_TX_NON_BLOCKING); + put_ptr, + tx_fifo->put_size, + RT_SERIAL_TX_NON_BLOCKING); + break; } + } - break; + rt_completion_done(&tx_fifo->tx_cpt); + + /* Trigger the transmit completion callback */ + if (serial->parent.tx_complete != RT_NULL) + { + serial->parent.tx_complete(&serial->parent, RT_NULL); } - default: - break; + rt_atomic_flag_clear(&tx_fifo->activated); + break; + } +#endif /* RT_SERIAL_USING_DMA */ + default: + break; } } diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index 6af944168a9..b94c0448cc1 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2025 RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -90,7 +90,10 @@ struct at_server char send_buffer[AT_SERVER_SEND_BUFF_LEN]; char recv_buffer[AT_SERVER_RECV_BUFF_LEN]; rt_size_t cur_recv_len; + +#if (!defined(RT_USING_SERIAL_V2)) rt_sem_t rx_notice; +#endif rt_thread_t parser; void (*parser_entry)(struct at_server *server); @@ -165,7 +168,11 @@ struct at_client rt_size_t recv_line_len; /* The maximum supported receive data length */ rt_size_t recv_bufsz; + +#if (!defined(RT_USING_SERIAL_V2)) rt_sem_t rx_notice; +#endif + rt_mutex_t lock; at_response_t resp; diff --git a/components/net/at/src/at_client.c b/components/net/at/src/at_client.c index 900f2b1b962..ed183f1eac8 100644 --- a/components/net/at/src/at_client.c +++ b/components/net/at/src/at_client.c @@ -11,6 +11,7 @@ * 2021-03-17 Meco Man fix a buf of leaking memory * 2021-07-14 Sszl fix a buf of leaking memory * 2025-01-02 dongly support SERIAL_V2 + * 2025-04-18 RyanCw support New SERIAL_V2 */ #include @@ -225,7 +226,8 @@ int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char RT_ASSERT(resp); RT_ASSERT(resp_expr); - if ((resp_line_buf = at_resp_get_line(resp, resp_line)) == RT_NULL) + resp_line_buf = at_resp_get_line(resp, resp_line); + if (resp_line_buf == RT_NULL) { return -1; } @@ -259,7 +261,8 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const RT_ASSERT(resp); RT_ASSERT(resp_expr); - if ((resp_line_buf = at_resp_get_line_by_kw(resp, keyword)) == RT_NULL) + resp_line_buf = at_resp_get_line_by_kw(resp, keyword); + if (resp_line_buf == RT_NULL) { return -1; } @@ -541,6 +544,7 @@ static rt_err_t at_client_getchar(at_client_t client, char *ch, rt_int32_t timeo { rt_err_t result = RT_EOK; +#if (!defined(RT_USING_SERIAL_V2)) while (rt_device_read(client->device, 0, ch, 1) == 0) { result = rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)); @@ -551,8 +555,19 @@ static rt_err_t at_client_getchar(at_client_t client, char *ch, rt_int32_t timeo rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL); } +#else + rt_int32_t rx_timeout = rt_tick_from_millisecond(timeout); + rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout); + result = rt_device_read(client->device, 0, ch, 1); + if(result <= 0) + { + result = -RT_ERROR; + } + rx_timeout = RT_WAITING_FOREVER; + rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout); +#endif - return RT_EOK; + return result; } /** @@ -570,7 +585,7 @@ static rt_err_t at_client_getchar(at_client_t client, char *ch, rt_int32_t timeo */ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_int32_t timeout) { - rt_size_t len = 0; + rt_size_t read_idx = 0; RT_ASSERT(buf); @@ -580,16 +595,17 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_i return 0; } +#if (!defined(RT_USING_SERIAL_V2)) while (size) { rt_size_t read_len; rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL); - read_len = rt_device_read(client->device, 0, buf + len, size); + read_len = rt_device_read(client->device, 0, buf + read_idx, size); if (read_len > 0) { - len += read_len; + read_idx += read_len; size -= read_len; } else @@ -598,12 +614,19 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_i break; } } +#else + rt_int32_t rx_timeout = rt_tick_from_millisecond(timeout); + rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout); + read_idx = rt_device_read(client->device, 0, buf, size); + rx_timeout = RT_WAITING_FOREVER; + rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout); +#endif #ifdef AT_PRINT_RAW_CMD - at_print_raw_cmd("urc_recv", buf, len); + at_print_raw_cmd("urc_recv", buf, read_idx); #endif - return len; + return read_idx; } /** @@ -780,7 +803,8 @@ static int at_recv_readline(at_client_t client) } /* is newline or URC data */ - if ((client->urc = get_urc_obj(client)) != RT_NULL || (ch == '\n' && last_ch == '\r') + client->urc = get_urc_obj(client); + if (client->urc != RT_NULL || (ch == '\n' && last_ch == '\r') || (client->end_sign != 0 && ch == client->end_sign)) { if (is_full) @@ -877,6 +901,7 @@ static void client_parser(at_client_t client) } } +#if (!defined(RT_USING_SERIAL_V2)) static rt_err_t at_client_rx_ind(rt_device_t dev, rt_size_t size) { int idx = 0; @@ -891,6 +916,7 @@ static rt_err_t at_client_rx_ind(rt_device_t dev, rt_size_t size) return RT_EOK; } +#endif /* initialize the client object parameters */ static int at_client_para_init(at_client_t client) @@ -933,6 +959,7 @@ static int at_client_para_init(at_client_t client) goto __exit; } +#if (!defined(RT_USING_SERIAL_V2)) rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_SEM_NAME, at_client_num); client->rx_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO); if (client->rx_notice == RT_NULL) @@ -941,6 +968,7 @@ static int at_client_para_init(at_client_t client) result = -RT_ENOMEM; goto __exit; } +#endif rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_RESP_NAME, at_client_num); client->resp_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO); @@ -974,10 +1002,12 @@ static int at_client_para_init(at_client_t client) rt_mutex_delete(client->lock); } +#if (!defined(RT_USING_SERIAL_V2)) if (client->rx_notice) { rt_sem_delete(client->rx_notice); } +#endif if (client->resp_notice) { @@ -1055,12 +1085,8 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu if (client->device) { RT_ASSERT(client->device->type == RT_Device_Class_Char); - +#if (!defined(RT_USING_SERIAL_V2)) rt_device_set_rx_indicate(client->device, at_client_rx_ind); - -#ifdef RT_USING_SERIAL_V2 - open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING); -#else /* using DMA mode first */ open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -1068,8 +1094,11 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu { open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } -#endif /* RT_USING_SERIAL_V2 */ RT_ASSERT(open_result == RT_EOK); +#else + open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + RT_ASSERT(open_result == RT_EOK); +#endif } else { diff --git a/components/net/at/src/at_server.c b/components/net/at/src/at_server.c index 78173729483..fd549232583 100644 --- a/components/net/at/src/at_server.c +++ b/components/net/at/src/at_server.c @@ -8,6 +8,7 @@ * 2018-03-30 chenyong first version * 2018-04-14 chenyong modify parse arguments * 2025-01-02 dongly support SERIAL_V2 + * 2025-04-18 RyanCw support New SERIAL_V2 */ #include @@ -223,6 +224,7 @@ rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32 return 0; } +#if (!defined(RT_USING_SERIAL_V2)) while (1) { if (read_idx < size) @@ -242,6 +244,13 @@ rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32 break; } } +#else + rt_int32_t rx_timout = rt_tick_from_millisecond(timeout); + rt_device_control(server->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timout); + read_idx = rt_device_read(server->device, 0, buf, size); + rx_timeout = RT_WAITING_FOREVER; + rt_device_control(server->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout); +#endif return read_idx; } @@ -411,15 +420,27 @@ static rt_err_t at_server_getchar(at_server_t server, char *ch, rt_int32_t timeo { rt_err_t result = RT_EOK; +#if (!defined(RT_USING_SERIAL_V2)) while (rt_device_read(at_server_local->device, 0, ch, 1) == 0) { - rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL); result = rt_sem_take(at_server_local->rx_notice, rt_tick_from_millisecond(timeout)); if (result != RT_EOK) { return result; } + rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL); + } +#else + rt_int32_t rx_timout = rt_tick_from_millisecond(timeout); + rt_device_control(server->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timout); + result = rt_device_read(server->device, 0, ch, 1); + if(result <= 0) + { + result = -RT_ERROR; } + rx_timeout = RT_WAITING_FOREVER; + rt_device_control(server->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout); +#endif return result; } @@ -497,6 +518,7 @@ static void server_parser(at_server_t server) } } +#if (!defined(RT_USING_SERIAL_V2)) static rt_err_t at_rx_ind(rt_device_t dev, rt_size_t size) { if (size > 0) @@ -506,6 +528,7 @@ static rt_err_t at_rx_ind(rt_device_t dev, rt_size_t size) return RT_EOK; } +#endif #if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */ #pragma section="RtAtCmdTab" @@ -551,6 +574,7 @@ int at_server_init(void) rt_memset(at_server_local->recv_buffer, 0x00, AT_SERVER_RECV_BUFF_LEN); at_server_local->cur_recv_len = 0; +#if (!defined(RT_USING_SERIAL_V2)) at_server_local->rx_notice = rt_sem_create("at_svr", 0, RT_IPC_FLAG_FIFO); if (!at_server_local->rx_notice) { @@ -558,18 +582,15 @@ int at_server_init(void) result = -RT_ENOMEM; goto __exit; } +#endif /* Find and open command device */ at_server_local->device = rt_device_find(AT_SERVER_DEVICE); if (at_server_local->device) { RT_ASSERT(at_server_local->device->type == RT_Device_Class_Char); - +#if (!defined(RT_USING_SERIAL_V2)) rt_device_set_rx_indicate(at_server_local->device, at_rx_ind); - -#ifdef RT_USING_SERIAL_V2 - open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING); -#else /* using DMA mode first */ open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -577,8 +598,11 @@ int at_server_init(void) { open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } -#endif /* RT_USING_SERIAL_V2 */ RT_ASSERT(open_result == RT_EOK); +#else + open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + RT_ASSERT(open_result == RT_EOK); +#endif } else { @@ -614,10 +638,14 @@ int at_server_init(void) { if (at_server_local) { + +#if (!defined(RT_USING_SERIAL_V2)) if (at_server_local->rx_notice) { rt_sem_delete(at_server_local->rx_notice); } +#endif + if (at_server_local->device) { rt_device_close(at_server_local->device); diff --git a/examples/utest/testcases/drivers/serial_v2/Kconfig b/examples/utest/testcases/drivers/serial_v2/Kconfig index 3c8d480b3af..f00d7311ac5 100644 --- a/examples/utest/testcases/drivers/serial_v2/Kconfig +++ b/examples/utest/testcases/drivers/serial_v2/Kconfig @@ -1,7 +1,50 @@ menu "Utest Serial Testcase" -config UTEST_SERIAL_TC - bool "Serial testcase" - default n + config UTEST_SERIAL_TC + bool "Serial testcase" + default n + + if UTEST_SERIAL_TC + + config RT_SERIAL_TC_DEVICE_NAME + string "the device name for serial test" + default "uart2" + + config RT_SERIAL_TC_RXBUF_SIZE + int "the rx buffer size for serial test" + default 128 + + config RT_SERIAL_TC_TXBUF_SIZE + int "the tx buffer size for serial test" + default 128 + + config RT_SERIAL_TC_SEND_ITERATIONS + int "the number of iterations for the test routine." + default 100 + + config UTEST_SERIAL_QEMU_TC + bool "qemu dedicated tests" + default n + + config UTEST_SERIAL_POSIX_TC + bool "Serial posix testcase" + default n + select RT_USING_DFS + select RT_USING_POSIX_FS + select RT_USING_POSIX_TERMIOS + + if UTEST_SERIAL_POSIX_TC + + config RT_SERIAL_POSIX_TC_DEVICE_NAME + string "the device name for serial posix test" + default "dev/uart2" + + config RT_SERIAL_POSIX_TC_SEND_ITERATIONS + int "the number of iterations for the posix test routine." + default 100 + + endif + + endif endmenu diff --git a/examples/utest/testcases/drivers/serial_v2/README.md b/examples/utest/testcases/drivers/serial_v2/README.md index 3a6625f4bc0..1a94c20a01d 100644 --- a/examples/utest/testcases/drivers/serial_v2/README.md +++ b/examples/utest/testcases/drivers/serial_v2/README.md @@ -14,6 +14,14 @@ | uart_blocking_rx.c| 串口阻塞接收模式 的测试 | | uart_nonblocking_tx.c| 串口非阻塞发送模式 的测试 | | uart_nonblocking_rx.c | 串口非阻塞接收模式 的测试 | +| uart_flush_rx | 刷新接收缓冲区的测试 | +| uart_flush_txb | 阻塞模式下刷新发送缓冲区的测试 | +| uart_flush_txnb | 非阻塞模式下刷新发送缓冲区的测试 | +| uart_timeout_rxb_txb | 串口 发送 / 接收 超时的测试 | +| uart_overflow_rxb_txb | 串口溢出处理的测试 | +| uart_get_unread_bytes_count | 获取串口接收缓冲区中的数据长度的测试 | +| uart_posix_nonblock | posix非阻塞测试 | +| uart_posix_echo_block | posix阻塞echo测试 | ## 3、软硬件环境 @@ -77,37 +85,20 @@ 需要解释的是,为什么会存在无意义的组合模式,举个例子,非阻塞模式下,肯定是不会出现POLL(轮询)方式的,因为POLL方式已经表明是阻塞方式了。 该测试用例在测试多种组合时,需要通过更改`rtconfig.h`文件对硬件模式进行静态配置。 -### 4.2 测试思路 +### 4.2 测试条件 -前四个测试用例的测试思路: +**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。 ->硬件上:**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。 -> ->软件上:创建两个线程A和B,A为接收线程,B为发送线程,设置A线程优先级比B线程优先级高。发送线程发送随机长度(长度范围是 0 到 1000)的数据,接收线程接收到数据进行校验,数据正确则测试通过,默认测试100次。 - -后四个测试用例的测试思路: +大致的测试思路: ->硬件上: **不需要将TX,RX引脚进行短接**,每次只针对发送或接收中的一种进行测试,更为简单与直接 -> ->软件上: 四个样例每次仅测试TX/RX中的一种引脚与一种对应的阻塞/非阻塞模式 ->四种测试模式具体分为: ->>阻塞接收模式----(硬件工作模式可选: 轮询, 中断, DMA) ->>阻塞发送模式----(硬件工作模式可选: 轮询, 中断, DMA) ->>非阻塞接收模式--(硬件工作模式可选: 中断, DMA) ->>非阻塞发送模式--(硬件工作模式可选: 中断, DMA) -> ->其中阻塞或非阻塞背后的具体硬件工作模式选择(如 轮询, 中断, DMA)需要对`rtconfig.h`文件做出配置,具体配置流程可见文章中关于 - [seril_v2硬件工作模式的选择](https://club.rt-thread.org/ask/article/b4c536303c8e2335.html "serial_v2源码分析")一节. -> >发送测试流程 : >>1. 先关闭串口,再以需要测试的模式打开. ->>2. 然后依次发送 UART_SEND_TIMES(默认为400) * 1024, 8, 32, 128, 512, 1024个数据. ->>3. 发送的同时记录每次发送所耗费的时钟周期与成功发送的数据数量. ->>3. 打印记录的数据,通过时钟周期来反应发送效率, 通过成功发送的数据量来反应是否产生丢包问题. +>>2. 然后依次发送 UART_SEND_TIMES * (1000以内的随机数)个数据. +>>3. 打印记录的数据,通过LOG日志的时钟周期来反应发送效率, 通过成功发送的数据量来反应是否产生丢包问题. > >接收测试流程 : >>1. 先关闭串口,再以需要测试的模式打开. ->>2. 然后以此接收 256, 256, 256, 128, 128, 共计1024个数据 +>>2. 然后以此接收 同发送测试流程一致的 UART_SEND_TIMES *(1000以内随机数)个数据 >>3. 接收的同时记录成功接收的数据数量 >>4. 打印记录的数据, 通过现实成功接收的数据量与串口发送的数据量做对比,来验证是否出现丢包问题 @@ -119,7 +110,14 @@ RT-Thread Utestcases ---> [*] RT-Thread Utestcases ---> Utest Serial Testcase ---> - [*] Serial testcase + [*] Serial testcase ---> + the device name for serial test: uart2 (选择测试的串口) + (128)the rx buffer size for serial test (测试串口rx缓冲区大小) + (128)the tx buffer size for serial test (测试串口tx缓冲区大小) + (100)the number of iterations for the test routine. (测试例程的迭代次数) + [*] Serial posix testcase ---> + the device name for serial posix test: dev/uart2 (posix测试的串口) + (100)the number of iterations for the posix test routine. (posix测试例程的迭代次数) ``` ## 6、使用 @@ -140,9 +138,9 @@ RT-Thread Utestcases ---> \- 在 MSH 中输入 `utest_run testcases.drivers.uart_nonblocking_tx` 运行串口非阻塞发送测试 -\- 在 MSH 中输入 `utest_run testcases.drivers.uart_nonblocking_rx` 运行串口非阻塞接收测试 +其余同理,可在函数内部查看命令。 -如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run` 运行即可将上述测试用例按序测试。 +如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run *` 运行即可将上述测试用例按序测试。 ## 7、注意事项 @@ -152,7 +150,5 @@ RT-Thread Utestcases ---> \- 需在 MSH 中输入正确的命令行。 -\- 测试用例默认的测试数据长度范围最大为1000字节,如果接收端的缓冲区大小配置为小于1000字节时,那么在测试接收阻塞模式时,将会由于获取不了1000字节长度导致线程持续阻塞(因为测试用例是按 `recv_len` 长度去接收的,而不是按照单字节去接收的),因此建议接收端的缓冲区大小 (对应宏例如为 `BSP_UART2_RX_BUFSIZE`)设置为1024即可;当然也可按需减小测试的最大数据长度。 - \- 该测试用例需要结合硬件具体的工作模式(POLL 、INT、DMA)进行测试,而硬件工作模式只能选择一种,因此需要在 `rtconfig.h` 中对串口相应的宏进行配置,来选择不同的工作模式去进行测试。 diff --git a/examples/utest/testcases/drivers/serial_v2/SConscript b/examples/utest/testcases/drivers/serial_v2/SConscript index a7438e3a32d..7ef99d20b7d 100644 --- a/examples/utest/testcases/drivers/serial_v2/SConscript +++ b/examples/utest/testcases/drivers/serial_v2/SConscript @@ -2,19 +2,17 @@ Import('rtconfig') from building import * cwd = GetCurrentDir() -src = Split(''' -uart_rxb_txnb.c -uart_rxb_txb.c -uart_rxnb_txb.c -uart_rxnb_txnb.c -uart_blocking_rx.c -uart_blocking_tx.c -uart_nonblocking_rx.c -uart_nonblocking_tx.c -''') +src = Glob('*.c') -CPPPATH = [cwd] +path = [cwd] -group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = CPPPATH) +if GetDepend(['UTEST_SERIAL_POSIX_TC']): + src += Glob('posix/*.c') + +if GetDepend(['UTEST_SERIAL_QEMU_TC']): + src += Glob('qemu/*.c') + +group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = path) Return('group') + diff --git a/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c new file mode 100644 index 00000000000..1a0a8ec1eec --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include +#include +#include +#include +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static int32_t serial_fd; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial_fd = open(RT_SERIAL_POSIX_TC_DEVICE_NAME, O_RDWR); + if (serial_fd == -1) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t configureSerial(int fd, int baud) +{ + int32_t result = 0; + struct termios options; + + result = tcgetattr(fd, &options); // 获取当前端口的属性 + if (result == -1) + return -RT_ERROR; + + // 设置波特率 + result = cfsetispeed(&options, baud); // 设置输入波特率 + if (result == -1) + return -RT_ERROR; + + result = cfsetospeed(&options, baud); // 设置输出波特率 + if (result == -1) + return -RT_ERROR; + + // 设置数据位 + options.c_cflag &= ~PARENB; // 清除校验位,无校验 + options.c_cflag &= ~CSTOPB; // 仅一个停止位 + options.c_cflag &= ~CSIZE; // 清除掩码 + options.c_cflag |= CS8; // 8位数据 + + // 设置无流控 + options.c_cflag &= ~CRTSCTS; // 不使用硬件流控制 + options.c_iflag &= ~(IXON | IXOFF | IXANY); // 不使用软件流控制 + + // 使能接收器和发送器 + options.c_cflag |= CLOCAL | CREAD; + + // 设置行终止符 + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + // 应用属性 + result = tcsetattr(fd, TCSANOW, &options); + if (result == -1) + return -RT_ERROR; + + return RT_EOK; +} + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_uint16_t send_len; + + rt_uint32_t i = 0; + send_len = *(rt_uint16_t *)parameter; + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + if (write(serial_fd, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint16_t rev_len; + + rev_len = *(rt_uint16_t *)parameter; + rt_uint8_t *uart_write_buffer; + uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; + rt_uint32_t all_receive_length = 0; + + while (1) + { + cnt = read(serial_fd, (void *)uart_write_buffer, rev_len); + if (cnt == 0) + { + continue; + } + + if (fisrt_flag != RT_TRUE) + { + if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0]) + { + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]); + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + } + else + { + fisrt_flag = RT_FALSE; + } + + for (i = 0; i < cnt - 1; i++) + { + if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1]) + { + LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]); + + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + } + all_receive_length += cnt; + if (all_receive_length >= rev_len) + break; + else + last_old_data = uart_write_buffer[cnt - 1]; + } + rt_free(uart_write_buffer); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint16_t length) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + int flags = 0; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + result = configureSerial(serial_fd, B115200); + if (result == -1) + { + goto __exit; + } + + + flags = fcntl(serial_fd, F_GETFL, 0); + if (flags == -1) + { + goto __exit; + } + + result = fcntl(serial_fd, F_SETFL, flags & ~O_NONBLOCK); + if (result == -1) + { + goto __exit; + } + + + thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); + if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) + { + rt_thread_startup(thread_send); + rt_thread_startup(thread_recv); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } + +__exit: + rt_thread_mdelay(5); + close(serial_fd); + uart_over_flag = RT_FALSE; + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t times = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + + while (RT_SERIAL_POSIX_TC_SEND_ITERATIONS - times) + { + num = (rand() % 1000) + 1; + if (uart_api(num) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] times testing.", num, ++times); + else + { + LOG_E("uart test error"); + break; + } + } + +__exit: + uassert_true(uart_result == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + close(serial_fd); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_posix_echo_block", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c new file mode 100644 index 00000000000..3159f2d6cd9 --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-06-16 KyleChan the first version + */ + +#include +#include "utest.h" +#include +#include +#include +#include +#include +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static int32_t serial_fd; + +static rt_err_t uart_find(void) +{ + serial_fd = open(RT_SERIAL_POSIX_TC_DEVICE_NAME, O_RDWR); + if (serial_fd == -1) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t configureSerial(int fd, int baud) +{ + int32_t result = 0; + struct termios options; + + result = tcgetattr(fd, &options); // 获取当前端口的属性 + if (result == -1) + return -RT_ERROR; + + // 设置波特率 + result = cfsetispeed(&options, baud); // 设置输入波特率 + if (result == -1) + return -RT_ERROR; + + result = cfsetospeed(&options, baud); // 设置输出波特率 + if (result == -1) + return -RT_ERROR; + + // 设置数据位 + options.c_cflag &= ~PARENB; // 清除校验位,无校验 + options.c_cflag &= ~CSTOPB; // 仅一个停止位 + options.c_cflag &= ~CSIZE; // 清除掩码 + options.c_cflag |= CS8; // 8位数据 + + // 设置无流控 + options.c_cflag &= ~CRTSCTS; // 不使用硬件流控制 + options.c_iflag &= ~(IXON | IXOFF | IXANY); // 不使用软件流控制 + + // 使能接收器和发送器 + options.c_cflag |= CLOCAL | CREAD; + + // 设置行终止符 + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + // 应用属性 + result = tcsetattr(fd, TCSANOW, &options); + if (result == -1) + return -RT_ERROR; + + return RT_EOK; +} + +static rt_err_t uart_api() +{ + rt_err_t result = RT_EOK; + rt_uint8_t *uart_write_buffer; + rt_int32_t cnt, i, send_size; + int flags = 0; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + result = configureSerial(serial_fd, B115200); + if (result == -1) + { + goto __exit; + } + + flags = fcntl(serial_fd, F_GETFL, 0); + if (flags == -1) + { + goto __exit; + } + + result = fcntl(serial_fd, F_SETFL, flags | O_NONBLOCK); + if (result == -1) + { + goto __exit; + } + + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * 100); + + for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++) + { + send_size = 1; + cnt = write(serial_fd, uart_write_buffer, send_size); + if (cnt != send_size) + { + result = -RT_ERROR; + goto __exit; + } + + rt_thread_mdelay(2); + cnt = read(serial_fd, (void *)uart_write_buffer, send_size); + if (cnt != send_size) + { + result = -RT_ERROR; + goto __exit; + } + + send_size = rand() % 30 + 1; + cnt = write(serial_fd, uart_write_buffer, send_size); + if (cnt != send_size) + { + LOG_E("uart write failed %d %d", cnt, send_size); + result = -RT_ERROR; + goto __exit; + } + + rt_thread_mdelay(send_size * 0.0868 + 5); + cnt = read(serial_fd, (void *)uart_write_buffer, send_size + 1); + if (cnt != send_size) + { + LOG_E("uart read failed %d %d", cnt, send_size); + result = -RT_ERROR; + goto __exit; + } + } + +__exit: + rt_thread_mdelay(5); + if (uart_write_buffer) + rt_free(uart_write_buffer); + close(serial_fd); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + close(serial_fd); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_posix_nonblock", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c b/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c new file mode 100644 index 00000000000..5fdaa97793e --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c @@ -0,0 +1,171 @@ +#include +#include +#include "utest.h" + +#define UART_SEND_TIMES 100 +#define UART_TEST_NUMBER 6 + + +#ifdef UTEST_SERIAL_TC +#define echo_test_buffer_size (1024) + +static rt_device_t u1serial; +static rt_device_t u2serial; + +static rt_uint32_t u2rx_length = 0; +static rt_uint32_t u2tx_length = 0; + +static rt_uint32_t u1rx_length = 0; +static rt_uint32_t u1tx_length = 0; + +static rt_uint8_t uart_over_flag = RT_FALSE; + +static void echo_test_u2_thread_entry(void *parameter) +{ + char *uart_name = "uart2"; + + u2serial = rt_device_find(uart_name); + if (!u2serial) + { + LOG_I("find %s failed!\n", uart_name); + return; + } + + rt_uint8_t *rx_buffer = rt_malloc(echo_test_buffer_size); + + rt_device_open(u2serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + + rt_ssize_t buf_datalen = 0; + while (1) + { + rt_device_control(u2serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen); + int32_t recbLen = rt_device_read(u2serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1); + if (recbLen > 0) + { + u2rx_length += recbLen; + u2tx_length += rt_device_write(u2serial, 0, rx_buffer, recbLen); + + if (uart_over_flag) + break; + } + } + rt_free(rx_buffer); +} + +static void echo_test_u1_thread_entry(void *parameter) +{ + rt_uint8_t *rx_buffer = rt_malloc(echo_test_buffer_size); + rt_ssize_t buf_datalen = 0; + while (1) + { + rt_device_control(u1serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen); + int32_t recbLen = rt_device_read(u1serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1); + if (recbLen > 0) + { + u1rx_length += recbLen; + if (uart_over_flag) + break; + } + } + + rt_free(rx_buffer); +} + + +static rt_bool_t echo_test() +{ + rt_bool_t result = RT_TRUE; + char *uart_name = "uart1"; + u1serial = rt_device_find(uart_name); + if (!u1serial) + { + LOG_I("find %s failed!\n", uart_name); + return RT_FALSE; + } + + rt_uint8_t *tx_buffer = rt_malloc(echo_test_buffer_size); + + rt_device_open(u1serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_thread_startup(rt_thread_create("serial2", echo_test_u2_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 4, 5)); + rt_thread_startup(rt_thread_create("serial1", echo_test_u1_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 5, 5)); + + uint32_t sendTotalCount = 0; + srand(rt_tick_get()); + for (uint32_t count = 0; count < 1000; count++) + { + // Indefinite length of data is sent + uint32_t sendCount = rand() % echo_test_buffer_size; + + + u1tx_length += rt_device_write(u1serial, 0, tx_buffer, sendCount); + sendTotalCount += sendCount; + + // Wait for the cross-send to complete + rt_thread_mdelay(UART_SEND_TIMES); + + if (count % 50 == 0) + { + LOG_I("echo, uart2: tx: %ld, rx: %ld", u2tx_length, u2rx_length); + LOG_I("echo, uart1: tx: %ld, rx: %ld", u1tx_length, u1rx_length); + if (u2tx_length != u2rx_length || u1tx_length != u1rx_length || u2tx_length != u1tx_length) + { + LOG_I("echo test error!!!"); + result = RT_FALSE; + break; + } + + if (u2tx_length != sendTotalCount) + { + LOG_I("u2tx_length != sendTotalCount echo test error!!!"); + result = RT_FALSE; + break; + } + } + } + + uart_over_flag = RT_TRUE; + // Notify the thread to exit + rt_device_write(u1serial, 0, tx_buffer, echo_test_buffer_size); + rt_thread_mdelay(30); + + { + rt_device_t uart_dev = rt_device_find("uart2"); + while (rt_device_close(uart_dev) != -RT_ERROR); + } + { + rt_device_t uart_dev = rt_device_find("uart1"); + while (rt_device_close(uart_dev) != -RT_ERROR); + } + rt_free(tx_buffer); + return result; +} + +static void uart_test_nonblocking_tx(void) +{ + uassert_true(echo_test()); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + u1serial = RT_NULL; + u2serial = RT_NULL; + u2rx_length = 0; + u2tx_length = 0; + u1rx_length = 0; + u1tx_length = 0; + uart_over_flag = RT_FALSE; + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(uart_test_nonblocking_tx); +} +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_qemu_echo", utest_tc_init, utest_tc_cleanup, 10); + +#endif diff --git a/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c index 2beb9e6fd94..432181c0318 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c @@ -2,53 +2,51 @@ #include #include "utest.h" -#define SERIAL_UART_NAME "uart2" - #ifdef UTEST_SERIAL_TC static rt_bool_t block_read(rt_device_t uart_dev) { rt_size_t total_length, recv_length; - rt_uint8_t uart_read_buffer[1024], log_buffer[64]; + char uart_read_buffer[1024], log_buffer[64]; /* make sure device is closed and reopen it */ - while(rt_device_close(uart_dev) != -RT_ERROR); + while (rt_device_close(uart_dev) != -RT_ERROR); rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_RX_BLOCKING); rt_sprintf(log_buffer, "\nBLOCKING READ BEGIN, PLEASE SEND SOME DATAS\n"); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); - total_length = 0; - recv_length = 0; - recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); + total_length = 0; + recv_length = 0; + recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer)); total_length += recv_length; rt_sprintf(log_buffer, "\nblock : %d bytes read, total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); - recv_length = 0; - recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); + recv_length = 0; + recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer)); total_length += recv_length; rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); - recv_length = 0; - recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); + recv_length = 0; + recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer)); total_length += recv_length; rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); - recv_length = 0; - recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128); + recv_length = 0; + recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer)); total_length += recv_length; rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); - recv_length = 0; - recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128); + recv_length = 0; + recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer)); total_length += recv_length; rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length); @@ -64,10 +62,10 @@ static rt_bool_t block_read(rt_device_t uart_dev) static void uart_test_blocking_rx(void) { rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); + uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); uassert_not_null(uart_dev); - uassert_true (block_read(uart_dev)); + uassert_true(block_read(uart_dev)); } static rt_err_t utest_tc_init(void) @@ -77,10 +75,8 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); - while(rt_device_close(uart_dev) != -RT_ERROR); - rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c b/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c index a3653079c13..a5893536ed4 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c @@ -2,82 +2,85 @@ #include #include "utest.h" -#define SERIAL_UART_NAME "uart2" -#define UART_SEND_TIMES 400 +#define UART_SEND_TIMES 100 #define UART_TEST_NUMBER 6 + #ifdef UTEST_SERIAL_TC static rt_bool_t block_write(rt_device_t uart_dev) { rt_size_t i, wr_sz, index, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER]; rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER]; - rt_uint8_t uart_write_buffer[1024]; + char uart_write_buffer[1024]; for (i = 0; i < 1024; i++) uart_write_buffer[i] = '0' + (i % 49); /* make sure device is closed and reopen it */ - while(rt_device_close(uart_dev) != -RT_ERROR); + while (rt_device_close(uart_dev) != -RT_ERROR); rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING); LOG_D("\nBLOCKING WRITE BEGIN\n"); - rt_thread_mdelay(2000); index = 0; wr_sz = 0; tick1 = rt_tick_get(); - for(i = 0; i < UART_SEND_TIMES; i++) + for (i = 0; i < UART_SEND_TIMES; i++) wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 1024); - tick2 = rt_tick_get(); - total_write_num[index] = UART_SEND_TIMES * 1024; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + total_write_num[index] = UART_SEND_TIMES * 1024; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - wr_sz = 0; - tick1 = rt_tick_get(); + wr_sz = 0; + tick1 = rt_tick_get(); wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 8); - tick2 = rt_tick_get(); - total_write_num[index] = 8; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + + total_write_num[index] = 8; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - wr_sz = 0; - tick1 = rt_tick_get(); + wr_sz = 0; + tick1 = rt_tick_get(); wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 32); - tick2 = rt_tick_get(); - total_write_num[index] = 32; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + + total_write_num[index] = 32; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - wr_sz = 0; - tick1 = rt_tick_get(); + wr_sz = 0; + tick1 = rt_tick_get(); wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 128); - tick2 = rt_tick_get(); - total_write_num[index] = 128; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + + total_write_num[index] = 128; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - wr_sz = 0; - tick1 = rt_tick_get(); + wr_sz = 0; + tick1 = rt_tick_get(); wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 512); - tick2 = rt_tick_get(); - total_write_num[index] = 512; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + + total_write_num[index] = 512; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - wr_sz = 0; - tick1 = rt_tick_get(); + wr_sz = 0; + tick1 = rt_tick_get(); wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 1024); - tick2 = rt_tick_get(); - total_write_num[index] = 1024; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + + total_write_num[index] = 1024; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - rt_thread_mdelay(1000); LOG_D("\nBLOCKING_TX END\n"); - for(i = 0; i < index; i++) + for (i = 0; i < index; i++) { LOG_D("\nBLOCKING_MODE : write %d / %d bytes in %d ticks\n", write_num_array[i], total_write_num[i], tick_array[i]); rt_thread_mdelay(1000); @@ -89,10 +92,10 @@ static rt_bool_t block_write(rt_device_t uart_dev) static void uart_test_blocking_tx(void) { rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); + uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); uassert_not_null(uart_dev); - uassert_true (block_write(uart_dev)); + uassert_true(block_write(uart_dev)); } static rt_err_t utest_tc_init(void) @@ -102,10 +105,8 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); - while(rt_device_close(uart_dev) != -RT_ERROR); - rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c new file mode 100644 index 00000000000..7411eeaa84a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size) +{ + rt_device_write(&serial->parent, 0, uart_write_buffer, size); + rt_thread_mdelay(size * 0.0868 + 5); + if (1 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1)) + { + LOG_E("read failed."); + return -RT_ERROR; + } + + rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL); + if (0 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1)) + { + LOG_E("read failed."); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_bool_t uart_api() +{ + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return RT_FALSE; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + return RT_FALSE; + } + + rt_uint8_t *uart_write_buffer; + rt_uint32_t i; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 1)); + + srand(rt_tick_get()); + for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++) + { + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5))) + { + LOG_E("test_item failed."); + result = -RT_ERROR; + goto __exit; + } + + if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5))) + { + LOG_E("test_item failed."); + result = -RT_ERROR; + goto __exit; + } + } + +__exit: + rt_free(uart_write_buffer); + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_rx", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c new file mode 100644 index 00000000000..567fe3740aa --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size) +{ + rt_uint32_t old_tick; + rt_tick_t tick_diff; + rt_tick_t expect_time = send_size * 0.0868; + + /* In interrupt mode, ticks may be inaccurate; compensation should be applied*/ + if (send_size > 384) + { + expect_time -= send_size / 384; + } + + old_tick = rt_tick_get(); + rt_device_write(&serial->parent, 0, uart_write_buffer, send_size); + rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL); + tick_diff = rt_tick_get() - old_tick; + + if (tick_diff < expect_time || tick_diff > expect_time + 10) + { + LOG_E("send_size [%4d], time required for TXB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time); + return -RT_ERROR; + } + else + { + LOG_I("send_size [%4d], time required for TXB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time); + } + + return RT_EOK; +} + +static rt_bool_t uart_api() +{ + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return RT_FALSE; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE * 5 + 10; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + return RT_FALSE; + } + + rt_uint8_t *uart_write_buffer; + rt_uint32_t i; + rt_int32_t tx_timeout = 1; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 10)); + + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout); + + srand(rt_tick_get()); + for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++) + { + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_TXBUF_SIZE * (rand() % 6))) + { + result = -RT_ERROR; + goto __exit; + } + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_TXBUF_SIZE * (rand() % 6) + 1)) + { + result = -RT_ERROR; + goto __exit; + } + + if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_TXBUF_SIZE * 5))) + { + result = -RT_ERROR; + goto __exit; + } + } + +__exit: + rt_free(uart_write_buffer); + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c new file mode 100644 index 00000000000..aa086a8679e --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size) +{ + rt_uint32_t old_tick; + rt_tick_t tick_diff; + rt_tick_t expect_time = send_size * 0.0868; + + /* In interrupt mode, ticks may be inaccurate; compensation should be applied */ + if (send_size > 384) + { + expect_time -= send_size / 384; + } + + old_tick = rt_tick_get(); + rt_uint32_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size); + rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL); + tick_diff = rt_tick_get() - old_tick; + if (tick_diff < expect_time) + { + LOG_E("send_size [%4d], time required for TXNB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time); + return -RT_ERROR; + } + else + { + LOG_I("send_size [%4d], time required for TXNB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time); + } + + return RT_EOK; +} + +static rt_bool_t uart_api() +{ + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return RT_FALSE; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_RXBUF_SIZE * 5 + 10; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + return RT_FALSE; + } + + rt_uint8_t *uart_write_buffer; + rt_uint32_t i; + rt_int32_t tx_timeout = 1; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_RXBUF_SIZE * 5 + 10)); + + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout); + + srand(rt_tick_get()); + for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++) + { + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * (rand() % 6))) + { + result = -RT_ERROR; + goto __exit; + } + + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * (rand() % 6) + 1)) + { + result = -RT_ERROR; + goto __exit; + } + + if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5))) + { + result = -RT_ERROR; + goto __exit; + } + } + +__exit: + rt_free(uart_write_buffer); + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_txnb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c b/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c new file mode 100644 index 00000000000..fc4323cc98d --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + +/* */ + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; +static rt_uint8_t uart_over_flag = RT_FALSE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size) +{ + rt_uint32_t old_tick; + rt_ssize_t send_len; + rt_ssize_t buf_data_len; + + send_len = rt_device_write(&serial->parent, 0, uart_write_buffer, size); + if (size > RT_SERIAL_TC_RXBUF_SIZE) + { + size = RT_SERIAL_TC_RXBUF_SIZE; + } + + rt_thread_delay(5); + rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len); + if (size != buf_data_len) + { + return -RT_ERROR; + } + + rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL); + + rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len); + if (0 != buf_data_len) + { + return -RT_ERROR; + } + + return RT_EOK; +} + +static rt_bool_t uart_api() +{ + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return RT_FALSE; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + return RT_FALSE; + } + + rt_uint8_t *uart_write_buffer; + rt_uint32_t i; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 1)); + + srand(rt_tick_get()); + for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++) + { + if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5))) + { + result = -RT_ERROR; + goto __exit; + } + + if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5))) + { + result = -RT_ERROR; + goto __exit; + } + } + + +__exit: + rt_free(uart_write_buffer); + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_get_unread_bytes_count", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c index 72b5e1e332f..d67a5d17aed 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c @@ -2,17 +2,15 @@ #include #include "utest.h" -#define SERIAL_UART_NAME "uart2" - #ifdef UTEST_SERIAL_TC static rt_bool_t nonblock_read(rt_device_t uart_dev) { rt_size_t total_length, recv_length; - rt_uint8_t uart_read_buffer[1024], log_buffer[64]; + char uart_read_buffer[1024], log_buffer[64]; /* make sure device is closed and reopen it */ - while(rt_device_close(uart_dev) != -RT_ERROR); + while (rt_device_close(uart_dev) != -RT_ERROR); rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING); rt_sprintf(log_buffer, "\nNONBLOCKING READ BEGIN, PLEASE SEND SOME DATAS\n"); @@ -22,9 +20,8 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev) rt_device_write(uart_dev, 0, "5\n", 2); recv_length = 0; recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); - rt_device_write(uart_dev, 0, uart_read_buffer, 256); + rt_device_write(uart_dev, 0, uart_read_buffer, 256); total_length += recv_length; - rt_thread_mdelay(1000); rt_sprintf(log_buffer, "\nnonblock : %d bytes read, total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); @@ -34,29 +31,26 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev) recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); rt_device_write(uart_dev, 0, uart_read_buffer, 256); total_length += recv_length; - rt_thread_mdelay(1000); - rt_sprintf(log_buffer,"\nnonblock : %d bytes read , total: %d \n", recv_length, total_length); - rt_device_write(uart_dev,0,log_buffer, rt_strlen(log_buffer)); + rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length); + rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); rt_device_write(uart_dev, 0, "3\n", 2); recv_length = 0; recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256); rt_device_write(uart_dev, 0, uart_read_buffer, 256); total_length += recv_length; - rt_thread_mdelay(1000); rt_sprintf(log_buffer, "\nnonblock : %d bytes read, total: %d \n", recv_length, total_length); - rt_device_write(uart_dev,0,log_buffer, rt_strlen(log_buffer)); + rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); rt_device_write(uart_dev, 0, "2\n", 2); recv_length = 0; recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128); rt_device_write(uart_dev, 0, uart_read_buffer, 128); total_length += recv_length; - rt_thread_mdelay(1000); - rt_sprintf(log_buffer,"\nnonblock : %d bytes read , total: %d \n", recv_length, total_length); + rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); rt_device_write(uart_dev, 0, "1\n", 2); @@ -64,7 +58,6 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev) recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128); rt_device_write(uart_dev, 0, uart_read_buffer, 128); total_length += recv_length; - rt_thread_mdelay(1000); rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length); rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer)); @@ -78,10 +71,10 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev) static void uart_test_nonblocking_rx(void) { rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); + uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); uassert_not_null(uart_dev); - uassert_true (nonblock_read(uart_dev)); + uassert_true(nonblock_read(uart_dev)); } static rt_err_t utest_tc_init(void) @@ -91,10 +84,8 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); - while(rt_device_close(uart_dev) != -RT_ERROR); - rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c index eb88abceb43..7723ef56b14 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c @@ -2,92 +2,90 @@ #include #include "utest.h" -#define SERIAL_UART_NAME "uart2" -#define UART_SEND_TIMES 400 +#define UART_SEND_TIMES 100 #define UART_TEST_NUMBER 6 + #ifdef UTEST_SERIAL_TC static rt_bool_t nonblock_write(rt_device_t uart_dev) { - rt_size_t wr_sz = 0, tmp = 0, i, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER], index; - rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER]; + rt_size_t wr_sz = 0, tmp = 0, i, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER], index; + rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER]; rt_uint8_t uart_write_buffer[1024]; for (i = 0; i < 1024; i++) uart_write_buffer[i] = '0' + (i % 50); /* make sure device is closed and reopen it */ - while(rt_device_close(uart_dev) != -RT_ERROR); - uart_dev = rt_device_find(SERIAL_UART_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_NON_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING); LOG_D("\nNONBLOCKING WRITE BEGIN\n"); - rt_thread_mdelay(2000); index = 0; - tmp = 0; + tmp = 0; tick1 = rt_tick_get(); for (i = 0; i < UART_SEND_TIMES; i++) { wr_sz = 0; - while(wr_sz < 1024) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024-wr_sz); + while (wr_sz < 1024) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024 - wr_sz); tmp += wr_sz; } - tick2 = rt_tick_get(); - total_write_num[index] = UART_SEND_TIMES * 1024; - tick_array[index] = tick2 - tick1; + tick2 = rt_tick_get(); + total_write_num[index] = UART_SEND_TIMES * 1024; + tick_array[index] = tick2 - tick1; write_num_array[index++] = tmp; wr_sz = 0; tick1 = rt_tick_get(); - while(wr_sz < 8) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 8-wr_sz); - tick2 = rt_tick_get(); - total_write_num[index] = 8; - tick_array[index] = tick2 - tick1; + while (wr_sz < 8) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 8 - wr_sz); + tick2 = rt_tick_get(); + total_write_num[index] = 8; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; wr_sz = 0; tick1 = rt_tick_get(); - while(wr_sz < 32) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 32-wr_sz); - tick2 = rt_tick_get(); - total_write_num[index] = 32; - tick_array[index] = tick2 - tick1; + while (wr_sz < 32) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 32 - wr_sz); + tick2 = rt_tick_get(); + total_write_num[index] = 32; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; wr_sz = 0; tick1 = rt_tick_get(); - while(wr_sz < 128) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 128-wr_sz); - tick2 = rt_tick_get(); - total_write_num[index] = 128; - tick_array[index] = tick2 - tick1; + while (wr_sz < 128) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 128 - wr_sz); + tick2 = rt_tick_get(); + total_write_num[index] = 128; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; wr_sz = 0; tick1 = rt_tick_get(); - while(wr_sz < 512) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 512-wr_sz); - tick2 = rt_tick_get(); - total_write_num[index] = 512; - tick_array[index] = tick2 - tick1; + while (wr_sz < 512) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 512 - wr_sz); + tick2 = rt_tick_get(); + total_write_num[index] = 512; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; wr_sz = 0; tick1 = rt_tick_get(); - while(wr_sz < 1024) - wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024-wr_sz); - tick2 = rt_tick_get(); - total_write_num[index] = 1024; - tick_array[index] = tick2 - tick1; + while (wr_sz < 1024) + wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024 - wr_sz); + tick2 = rt_tick_get(); + total_write_num[index] = 1024; + tick_array[index] = tick2 - tick1; write_num_array[index++] = wr_sz; - rt_thread_mdelay(1000); LOG_D("\nNONBLOCKING_TX END\n"); - for(i = 0; i < index; i++) + for (i = 0; i < index; i++) { LOG_D("\nNONBLOCKING_MODE : write %d / %d bytes in %d ticks\n", write_num_array[i], total_write_num[i], tick_array[i]); rt_thread_mdelay(1000); @@ -99,10 +97,10 @@ static rt_bool_t nonblock_write(rt_device_t uart_dev) static void uart_test_nonblocking_tx(void) { rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); + uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); uassert_not_null(uart_dev); - uassert_true (nonblock_write(uart_dev)); + uassert_true(nonblock_write(uart_dev)); } static rt_err_t utest_tc_init(void) @@ -112,10 +110,8 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - rt_device_t uart_dev; - uart_dev = rt_device_find(SERIAL_UART_NAME); - while(rt_device_close(uart_dev) != -RT_ERROR); - rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c new file mode 100644 index 00000000000..912d1ecd7cb --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; +static rt_uint8_t uart_over_flag = RT_FALSE; +static rt_bool_t uart_result = RT_TRUE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + + +static void uart_send_entry(void *parameter) +{ + rt_uint32_t send_len; + rt_uint8_t *uart_write_buffer = RT_NULL; + rt_uint32_t i = 0; + send_len = *(rt_uint32_t *)parameter; + + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + rt_memset(uart_write_buffer, 0, send_len); + + for (i = 0; i < send_len; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + /* send buffer */ + if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len) + { + LOG_E("device write failed\r\n"); + } + rt_free(uart_write_buffer); +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint32_t rev_len; + rt_uint8_t *uart_write_buffer; + rt_int32_t cnt, i; + rev_len = *(rt_uint32_t *)parameter; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (rev_len + 1)); + + while (1) + { + cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE); + if (cnt != RT_SERIAL_TC_RXBUF_SIZE) + { + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + +#ifdef RT_SERIAL_BUF_STRATEGY_DROP + for (i = 0; i < cnt; i++) + { + if (uart_write_buffer[i] != i) + { + LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], i); + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + } +#else + for (i = cnt - 1; i >= 0; i--) + { + if (uart_write_buffer[i] != ((rev_len - (cnt - i)) % (UINT8_MAX + 1))) + { + LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], ((rev_len - (cnt - i)) % (UINT8_MAX + 1))); + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + } +#endif /* RT_SERIAL_BUF_STRATEGY_DROP */ + break; + } + rt_free(uart_write_buffer); + uart_over_flag = RT_TRUE; +} + +static rt_err_t uart_api(rt_uint32_t length) +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; + + result = uart_find(); + if (result != RT_EOK) + { + return -RT_ERROR; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + uart_result = RT_FALSE; + return -RT_ERROR; + } + + rt_int32_t timeout = 5000; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + + thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 4, 10); + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 5, 10); + if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) + { + rt_thread_startup(thread_send); + /* waiting for data transmission to complete*/ + rt_thread_mdelay(length * 0.0868 + 10); + rt_thread_startup(thread_recv); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } +__exit: + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result; +} + +static void tc_uart_api(void) +{ + rt_uint32_t count = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + srand(rt_tick_get()); + while (RT_SERIAL_TC_SEND_ITERATIONS - count) + { + num = (rand() % RT_SERIAL_TC_RXBUF_SIZE) + 1; + if (uart_api(num + RT_SERIAL_TC_RXBUF_SIZE) == RT_EOK) + LOG_I("data_lens [%3d], it is correct to read and write data. [%d] count testing.", num, ++count); + else + { + LOG_E("uart test error"); + break; + } + } + +__exit: + uassert_true(uart_result == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + LOG_I("UART TEST: Please connect Tx and Rx directly for self testing."); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_overflow_rxb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */ diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c index 8b2205ee1a0..40702e8fb24 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,25 +13,20 @@ #include #include -#define TC_UART_DEVICE_NAME "uart2" -#define TC_UART_SEND_TIMES 100 - #ifdef UTEST_SERIAL_TC -#define TEST_UART_NAME TC_UART_DEVICE_NAME - static struct rt_serial_device *serial; -static rt_uint8_t uart_over_flag; -static rt_bool_t uart_result = RT_TRUE; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; static rt_err_t uart_find(void) { - serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); if (serial == RT_NULL) { - LOG_E("find %s device failed!\n", TEST_UART_NAME); + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); return -RT_ERROR; } @@ -44,7 +39,7 @@ static void uart_send_entry(void *parameter) rt_uint16_t send_len; rt_uint32_t i = 0; - send_len = *(rt_uint16_t *)parameter; + send_len = *(rt_uint16_t *)parameter; /* assign send buffer */ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); if (uart_write_buffer == RT_NULL) @@ -66,7 +61,6 @@ static void uart_send_entry(void *parameter) LOG_E("device write failed\r\n"); } rt_free(uart_write_buffer); - } static void uart_rec_entry(void *parameter) @@ -74,17 +68,17 @@ static void uart_rec_entry(void *parameter) rt_uint16_t rev_len; rev_len = *(rt_uint16_t *)parameter; - rt_uint8_t *ch; - ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); - rt_int32_t cnt, i; - rt_uint8_t last_old_data; - rt_bool_t fisrt_flag = RT_TRUE; + rt_uint8_t *uart_write_buffer; + uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; rt_uint32_t all_receive_length = 0; while (1) { - cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len); if (cnt == 0) { continue; @@ -92,11 +86,11 @@ static void uart_rec_entry(void *parameter) if (fisrt_flag != RT_TRUE) { - if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0]) { - LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -107,12 +101,12 @@ static void uart_rec_entry(void *parameter) for (i = 0; i < cnt - 1; i++) { - if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1]) { - LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -120,9 +114,9 @@ static void uart_rec_entry(void *parameter) if (all_receive_length >= rev_len) break; else - last_old_data = ch[cnt - 1]; + last_old_data = uart_write_buffer[cnt - 1]; } - rt_free(ch); + rt_free(uart_write_buffer); uart_over_flag = RT_TRUE; } @@ -130,8 +124,8 @@ static rt_err_t uart_api(rt_uint16_t length) { rt_thread_t thread_send = RT_NULL; rt_thread_t thread_recv = RT_NULL; - rt_err_t result = RT_EOK; - uart_over_flag = RT_FALSE; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; result = uart_find(); if (result != RT_EOK) @@ -141,13 +135,16 @@ static rt_err_t uart_api(rt_uint16_t length) /* Reinitialize */ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - config.baud_rate = BAUD_RATE_115200; - config.rx_bufsz = BSP_UART2_RX_BUFSIZE; - config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; + +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); - if (result != RT_EOK) { LOG_E("Open uart device failed."); @@ -155,6 +152,9 @@ static rt_err_t uart_api(rt_uint16_t length) return -RT_ERROR; } + rt_int32_t timeout = 5000; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10); thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10); if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) @@ -183,27 +183,56 @@ static rt_err_t uart_api(rt_uint16_t length) /* waiting for test over */ rt_thread_mdelay(5); } + __exit: rt_device_close(&serial->parent); + rt_thread_mdelay(5); + uart_over_flag = RT_FALSE; return result; } static void tc_uart_api(void) { - rt_uint32_t times = 0; - rt_uint16_t num = 0; - while (TC_UART_SEND_TIMES - times) + rt_uint32_t count = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + srand(rt_tick_get()); + while (RT_SERIAL_TC_SEND_ITERATIONS - count) { num = (rand() % 1000) + 1; - if(uart_api(num) == RT_EOK) - LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + if (uart_api(num) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count); else { LOG_E("uart test error"); break; } } - uassert_true(uart_over_flag == RT_TRUE); + +__exit: + uassert_true(uart_result == RT_TRUE); } static rt_err_t utest_tc_init(void) @@ -214,9 +243,10 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - uart_result = RT_TRUE; - uart_over_flag = RT_FALSE; - + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c index f03a24fe13e..c2e6be82058 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,26 +13,21 @@ #include #include -#define TC_UART_DEVICE_NAME "uart2" -#define TC_UART_SEND_TIMES 100 - #ifdef UTEST_SERIAL_TC -#define TEST_UART_NAME TC_UART_DEVICE_NAME - static struct rt_serial_device *serial; -static rt_sem_t tx_sem; -static rt_uint8_t uart_over_flag; -static rt_bool_t uart_result = RT_TRUE; +static rt_sem_t tx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; static rt_err_t uart_find(void) { - serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); if (serial == RT_NULL) { - LOG_E("find %s device failed!\n", TEST_UART_NAME); + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); return -RT_ERROR; } @@ -50,10 +45,10 @@ static void uart_send_entry(void *parameter) { rt_uint8_t *uart_write_buffer; rt_uint16_t send_len, len = 0; - rt_err_t result; + rt_err_t result; rt_uint32_t i = 0; - send_len = *(rt_uint16_t *)parameter; + send_len = *(rt_uint16_t *)parameter; /* assign send buffer */ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); if (uart_write_buffer == RT_NULL) @@ -72,15 +67,14 @@ static void uart_send_entry(void *parameter) /* send buffer */ while (send_len - len) { - len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); - result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); if (result != RT_EOK) { LOG_E("take sem err in send."); } } rt_free(uart_write_buffer); - } static void uart_rec_entry(void *parameter) @@ -88,16 +82,16 @@ static void uart_rec_entry(void *parameter) rt_uint16_t rev_len; rev_len = *(rt_uint16_t *)parameter; - rt_uint8_t *ch; - ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); - rt_int32_t cnt, i; - rt_uint8_t last_old_data; - rt_bool_t fisrt_flag = RT_TRUE; + rt_uint8_t *uart_write_buffer; + uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; rt_uint32_t all_receive_length = 0; while (1) { - cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len); if (cnt != rev_len) { continue; @@ -105,11 +99,11 @@ static void uart_rec_entry(void *parameter) if (fisrt_flag != RT_TRUE) { - if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0]) { - LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -120,12 +114,12 @@ static void uart_rec_entry(void *parameter) for (i = 0; i < cnt - 1; i++) { - if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1]) { - LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -133,9 +127,9 @@ static void uart_rec_entry(void *parameter) if (all_receive_length >= rev_len) break; else - last_old_data = ch[cnt - 1]; + last_old_data = uart_write_buffer[cnt - 1]; } - rt_free(ch); + rt_free(uart_write_buffer); uart_over_flag = RT_TRUE; } @@ -143,8 +137,8 @@ static rt_err_t uart_api(rt_uint16_t test_buf) { rt_thread_t thread_send = RT_NULL; rt_thread_t thread_recv = RT_NULL; - rt_err_t result = RT_EOK; - uart_over_flag = RT_FALSE; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; result = uart_find(); if (result != RT_EOK) @@ -162,13 +156,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf) /* Reinitialize */ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - config.baud_rate = BAUD_RATE_115200; - config.rx_bufsz = BSP_UART2_RX_BUFSIZE; - config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; + +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); - if (result != RT_EOK) { LOG_E("Open uart device failed."); @@ -176,6 +173,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf) return -RT_ERROR; } + rt_int32_t timeout = 5000; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + /* set receive callback function */ result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); if (result != RT_EOK) @@ -217,25 +217,53 @@ static rt_err_t uart_api(rt_uint16_t test_buf) rt_sem_delete(tx_sem); rt_device_close(&serial->parent); + rt_thread_mdelay(5); + uart_over_flag = RT_FALSE; return result; } static void tc_uart_api(void) { - rt_uint32_t times = 0; - rt_uint16_t num = 0; - while (TC_UART_SEND_TIMES - times) + rt_uint32_t count = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + srand(rt_tick_get()); + while (RT_SERIAL_TC_SEND_ITERATIONS - count) { num = (rand() % 1000) + 1; - if(uart_api(num) == RT_EOK) - LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + if (uart_api(num) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count); else { LOG_E("uart test error"); break; } } - uassert_true(uart_over_flag == RT_TRUE); + +__exit: + uassert_true(uart_result == RT_TRUE); } static rt_err_t utest_tc_init(void) @@ -246,10 +274,11 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - tx_sem = RT_NULL; - uart_result = RT_TRUE; - uart_over_flag = RT_FALSE; - + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c index c1c88ddc9ff..a1efcc73157 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,26 +13,21 @@ #include #include -#define TC_UART_DEVICE_NAME "uart2" -#define TC_UART_SEND_TIMES 100 - #ifdef UTEST_SERIAL_TC -#define TEST_UART_NAME TC_UART_DEVICE_NAME - static struct rt_serial_device *serial; -static rt_sem_t rx_sem; -static rt_uint8_t uart_over_flag; -static rt_bool_t uart_result = RT_TRUE; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; static rt_err_t uart_find(void) { - serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); if (serial == RT_NULL) { - LOG_E("find %s device failed!\n", TEST_UART_NAME); + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); return -RT_ERROR; } @@ -52,7 +47,7 @@ static void uart_send_entry(void *parameter) rt_uint16_t send_len; rt_uint32_t i = 0; - send_len = *(rt_uint16_t *)parameter; + send_len = *(rt_uint16_t *)parameter; /* assign send buffer */ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); @@ -83,11 +78,11 @@ static void uart_rec_entry(void *parameter) rt_uint16_t rev_len; rev_len = *(rt_uint16_t *)parameter; - rt_uint8_t *ch; - ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); - rt_int32_t cnt, i; - rt_uint8_t last_old_data; - rt_bool_t fisrt_flag = RT_TRUE; + rt_uint8_t *uart_write_buffer; + uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; rt_uint32_t all_receive_length = 0; while (1) @@ -100,7 +95,7 @@ static void uart_rec_entry(void *parameter) LOG_E("take sem err in recv."); } - cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len); if (cnt == 0) { continue; @@ -108,11 +103,11 @@ static void uart_rec_entry(void *parameter) if (fisrt_flag != RT_TRUE) { - if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0]) { - LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -123,12 +118,12 @@ static void uart_rec_entry(void *parameter) for (i = 0; i < cnt - 1; i++) { - if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1]) { - LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -136,9 +131,9 @@ static void uart_rec_entry(void *parameter) if (all_receive_length >= rev_len) break; else - last_old_data = ch[cnt - 1]; + last_old_data = uart_write_buffer[cnt - 1]; } - rt_free(ch); + rt_free(uart_write_buffer); uart_over_flag = RT_TRUE; } @@ -146,7 +141,7 @@ static rt_err_t uart_api(rt_uint16_t test_buf) { rt_thread_t thread_send = RT_NULL; rt_thread_t thread_recv = RT_NULL; - rt_err_t result = RT_EOK; + rt_err_t result = RT_EOK; result = uart_find(); if (result != RT_EOK) @@ -164,13 +159,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf) /* reinitialize */ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - config.baud_rate = BAUD_RATE_115200; - config.rx_bufsz = BSP_UART2_RX_BUFSIZE; - config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; + +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); - if (result != RT_EOK) { LOG_E("Open uart device failed."); @@ -179,6 +177,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf) return -RT_ERROR; } + rt_int32_t timeout = 5000; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + /* set receive callback function */ result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate); if (result != RT_EOK) @@ -219,25 +220,52 @@ static rt_err_t uart_api(rt_uint16_t test_buf) if (rx_sem) rt_sem_delete(rx_sem); rt_device_close(&serial->parent); + rt_thread_mdelay(5); uart_over_flag = RT_FALSE; return result; } static void tc_uart_api(void) { - rt_uint32_t times = 0; - rt_uint16_t num = 0; - while (TC_UART_SEND_TIMES - times) + rt_uint32_t count = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + srand(rt_tick_get()); + while (RT_SERIAL_TC_SEND_ITERATIONS - count) { num = (rand() % 1000) + 1; - if(uart_api(num) == RT_EOK) - LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + if (uart_api(num) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count); else { LOG_E("uart test error"); break; } } + +__exit: uassert_true(uart_result == RT_TRUE); } @@ -249,10 +277,11 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - rx_sem = RT_NULL; - uart_result = RT_TRUE; - uart_over_flag = RT_FALSE; - + rx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c index ad8d20b8cff..edc66e2be85 100644 --- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c +++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2024 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,27 +13,22 @@ #include #include -#define TC_UART_DEVICE_NAME "uart2" -#define TC_UART_SEND_TIMES 100 - #ifdef UTEST_SERIAL_TC -#define TEST_UART_NAME TC_UART_DEVICE_NAME - static struct rt_serial_device *serial; -static rt_sem_t tx_sem; -static rt_sem_t rx_sem; -static rt_uint8_t uart_over_flag; -static rt_bool_t uart_result = RT_TRUE; +static rt_sem_t tx_sem; +static rt_sem_t rx_sem; +static rt_uint8_t uart_over_flag; +static rt_bool_t uart_result = RT_TRUE; static rt_err_t uart_find(void) { - serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME); + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); if (serial == RT_NULL) { - LOG_E("find %s device failed!\n", TEST_UART_NAME); + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); return -RT_ERROR; } @@ -56,10 +51,10 @@ static void uart_send_entry(void *parameter) { rt_uint8_t *uart_write_buffer; rt_uint16_t send_len, len = 0; - rt_err_t result; + rt_err_t result; rt_uint32_t i = 0; - send_len = *(rt_uint16_t *)parameter; + send_len = *(rt_uint16_t *)parameter; /* assign send buffer */ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len); if (uart_write_buffer == RT_NULL) @@ -78,15 +73,14 @@ static void uart_send_entry(void *parameter) /* send buffer */ while (send_len - len) { - len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); - result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); + len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len); + result = rt_sem_take(tx_sem, RT_WAITING_FOREVER); if (result != RT_EOK) { LOG_E("take sem err in send."); } } rt_free(uart_write_buffer); - } static void uart_rec_entry(void *parameter) @@ -94,11 +88,11 @@ static void uart_rec_entry(void *parameter) rt_uint16_t rev_len; rev_len = *(rt_uint16_t *)parameter; - rt_uint8_t *ch; - ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); - rt_int32_t cnt, i; - rt_uint8_t last_old_data; - rt_bool_t fisrt_flag = RT_TRUE; + rt_uint8_t *uart_write_buffer; + uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1)); + rt_int32_t cnt, i; + rt_uint8_t last_old_data; + rt_bool_t fisrt_flag = RT_TRUE; rt_uint32_t all_receive_length = 0; while (1) @@ -111,7 +105,7 @@ static void uart_rec_entry(void *parameter) LOG_E("take sem err in recv."); } - cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len); + cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len); if (cnt == 0) { continue; @@ -119,11 +113,11 @@ static void uart_rec_entry(void *parameter) if (fisrt_flag != RT_TRUE) { - if ((rt_uint8_t)(last_old_data + 1) != ch[0]) + if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0]) { - LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]); + LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -134,12 +128,12 @@ static void uart_rec_entry(void *parameter) for (i = 0; i < cnt - 1; i++) { - if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1]) + if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1]) { - LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]); + LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]); uart_result = RT_FALSE; - rt_free(ch); + rt_free(uart_write_buffer); return; } } @@ -147,9 +141,9 @@ static void uart_rec_entry(void *parameter) if (all_receive_length >= rev_len) break; else - last_old_data = ch[cnt - 1]; + last_old_data = uart_write_buffer[cnt - 1]; } - rt_free(ch); + rt_free(uart_write_buffer); uart_over_flag = RT_TRUE; } @@ -157,8 +151,8 @@ static rt_err_t uart_api(rt_uint16_t test_buf) { rt_thread_t thread_send = RT_NULL; rt_thread_t thread_recv = RT_NULL; - rt_err_t result = RT_EOK; - uart_over_flag = RT_FALSE; + rt_err_t result = RT_EOK; + uart_over_flag = RT_FALSE; result = uart_find(); if (result != RT_EOK) @@ -184,13 +178,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf) /* reinitialize */ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - config.baud_rate = BAUD_RATE_115200; - config.rx_bufsz = BSP_UART2_RX_BUFSIZE; - config.tx_bufsz = BSP_UART2_TX_BUFSIZE; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; + +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING); - if (result != RT_EOK) { LOG_E("Open uart device failed."); @@ -198,6 +195,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf) return -RT_ERROR; } + rt_int32_t timeout = 5000; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + /* set receive callback function */ result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion); if (result != RT_EOK) @@ -248,25 +248,53 @@ static rt_err_t uart_api(rt_uint16_t test_buf) rt_sem_delete(rx_sem); rt_device_close(&serial->parent); + rt_thread_mdelay(5); + uart_over_flag = RT_FALSE; return result; } static void tc_uart_api(void) { - rt_uint32_t times = 0; - rt_uint16_t num = 0; - while (TC_UART_SEND_TIMES - times) + rt_uint32_t count = 0; + rt_uint16_t num = 0; + rt_uint32_t i = 0; + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + for (i = 1; i < 10; i++) + { + if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count); + else + { + LOG_E("uart test error"); + goto __exit; + } + } + + srand(rt_tick_get()); + while (RT_SERIAL_TC_SEND_ITERATIONS - count) { num = (rand() % 1000) + 1; - if(uart_api(num) == RT_EOK) - LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times); + if (uart_api(num) == RT_EOK) + LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count); else { LOG_E("uart test error"); break; } } - uassert_true(uart_over_flag == RT_TRUE); + +__exit: + uassert_true(uart_result == RT_TRUE); } static rt_err_t utest_tc_init(void) @@ -277,10 +305,11 @@ static rt_err_t utest_tc_init(void) static rt_err_t utest_tc_cleanup(void) { - tx_sem = RT_NULL; - uart_result = RT_TRUE; - uart_over_flag = RT_FALSE; - + tx_sem = RT_NULL; + uart_result = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); return RT_EOK; } diff --git a/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c new file mode 100644 index 00000000000..ae42ee5d05a --- /dev/null +++ b/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2006-2024 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * + */ + +#include +#include "utest.h" +#include +#include + +/* */ + +#ifdef UTEST_SERIAL_TC + +static struct rt_serial_device *serial; +static rt_bool_t uart_result = RT_TRUE; +static rt_uint8_t uart_write_flag = RT_TRUE; +static rt_uint8_t uart_over_flag = RT_FALSE; + +static rt_err_t uart_find(void) +{ + serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + + if (serial == RT_NULL) + { + LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME); + return -RT_ERROR; + } + + return RT_EOK; +} + + +static void uart_send_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer = RT_NULL; + rt_uint32_t i = 0; + + /* assign send buffer */ + uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE); + if (uart_write_buffer == RT_NULL) + { + LOG_E("Without spare memory for uart dma!"); + uart_result = RT_FALSE; + return; + } + + for (i = 0; i < RT_SERIAL_TC_RXBUF_SIZE; i++) + { + uart_write_buffer[i] = (rt_uint8_t)i; + } + + while (1) + { + if (uart_write_flag == RT_FALSE) + break; + + rt_device_write(&serial->parent, 0, uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE / 3); + rt_thread_mdelay(40); + } + + rt_free(uart_write_buffer); +} + +static void uart_rec_entry(void *parameter) +{ + rt_uint8_t *uart_write_buffer; + rt_tick_t old_tick; + rt_tick_t tick_diff; + rt_ssize_t recv_len; + rt_uint32_t i; + rt_int32_t timeout = 0; + uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_RXBUF_SIZE * 10 + 1)); + + timeout = 100; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout); + + uart_write_flag = RT_TRUE; + for (i = 0; i < 10; i++) + { + rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL); + old_tick = rt_tick_get(); + recv_len = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE); + tick_diff = rt_tick_get() - old_tick; + if (tick_diff > 100 + 1 || tick_diff < 100) + { + LOG_E("timeout_test: recv_size [%d], RX block time [%d], expect_time [100 - 101]", recv_len, tick_diff); + uart_write_flag = RT_FALSE; + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + rt_thread_mdelay(60); + return; + } + + LOG_I("timeout_test: RX block time [%d], expect_time [100 - 101]", tick_diff); + } + uart_write_flag = RT_FALSE; + + rt_thread_mdelay(60); + timeout = 10; + rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&timeout); + + for (i = 0; i < 10; i++) + { + old_tick = rt_tick_get(); + recv_len = rt_device_write(&serial->parent, 0, uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * 10); + tick_diff = rt_tick_get() - old_tick; + if (tick_diff > 10 + 1 || tick_diff < 10) + { + LOG_E("timeout_test: recv_size [%d], TX block time [%d], expect_time [10 - 11]", recv_len, tick_diff); + uart_result = RT_FALSE; + rt_free(uart_write_buffer); + return; + } + + LOG_I("timeout_test: TX block time [%d], expect_time [10 - 11]", tick_diff); + rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL); + } + + rt_free(uart_write_buffer); + uart_over_flag = RT_TRUE; +} + +static rt_bool_t uart_api() +{ + rt_thread_t thread_send = RT_NULL; + rt_thread_t thread_recv = RT_NULL; + rt_err_t result = RT_EOK; + + result = uart_find(); + if (result != RT_EOK) + { + return RT_FALSE; + } + + /* Reinitialize */ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.baud_rate = BAUD_RATE_115200; + config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE; + config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE; +#ifdef RT_SERIAL_USING_DMA + config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2; +#endif + rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config); + + result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); + if (result != RT_EOK) + { + LOG_E("Open uart device failed."); + return RT_FALSE; + } + + thread_send = rt_thread_create("uart_send", uart_send_entry, NULL, 2048, RT_THREAD_PRIORITY_MAX - 4, 10); + thread_recv = rt_thread_create("uart_recv", uart_rec_entry, NULL, 2048, RT_THREAD_PRIORITY_MAX - 5, 10); + + if ((thread_send != RT_NULL) && (thread_recv != RT_NULL)) + { + rt_thread_startup(thread_send); + rt_thread_startup(thread_recv); + } + else + { + result = -RT_ERROR; + goto __exit; + } + + while (1) + { + if (uart_result != RT_TRUE) + { + LOG_E("The test for uart dma is failure."); + result = -RT_ERROR; + goto __exit; + } + if (uart_over_flag == RT_TRUE) + { + goto __exit; + } + /* waiting for test over */ + rt_thread_mdelay(5); + } + +__exit: + rt_device_close(&serial->parent); + rt_thread_mdelay(5); + return result == RT_EOK ? RT_TRUE : RT_FALSE; +} + +static void tc_uart_api(void) +{ + uassert_true(uart_api() == RT_TRUE); +} + +static rt_err_t utest_tc_init(void) +{ + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + uart_result = RT_TRUE; + uart_write_flag = RT_TRUE; + uart_over_flag = RT_FALSE; + rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME); + while (rt_device_close(uart_dev) != -RT_ERROR); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(tc_uart_api); +} + +UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_timeout_rxb_txb", utest_tc_init, utest_tc_cleanup, 30); + +#endif /* TC_UART_USING_TC */