From c45f5a249089e1e453f358bcab052ddce8a8dff7 Mon Sep 17 00:00:00 2001 From: bernard Date: Fri, 18 Jul 2014 06:45:54 +0800 Subject: [PATCH] [Drivers] re-write serial framework. --- bsp/at91sam9260/drivers/usart.c | 24 +- bsp/beaglebone/drivers/serial.c | 36 +- bsp/frdm-k64f/board/drv_uart.c | 5 +- bsp/lpc408x/drivers/drv_uart.c | 10 +- bsp/lpc43xx/drivers/drv_uart.c | 14 +- bsp/mb9bf506r/drivers/fm3_uart.c | 40 +- bsp/realview-a8/drivers/serial.c | 13 +- bsp/rm48x50/drivers/drv_uart.c | 6 +- bsp/stm32f0x/drivers/usart.c | 10 +- bsp/xplorer4330/drivers/drv_uart.c | 16 +- bsp/zynq7000/drivers/uart.c | 11 +- components/drivers/include/drivers/serial.h | 67 +- components/drivers/serial/serial.c | 691 ++++++++++++-------- components/finsh/shell.c | 2 +- 14 files changed, 542 insertions(+), 403 deletions(-) diff --git a/bsp/at91sam9260/drivers/usart.c b/bsp/at91sam9260/drivers/usart.c index 7b95ca0e4d..c47d378cb8 100644 --- a/bsp/at91sam9260/drivers/usart.c +++ b/bsp/at91sam9260/drivers/usart.c @@ -95,7 +95,7 @@ void rt_at91_usart_handler(int vector, void *param) return; } rt_interrupt_enter(); - rt_hw_serial_isr(dev); + rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_RX_IND); rt_interrupt_leave(); } @@ -231,7 +231,6 @@ static const struct rt_uart_ops at91_usart_ops = #if defined(RT_USING_DBGU) static struct rt_serial_device serial_dbgu; -static struct serial_ringbuffer dbgu_int_rx; struct at91_uart dbgu = { DBGU, AT91_ID_SYS @@ -241,7 +240,6 @@ struct at91_uart dbgu = { #if defined(RT_USING_UART0) static struct rt_serial_device serial0; -static struct serial_ringbuffer uart0_int_rx; struct at91_uart uart0 = { UART0, AT91SAM9260_ID_US0 @@ -250,7 +248,6 @@ struct at91_uart uart0 = { #if defined(RT_USING_UART1) static struct rt_serial_device serial1; -static struct serial_ringbuffer uart1_int_rx; struct at91_uart uart1 = { UART1, AT91SAM9260_ID_US1 @@ -259,7 +256,6 @@ struct at91_uart uart1 = { #if defined(RT_USING_UART2) static struct rt_serial_device serial2; -static struct serial_ringbuffer uart2_int_rx; struct at91_uart uart2 = { UART2, AT91SAM9260_ID_US2 @@ -268,7 +264,6 @@ struct at91_uart uart2 = { #if defined(RT_USING_UART3) static struct rt_serial_device serial3; -static struct serial_ringbuffer uart3_int_rx; struct at91_uart uart3 = { UART3, AT91SAM9260_ID_US3 @@ -337,29 +332,29 @@ void rt_hw_uart_init(void) #if defined(RT_USING_DBGU) serial_dbgu.ops = &at91_usart_ops; - serial_dbgu.int_rx = &dbgu_int_rx; serial_dbgu.config.baud_rate = BAUD_RATE_115200; serial_dbgu.config.bit_order = BIT_ORDER_LSB; serial_dbgu.config.data_bits = DATA_BITS_8; serial_dbgu.config.parity = PARITY_NONE; serial_dbgu.config.stop_bits = STOP_BITS_1; serial_dbgu.config.invert = NRZ_NORMAL; + serial_dbgu.config.bufsz = RT_SERIAL_RB_BUFSZ; /* register vcom device */ rt_hw_serial_register(&serial_dbgu, "dbgu", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &dbgu); #endif #if defined(RT_USING_UART0) serial0.ops = &at91_usart_ops; - serial0.int_rx = &uart0_int_rx; serial0.config.baud_rate = BAUD_RATE_115200; serial0.config.bit_order = BIT_ORDER_LSB; serial0.config.data_bits = DATA_BITS_8; serial0.config.parity = PARITY_NONE; serial0.config.stop_bits = STOP_BITS_1; serial0.config.invert = NRZ_NORMAL; + serial0.config.bufsz = RT_SERIAL_RB_BUFSZ; /* register vcom device */ rt_hw_serial_register(&serial0, "uart0", @@ -379,10 +374,11 @@ void rt_hw_uart_init(void) serial1.config.parity = PARITY_NONE; serial1.config.stop_bits = STOP_BITS_1; serial1.config.invert = NRZ_NORMAL; + serial1.config.bufsz = RT_SERIAL_RB_BUFSZ; /* register vcom device */ rt_hw_serial_register(&serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart1); rt_hw_interrupt_install(uart1.irq, rt_at91_usart_handler, (void *)&(serial1.parent), "UART1"); @@ -391,17 +387,17 @@ void rt_hw_uart_init(void) #if defined(RT_USING_UART2) serial2.ops = &at91_usart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config.baud_rate = BAUD_RATE_115200; serial2.config.bit_order = BIT_ORDER_LSB; serial2.config.data_bits = DATA_BITS_8; serial2.config.parity = PARITY_NONE; serial2.config.stop_bits = STOP_BITS_1; serial2.config.invert = NRZ_NORMAL; + serial2.config.bufsz = RT_SERIAL_RB_BUFSZ; /* register vcom device */ rt_hw_serial_register(&serial2, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart2); rt_hw_interrupt_install(uart2.irq, rt_at91_usart_handler, (void *)&(serial2.parent), "UART2"); @@ -410,17 +406,17 @@ void rt_hw_uart_init(void) #if defined(RT_USING_UART3) serial3.ops = &at91_usart_ops; - serial3.int_rx = &uart3_int_rx; serial3.config.baud_rate = BAUD_RATE_115200; serial3.config.bit_order = BIT_ORDER_LSB; serial3.config.data_bits = DATA_BITS_8; serial3.config.parity = PARITY_NONE; serial3.config.stop_bits = STOP_BITS_1; serial3.config.invert = NRZ_NORMAL; + serial3.config.bufsz = RT_SERIAL_RB_BUFSZ; /* register vcom device */ rt_hw_serial_register(&serial3, "uart3", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart3); rt_hw_interrupt_install(uart3.irq, rt_at91_usart_handler, (void *)&(serial3.parent), "UART3"); diff --git a/bsp/beaglebone/drivers/serial.c b/bsp/beaglebone/drivers/serial.c index d07621080b..8dcd389123 100644 --- a/bsp/beaglebone/drivers/serial.c +++ b/bsp/beaglebone/drivers/serial.c @@ -41,7 +41,7 @@ static void am33xx_uart_isr(int irqno, void* param) if ((iir & (0x02 << 1)) || (iir & (0x6 << 1))) { - rt_hw_serial_isr(serial); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } } @@ -165,7 +165,6 @@ static const struct rt_uart_ops am33xx_uart_ops = /* UART device driver structure */ #ifdef RT_USING_UART0 -struct serial_ringbuffer uart0_int_rx; struct am33xx_uart uart0 = { UART0_BASE, @@ -175,7 +174,6 @@ struct rt_serial_device serial0; #endif #ifdef RT_USING_UART1 -struct serial_ringbuffer uart1_int_rx; struct am33xx_uart uart1 = { UART1_BASE, @@ -185,7 +183,6 @@ struct rt_serial_device serial1; #endif #ifdef RT_USING_UART2 -struct serial_ringbuffer uart2_int_rx; struct am33xx_uart uart2 = { UART2_BASE, @@ -195,7 +192,6 @@ struct rt_serial_device serial2; #endif #ifdef RT_USING_UART3 -struct serial_ringbuffer uart3_int_rx; struct am33xx_uart uart3 = { UART3_BASE, @@ -205,7 +201,6 @@ struct rt_serial_device serial3; #endif #ifdef RT_USING_UART4 -struct serial_ringbuffer uart4_int_rx; struct am33xx_uart uart4 = { UART4_BASE, @@ -215,7 +210,6 @@ struct rt_serial_device serial4; #endif #ifdef RT_USING_UART5 -struct serial_ringbuffer uart5_int_rx; struct am33xx_uart uart5 = { UART5_BASE, @@ -359,8 +353,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; + serial0.ops = &am33xx_uart_ops; - serial0.int_rx = &uart0_int_rx; serial0.config = config; /* enable RX interrupt */ UART_IER_REG(uart0.base) = 0x01; @@ -370,7 +365,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart0.irq); /* register UART0 device */ rt_hw_serial_register(&serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart0); #endif @@ -381,8 +376,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; + serial1.ops = &am33xx_uart_ops; - serial1.int_rx = &uart1_int_rx; serial1.config = config; /* enable RX interrupt */ UART_IER_REG(uart1.base) = 0x01; @@ -392,7 +388,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart1.irq); /* register UART0 device */ rt_hw_serial_register(&serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart1); #endif @@ -403,8 +399,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; + serial2.ops = &am33xx_uart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; /* enable RX interrupt */ UART_IER_REG(uart2.base) = 0x01; @@ -414,7 +411,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart2.irq); /* register UART2 device */ rt_hw_serial_register(&serial2, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart2); #endif @@ -425,8 +422,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; + serial3.ops = &am33xx_uart_ops; - serial3.int_rx = &uart_3_int_rx; serial3.config = config; /* enable RX interrupt */ UART_IER_REG(uart3.base) = 0x01; @@ -436,7 +434,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart3.irq); /* register UART3 device */ rt_hw_serial_register(&serial3, "uart3", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart3); #endif @@ -447,9 +445,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial4.ops = &am33xx_uart_ops; - serial4.int_rx = &uart4_int_rx; serial4.config = config; /* enable RX interrupt */ UART_IER_REG(uart4.base) = 0x01; @@ -459,7 +457,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart4.irq); /* register UART4 device */ rt_hw_serial_register(&serial4, "uart4", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart4); #endif @@ -470,9 +468,9 @@ int rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial5.ops = &am33xx_uart_ops; - serial5.int_rx = &uart5_int_rx; serial5.config = config; /* enable RX interrupt */ UART_IER_REG(uart5.base) = 0x01; @@ -482,7 +480,7 @@ int rt_hw_serial_init(void) rt_hw_interrupt_mask(uart5.irq); /* register UART4 device */ rt_hw_serial_register(&serial5, "uart5", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart5); #endif diff --git a/bsp/frdm-k64f/board/drv_uart.c b/bsp/frdm-k64f/board/drv_uart.c index 7813b21ad7..ac9ef8d51a 100644 --- a/bsp/frdm-k64f/board/drv_uart.c +++ b/bsp/frdm-k64f/board/drv_uart.c @@ -16,7 +16,6 @@ #include "drv_uart.h" static struct rt_serial_device _k64_serial; //abstracted serial for RTT -static struct serial_ringbuffer _k64_int_rx; //UART send buffer area struct k64_serial_device { @@ -231,7 +230,7 @@ static const struct rt_uart_ops _k64_ops = void UART0_RX_TX_IRQHandler(void) { rt_interrupt_enter(); - rt_hw_serial_isr((struct rt_serial_device*)&_k64_serial); + rt_hw_serial_isr((struct rt_serial_device*)&_k64_serial, RT_SERIAL_EVENT_RX_IND); rt_interrupt_leave(); } @@ -247,9 +246,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; _k64_serial.ops = &_k64_ops; - _k64_serial.int_rx = &_k64_int_rx; _k64_serial.config = config; rt_hw_serial_register(&_k64_serial, "uart0", diff --git a/bsp/lpc408x/drivers/drv_uart.c b/bsp/lpc408x/drivers/drv_uart.c index 37213c0474..0b3756a5b9 100644 --- a/bsp/lpc408x/drivers/drv_uart.c +++ b/bsp/lpc408x/drivers/drv_uart.c @@ -118,7 +118,6 @@ static const struct rt_uart_ops lpc_uart_ops = #if defined(RT_USING_UART0) /* UART0 device driver structure */ -struct serial_ringbuffer uart0_int_rx; struct lpc_uart uart0 = { UART_0, @@ -158,7 +157,7 @@ void UART0_IRQHandler(void) // Receive Data Available or Character time-out if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)) { - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); } /* leave interrupt */ @@ -167,7 +166,6 @@ void UART0_IRQHandler(void) #endif #if defined(RT_USING_UART2) /* UART2 device driver structure */ -struct serial_ringbuffer uart2_int_rx; struct lpc_uart uart2 = { UART_2, @@ -207,7 +205,7 @@ void UART2_IRQHandler(void) // Receive Data Available or Character time-out if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)) { - rt_hw_serial_isr(&serial2); + rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND); } /* leave interrupt */ @@ -227,9 +225,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial0.ops = &lpc_uart_ops; - serial0.int_rx = &uart0_int_rx; serial0.config = config; /* @@ -259,9 +257,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial2.ops = &lpc_uart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; /* diff --git a/bsp/lpc43xx/drivers/drv_uart.c b/bsp/lpc43xx/drivers/drv_uart.c index 867ee32bd5..58a385b8b1 100644 --- a/bsp/lpc43xx/drivers/drv_uart.c +++ b/bsp/lpc43xx/drivers/drv_uart.c @@ -97,7 +97,6 @@ static const struct rt_uart_ops lpc_uart_ops = #if defined(RT_USING_UART0) /* UART0 device driver structure */ -struct serial_ringbuffer uart0_int_rx; struct lpc_uart uart0 = { LPC_USART0, @@ -136,7 +135,7 @@ void UART0_IRQHandler(void) /* read the data to buffer */ while (uart->USART->LSR & UART_LSR_RDR) { - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); } break; @@ -150,7 +149,6 @@ void UART0_IRQHandler(void) #endif #if defined(RT_USING_UART2) /* UART2 device driver structure */ -struct serial_ringbuffer uart2_int_rx; struct lpc_uart uart2 = { LPC_USART2, @@ -189,7 +187,7 @@ void UART2_IRQHandler(void) /* read the data to buffer */ while (uart->USART->LSR & UART_LSR_RDR) { - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); } break; @@ -214,9 +212,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial0.ops = &lpc_uart_ops; - serial0.int_rx = &uart0_int_rx; serial0.config = config; /* Enable GPIO register interface clock */ @@ -256,7 +254,7 @@ void rt_hw_uart_init(void) /* register UART1 device */ rt_hw_serial_register(&serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif #ifdef RT_USING_UART2 @@ -267,9 +265,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial2.ops = &lpc_uart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; /* Enable GPIO register interface clock */ @@ -309,7 +307,7 @@ void rt_hw_uart_init(void) /* register UART1 device */ rt_hw_serial_register(&serial2, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif } diff --git a/bsp/mb9bf506r/drivers/fm3_uart.c b/bsp/mb9bf506r/drivers/fm3_uart.c index 51fb820ed8..2c82afd288 100644 --- a/bsp/mb9bf506r/drivers/fm3_uart.c +++ b/bsp/mb9bf506r/drivers/fm3_uart.c @@ -20,7 +20,6 @@ #if (defined(RT_USING_UART0_0) || defined(RT_USING_UART0_1)) /* UART0 device driver structure */ -struct serial_ringbuffer uart0_int_rx; struct uart03_device uart0 = { FM3_MFS0_UART, @@ -33,7 +32,7 @@ void MFS0RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -41,7 +40,6 @@ void MFS0RX_IRQHandler(void) #if (defined(RT_USING_UART1_0) || defined(RT_USING_UART1_1)) /* UART1 device driver structure */ -struct serial_ringbuffer uart1_int_rx; struct uart03_device uart1 = { FM3_MFS1_UART, @@ -54,7 +52,7 @@ void MFS1RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial1); + rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -62,7 +60,6 @@ void MFS1RX_IRQHandler(void) #if (defined(RT_USING_UART2_0) || defined(RT_USING_UART2_1) || defined(RT_USING_UART2_2)) /* UART2 device driver structure */ -struct serial_ringbuffer uart2_int_rx; struct uart03_device uart2 = { FM3_MFS2_UART, @@ -75,7 +72,7 @@ void MFS2RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial2); + rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -83,7 +80,6 @@ void MFS2RX_IRQHandler(void) #if (defined(RT_USING_UART3_0) || defined(RT_USING_UART3_1) || defined(RT_USING_UART3_2)) /* UART3 device driver structure */ -struct serial_ringbuffer uart3_int_rx; struct uart03_device uart3 = { FM3_MFS3_UART, @@ -96,7 +92,7 @@ void MFS3RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial3); + rt_hw_serial_isr(&serial3, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -104,7 +100,6 @@ void MFS3RX_IRQHandler(void) #if (defined(RT_USING_UART4_0) || defined(RT_USING_UART4_1) || defined(RT_USING_UART4_2)) /* UART4 device driver structure */ -struct serial_ringbuffer uart4_int_rx; struct uart47_device uart4 = { FM3_MFS4_UART, @@ -118,7 +113,7 @@ void MFS4RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial4); + rt_hw_serial_isr(&serial4, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -126,7 +121,6 @@ void MFS4RX_IRQHandler(void) #if (defined(RT_USING_UART5_0) || defined(RT_USING_UART5_1) || defined(RT_USING_UART5_2)) /* UART5 device driver structure */ -struct serial_ringbuffer uart5_int_rx; struct uart47_device uart5 = { FM3_MFS5_UART, @@ -140,7 +134,7 @@ void MFS5RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial5); + rt_hw_serial_isr(&serial5, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -148,7 +142,6 @@ void MFS5RX_IRQHandler(void) #if (defined(RT_USING_UART6_0) || defined(RT_USING_UART6_1)) /* UART6 device driver structure */ -struct serial_ringbuffer uart6_int_rx; struct uart47_device uart6 = { FM3_MFS6_UART, @@ -162,7 +155,7 @@ void MFS6RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial6); + rt_hw_serial_isr(&serial6, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -170,7 +163,6 @@ void MFS6RX_IRQHandler(void) #if (defined(RT_USING_UART7_0) || defined(RT_USING_UART7_1)) /* UART7 device driver structure */ -struct serial_ringbuffer uart7_int_rx; struct uart47_device uart7 = { FM3_MFS7_UART, @@ -184,7 +176,7 @@ void MFS7RX_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); - rt_hw_serial_isr(&serial7); + rt_hw_serial_isr(&serial7, RT_SERIAL_EVENT_RX_IND); /* leave interrupt */ rt_interrupt_leave(); } @@ -796,9 +788,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial0.ops = &uart03_ops; - serial0.int_rx = &uart0_int_rx; serial0.config = config; /* register UART0 device */ @@ -814,9 +806,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial1.ops = &uart03_ops; - serial1.int_rx = &uart1_int_rx; serial1.config = config; /* register UART1 device */ @@ -833,9 +825,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial2.ops = &uart03_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; /* register UART2 device */ @@ -852,9 +844,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial3.ops = &uart03_ops; - serial3.int_rx = &uart3_int_rx; serial3.config = config; /* register UART3 device */ @@ -871,9 +863,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial4.ops = &uart47_ops; - serial4.int_rx = &uart4_int_rx; serial4.config = config; /* register UART4 device */ @@ -890,9 +882,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial5.ops = &uart47_ops; - serial5.int_rx = &uart5_int_rx; serial5.config = config; /* register UART5 device */ @@ -909,9 +901,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial6.ops = &uart47_ops; - serial6.int_rx = &uart6_int_rx; serial6.config = config; /* register UART6 device */ @@ -928,9 +920,9 @@ void rt_hw_serial_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial7.ops = &uart47_ops; - serial7.int_rx = &uart7_int_rx; serial7.config = config; /* register UART7 device */ diff --git a/bsp/realview-a8/drivers/serial.c b/bsp/realview-a8/drivers/serial.c index 0af03b2759..011d10fb99 100644 --- a/bsp/realview-a8/drivers/serial.c +++ b/bsp/realview-a8/drivers/serial.c @@ -58,7 +58,7 @@ static void rt_hw_uart_isr(int irqno, void *param) { struct rt_serial_device *serial = (struct rt_serial_device *)param; - rt_hw_serial_isr(serial); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) @@ -131,7 +131,6 @@ static const struct rt_uart_ops _uart_ops = #ifdef RT_USING_UART0 /* UART device driver structure */ -static struct serial_ringbuffer _uart0_int_rx; static struct hw_uart_device _uart0_device = { REALVIEW_UART0_BASE, @@ -142,7 +141,6 @@ static struct rt_serial_device _serial0; #ifdef RT_USING_UART1 /* UART1 device driver structure */ -static struct serial_ringbuffer _uart1_int_rx; static struct hw_uart_device _uart1_device = { REALVIEW_UART1_BASE, @@ -167,7 +165,8 @@ int rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; - + config.bufsz = RT_SERIAL_RB_BUFSZ; + #ifdef RT_USING_UART0 uart = &_uart0_device; #ifdef RT_USING_VMM @@ -175,12 +174,11 @@ int rt_hw_uart_init(void) #endif _serial0.ops = &_uart_ops; - _serial0.int_rx = &_uart0_int_rx; _serial0.config = config; /* register UART1 device */ rt_hw_serial_register(&_serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); /* enable Rx and Tx of UART */ UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); @@ -192,12 +190,11 @@ int rt_hw_uart_init(void) uart->hw_base = vmm_find_iomap("UART1"); #endif _serial1.ops = &_uart_ops; - _serial1.int_rx = &_uart1_int_rx; _serial1.config = config; /* register UART1 device */ rt_hw_serial_register(&_serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, uart); + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); /* enable Rx and Tx of UART */ UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9); #endif diff --git a/bsp/rm48x50/drivers/drv_uart.c b/bsp/rm48x50/drivers/drv_uart.c index 3f0237e648..d42a52bc6b 100644 --- a/bsp/rm48x50/drivers/drv_uart.c +++ b/bsp/rm48x50/drivers/drv_uart.c @@ -178,11 +178,10 @@ static const struct rt_uart_ops _sci_ops = static void _irq_wrapper(int vector, void *param) { - rt_hw_serial_isr((struct rt_serial_device*)param); + rt_hw_serial_isr((struct rt_serial_device*)param, RT_SERIAL_EVENT_RX_IND); } static struct rt_serial_device _sci2_serial; -static struct serial_ringbuffer _sci2_int_rx; void rt_hw_uart_init(void) { @@ -195,9 +194,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; _sci2_serial.ops = &_sci_ops; - _sci2_serial.int_rx = &_sci2_int_rx; _sci2_serial.config = config; rt_hw_serial_register(&_sci2_serial, "sci2", @@ -208,3 +207,4 @@ void rt_hw_uart_init(void) rt_hw_interrupt_install(SCI_INT_VEC, _irq_wrapper, &_sci2_serial, "sci2"); rt_hw_interrupt_umask(SCI_INT_VEC); } + diff --git a/bsp/stm32f0x/drivers/usart.c b/bsp/stm32f0x/drivers/usart.c index f7784ce556..7a7d3a8230 100644 --- a/bsp/stm32f0x/drivers/usart.c +++ b/bsp/stm32f0x/drivers/usart.c @@ -134,7 +134,6 @@ static const struct rt_uart_ops stm32_uart_ops = #if defined(RT_USING_UART1) /* UART1 device driver structure */ -struct serial_ringbuffer uart1_int_rx; struct stm32_uart uart1 = { USART1, @@ -152,7 +151,7 @@ void USART1_IRQHandler(void) rt_interrupt_enter(); if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET) { - rt_hw_serial_isr(&serial1); + rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND); /* clear interrupt */ USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE); } @@ -169,7 +168,6 @@ void USART1_IRQHandler(void) #if defined(RT_USING_UART2) /* UART2 device driver structure */ -struct serial_ringbuffer uart2_int_rx; struct stm32_uart uart2 = { USART2, @@ -187,7 +185,7 @@ void USART2_IRQHandler(void) rt_interrupt_enter(); if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET) { - rt_hw_serial_isr(&serial2); + rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND); /* clear interrupt */ USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE); } @@ -281,14 +279,13 @@ void rt_hw_usart_init(void) config.baud_rate = BAUD_RATE_115200; serial1.ops = &stm32_uart_ops; - serial1.int_rx = &uart1_int_rx; serial1.config = config; NVIC_Configuration(&uart1); /* register UART1 device */ rt_hw_serial_register(&serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif /* RT_USING_UART1 */ @@ -297,7 +294,6 @@ void rt_hw_usart_init(void) config.baud_rate = BAUD_RATE_115200; serial2.ops = &stm32_uart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; NVIC_Configuration(&uart2); diff --git a/bsp/xplorer4330/drivers/drv_uart.c b/bsp/xplorer4330/drivers/drv_uart.c index c8242277b2..4fa489ea06 100644 --- a/bsp/xplorer4330/drivers/drv_uart.c +++ b/bsp/xplorer4330/drivers/drv_uart.c @@ -97,7 +97,6 @@ static const struct rt_uart_ops lpc_uart_ops = #if defined(RT_USING_UART0) /* UART0 device driver structure */ -struct serial_ringbuffer uart0_int_rx; struct lpc_uart uart0 = { LPC_USART0, @@ -136,7 +135,7 @@ void UART0_IRQHandler(void) /* read the data to buffer */ while (uart->USART->LSR & UART_LSR_RDR) { - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); } break; @@ -150,7 +149,6 @@ void UART0_IRQHandler(void) #endif #if defined(RT_USING_UART2) /* UART2 device driver structure */ -struct serial_ringbuffer uart2_int_rx; struct lpc_uart uart2 = { LPC_USART2, @@ -189,7 +187,7 @@ void UART2_IRQHandler(void) /* read the data to buffer */ while (uart->USART->LSR & UART_LSR_RDR) { - rt_hw_serial_isr(&serial0); + rt_hw_serial_isr(&serial0, RT_SERIAL_EVENT_RX_IND); } break; @@ -214,9 +212,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; - + config.bufsz = RT_SERIAL_RB_BUFSZ; + serial0.ops = &lpc_uart_ops; - serial0.int_rx = &uart0_int_rx; serial0.config = config; /* Enable GPIO register interface clock */ @@ -256,7 +254,7 @@ void rt_hw_uart_init(void) /* register UART1 device */ rt_hw_serial_register(&serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif #ifdef RT_USING_UART2 @@ -267,9 +265,9 @@ void rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; serial2.ops = &lpc_uart_ops; - serial2.int_rx = &uart2_int_rx; serial2.config = config; /* Enable GPIO register interface clock */ @@ -309,7 +307,7 @@ void rt_hw_uart_init(void) /* register UART1 device */ rt_hw_serial_register(&serial2, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif } diff --git a/bsp/zynq7000/drivers/uart.c b/bsp/zynq7000/drivers/uart.c index f10c48d330..df4250b399 100644 --- a/bsp/zynq7000/drivers/uart.c +++ b/bsp/zynq7000/drivers/uart.c @@ -98,7 +98,7 @@ static void rt_hw_uart_isr(int irqno, void *param) { struct rt_serial_device *serial = (struct rt_serial_device *)param; - rt_hw_serial_isr(serial); + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) @@ -267,9 +267,7 @@ static struct hw_uart_device _uart_device1 = .txmio = (rt_uint32_t*)(Zynq7000_SLCR_BASE+0x07C0), /* MIO48 */ }; -static struct serial_ringbuffer _uart_int_rx0; static struct rt_serial_device _serial0; -static struct serial_ringbuffer _uart_int_rx1; static struct rt_serial_device _serial1; int rt_hw_uart_init(void) @@ -282,21 +280,20 @@ int rt_hw_uart_init(void) config.parity = PARITY_NONE; config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; + config.bufsz = RT_SERIAL_RB_BUFSZ; _serial0.ops = &_uart_ops; - _serial0.int_rx = &_uart_int_rx0; _serial0.config = config; _serial1.ops = &_uart_ops; - _serial1.int_rx = &_uart_int_rx1; _serial1.config = config; /* register uart device */ rt_hw_serial_register(&_serial0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &_uart_device0); rt_hw_serial_register(&_serial1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &_uart_device1); return 0; } diff --git a/components/drivers/include/drivers/serial.h b/components/drivers/include/drivers/serial.h index 9655820736..bf2a25ae1e 100644 --- a/components/drivers/include/drivers/serial.h +++ b/components/drivers/include/drivers/serial.h @@ -70,6 +70,15 @@ #define RT_DEVICE_CTRL_CLR_INT 0x11 /* disable receive irq */ #define RT_DEVICE_CTRL_GET_INT 0x12 +#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 */ + +#define RT_SERIAL_DMA_RX 0x01 +#define RT_SERIAL_DMA_TX 0x02 + #define RT_SERIAL_RX_INT 0x01 #define RT_SERIAL_TX_INT 0x02 @@ -89,24 +98,51 @@ PARITY_NONE, /* No parity */ \ BIT_ORDER_LSB, /* LSB first sent */ \ NRZ_NORMAL, /* Normal mode */ \ + RT_SERIAL_RB_BUFSZ, /* Buffer size */ \ 0 \ } -struct serial_ringbuffer -{ - rt_uint8_t buffer[RT_SERIAL_RB_BUFSZ]; - rt_uint16_t put_index, get_index; -}; - struct serial_configure { rt_uint32_t baud_rate; + rt_uint32_t data_bits :4; rt_uint32_t stop_bits :2; rt_uint32_t parity :2; rt_uint32_t bit_order :1; rt_uint32_t invert :1; - rt_uint32_t reserved :20; + rt_uint32_t bufsz :16; + rt_uint32_t reserved :4; +}; + +/* + * Serial FIFO mode + */ +struct rt_serial_rx_fifo +{ + /* software fifo */ + rt_uint8_t *buffer; + + rt_uint16_t put_index, get_index; +}; + +struct rt_serial_tx_fifo +{ + struct rt_completion completion; +}; + +/* + * Serial DMA mode + */ +struct rt_serial_rx_dma +{ + rt_bool_t activated; +}; + +struct rt_serial_tx_dma +{ + rt_bool_t activated; + struct rt_data_queue data_queue; }; struct rt_serial_device @@ -116,14 +152,8 @@ struct rt_serial_device const struct rt_uart_ops *ops; struct serial_configure config; - /* rx structure */ - struct serial_ringbuffer *int_rx; - /* tx structure */ - struct serial_ringbuffer *int_tx; - - struct rt_data_queue tx_dq; /* tx dataqueue */ - - volatile rt_bool_t dma_flag; /* dma transfer flag */ + void *serial_rx; + void *serial_tx; }; typedef struct rt_serial_device rt_serial_t; @@ -138,14 +168,15 @@ struct rt_uart_ops int (*putc)(struct rt_serial_device *serial, char c); int (*getc)(struct rt_serial_device *serial); - rt_size_t (*dma_transmit)(struct rt_serial_device *serial, const char *buf, rt_size_t size); + rt_size_t (*dma_transmit)(struct rt_serial_device *serial, const rt_uint8_t *buf, rt_size_t size, int direction); }; -void rt_hw_serial_isr(struct rt_serial_device *serial); -void rt_hw_serial_dma_tx_isr(struct rt_serial_device *serial); +void rt_hw_serial_isr(struct rt_serial_device *serial, int event); + rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, const char *name, rt_uint32_t flag, void *data); #endif + diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index 61c03fa955..776316baf5 100644 --- a/components/drivers/serial/serial.c +++ b/components/drivers/serial/serial.c @@ -25,104 +25,197 @@ * 2012-11-23 bernard fix compiler warning. * 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define * the size of ring buffer. + * 2014-07-10 bernard rewrite serial framework */ #include #include #include -rt_inline void serial_ringbuffer_init(struct serial_ringbuffer *rbuffer) +/* + * Serial poll routines + */ +rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) { - rt_memset(rbuffer->buffer, 0, sizeof(rbuffer->buffer)); - rbuffer->put_index = 0; - rbuffer->get_index = 0; + int ch; + int size; + + RT_ASSERT(serial != RT_NULL); + size = length; + + while (length) + { + ch = serial->ops->getc(serial); + *data = ch; + data ++; length --; + + if (ch == '\n') break; + } + + return size - length; } -rt_inline void serial_ringbuffer_putc(struct serial_ringbuffer *rbuffer, - char ch) +rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) { - rt_base_t level; + int size; + RT_ASSERT(serial != RT_NULL); - /* disable interrupt */ - level = rt_hw_interrupt_disable(); + size = length; + while (length) + { + /* + * to be polite with serial console add a line feed + * to the carriage return character + */ + if (*data == '\n' && (serial->parent.flag & RT_DEVICE_FLAG_STREAM)) + { + serial->ops->putc(serial, '\r'); + } + + serial->ops->putc(serial, *data); + + ++ data; + -- length; + } - rbuffer->buffer[rbuffer->put_index] = ch; - rbuffer->put_index = (rbuffer->put_index + 1) & (RT_SERIAL_RB_BUFSZ - 1); - - /* if the next position is read index, discard this 'read char' */ - if (rbuffer->put_index == rbuffer->get_index) - { - rbuffer->get_index = (rbuffer->get_index + 1) & (RT_SERIAL_RB_BUFSZ - 1); - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); + return size - length; } -rt_inline int serial_ringbuffer_putchar(struct serial_ringbuffer *rbuffer, - char ch) +/* + * Serial interrupt routines + */ +rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) { - rt_base_t level; - rt_uint16_t next_index; + int size; + struct rt_serial_rx_fifo* rx_fifo; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); + RT_ASSERT(serial != RT_NULL); + size = length; + + rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); - next_index = (rbuffer->put_index + 1) & (RT_SERIAL_RB_BUFSZ - 1); - if (next_index != rbuffer->get_index) - { - rbuffer->buffer[rbuffer->put_index] = ch; - rbuffer->put_index = next_index; - } - else - { - /* enable interrupt */ - rt_hw_interrupt_enable(level); + /* read from software FIFO */ + while (length) + { + int ch; + rt_base_t level; - return -1; - } + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + if (rx_fifo->get_index != rx_fifo->put_index) + { + ch = rx_fifo->buffer[rx_fifo->get_index]; + rx_fifo->get_index += 1; + if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; + } + else + { + /* no data, enable interrupt and break out */ + rt_hw_interrupt_enable(level); + break; + } - /* enable interrupt */ - rt_hw_interrupt_enable(level); + /* enable interrupt */ + rt_hw_interrupt_enable(level); - return 1; + *data = ch & 0xff; + data ++; length --; + } + + return size - length; } -rt_inline int serial_ringbuffer_getc(struct serial_ringbuffer *rbuffer) +rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) { - int ch; - rt_base_t level; + int size; + struct rt_serial_tx_fifo *tx; + + RT_ASSERT(serial != RT_NULL); - ch = -1; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - if (rbuffer->get_index != rbuffer->put_index) - { - ch = rbuffer->buffer[rbuffer->get_index]; - rbuffer->get_index = (rbuffer->get_index + 1) & (RT_SERIAL_RB_BUFSZ - 1); - } - /* enable interrupt */ - rt_hw_interrupt_enable(level); + size = length; + tx = (struct rt_serial_tx_fifo*) serial->serial_tx; + RT_ASSERT(tx != RT_NULL); - return ch; + while (length) + { + if (serial->ops->putc(serial, *(char*)data) == -1) + { + rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER); + continue; + } + + data ++; length --; + } + + return size - length; } -rt_inline rt_uint32_t serial_ringbuffer_size(struct serial_ringbuffer *rbuffer) +/* + * Serial DMA routines + */ +rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) { - rt_uint32_t size; - rt_base_t level; + rt_base_t level; + int result = RT_EOK; + struct rt_serial_rx_dma *rx_dma; - level = rt_hw_interrupt_disable(); - size = (rbuffer->put_index - rbuffer->get_index) & (RT_SERIAL_RB_BUFSZ - 1); - rt_hw_interrupt_enable(level); + RT_ASSERT((serial != RT_NULL) && (data != RT_NULL)); + rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; + RT_ASSERT(rx_dma != RT_NULL); - return size; + level = rt_hw_interrupt_disable(); + if (rx_dma->activated != RT_TRUE) + { + rx_dma->activated = RT_TRUE; + serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX); + } + else result = -RT_EBUSY; + rt_hw_interrupt_enable(level); + + if (result == RT_EOK) return length; + + rt_set_errno(result); + return 0; +} + +rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) +{ + rt_base_t level; + rt_err_t result; + struct rt_serial_tx_dma *tx_dma; + + tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx); + + result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER); + if (result == RT_EOK) + { + level = rt_hw_interrupt_disable(); + if (tx_dma->activated != RT_TRUE) + { + tx_dma->activated = RT_TRUE; + rt_hw_interrupt_enable(level); + + /* make a DMA transfer */ + serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_TX); + } + else + { + rt_hw_interrupt_enable(level); + } + + return length; + } + else + { + rt_set_errno(result); + return 0; + } } /* RT-Thread Device Interface */ - /* - * This function initializes serial + * This function initializes serial device. */ static rt_err_t rt_serial_init(struct rt_device *dev) { @@ -132,58 +225,107 @@ static rt_err_t rt_serial_init(struct rt_device *dev) RT_ASSERT(dev != RT_NULL); serial = (struct rt_serial_device *)dev; - if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) - { - /* apply configuration */ - if (serial->ops->configure) - result = serial->ops->configure(serial, &serial->config); + /* initialize rx/tx */ + serial->serial_rx = RT_NULL; + serial->serial_tx = RT_NULL; - if (result != RT_EOK) - return result; + /* apply configuration */ + if (serial->ops->configure) + result = serial->ops->configure(serial, &serial->config); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - serial_ringbuffer_init(serial->int_rx); - - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - /* not supported yet */ - /* - serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_NULL); - serial_ringbuffer_init(serial->int_tx); - serial->int_sending_flag = RT_FALSE; - */ - } - - if (dev->flag & RT_DEVICE_FLAG_DMA_TX) - { - serial->dma_flag = RT_FALSE; - - /* init data queue */ - rt_data_queue_init(&(serial->tx_dq), RT_SERIAL_TX_DATAQUEUE_SIZE, - RT_SERIAL_TX_DATAQUEUE_LWM, RT_NULL); - } - } - - return result; + return result; } static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) { struct rt_serial_device *serial; - rt_uint32_t int_flags = 0; RT_ASSERT(dev != RT_NULL); serial = (struct rt_serial_device *)dev; - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - int_flags = RT_SERIAL_RX_INT; - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - int_flags |= RT_SERIAL_TX_INT; + /* check device flag with the open flag */ + if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX)) + return -RT_EIO; + if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX)) + return -RT_EIO; + if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX)) + return -RT_EIO; + if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX)) + return -RT_EIO; - if (int_flags) - { - serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)int_flags); - } + /* get open flags */ + dev->open_flag = oflag & 0xff; + + /* initialize the Rx/Tx structure according to open flag */ + if (serial->serial_rx == RT_NULL) + { + if (oflag & RT_DEVICE_FLAG_DMA_RX) + { + struct rt_serial_rx_dma* rx_dma; + + rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma)); + RT_ASSERT(rx_dma != RT_NULL); + rx_dma->activated = RT_FALSE; + + serial->serial_rx = rx_dma; + dev->open_flag |= RT_DEVICE_FLAG_DMA_RX; + } + else if (oflag & RT_DEVICE_FLAG_INT_RX) + { + struct rt_serial_rx_fifo* rx_fifo; + + rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) + + serial->config.bufsz); + RT_ASSERT(rx_fifo != RT_NULL); + rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1); + rt_memset(rx_fifo->buffer, 0, RT_SERIAL_RB_BUFSZ); + rx_fifo->put_index = 0; + rx_fifo->get_index = 0; + + serial->serial_rx = rx_fifo; + dev->open_flag |= RT_DEVICE_FLAG_INT_RX; + /* configure low level device */ + serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX); + } + else + { + serial->serial_rx = RT_NULL; + } + } + + if (serial->serial_tx == RT_NULL) + { + if (oflag & RT_DEVICE_FLAG_DMA_TX) + { + struct rt_serial_tx_dma* tx_dma; + + tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma)); + RT_ASSERT(tx_dma != RT_NULL); + + rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL); + serial->serial_tx = tx_dma; + + dev->open_flag |= RT_DEVICE_FLAG_DMA_TX; + } + else if (oflag & RT_DEVICE_FLAG_INT_TX) + { + struct rt_serial_tx_fifo *tx_fifo; + + tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc(sizeof(struct rt_serial_tx_fifo)); + RT_ASSERT(tx_fifo != RT_NULL); + + rt_completion_init(&(tx_fifo->completion)); + serial->serial_tx = tx_fifo; + + dev->open_flag |= RT_DEVICE_FLAG_INT_TX; + /* configure low level device */ + serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX); + } + else + { + serial->serial_tx = RT_NULL; + } + } return RT_EOK; } @@ -191,20 +333,62 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) static rt_err_t rt_serial_close(struct rt_device *dev) { struct rt_serial_device *serial; - rt_uint32_t int_flags = 0; RT_ASSERT(dev != RT_NULL); serial = (struct rt_serial_device *)dev; - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - int_flags = RT_SERIAL_RX_INT; - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - int_flags |= RT_SERIAL_TX_INT; + /* this device has more reference count */ + if (dev->ref_count > 1) return RT_EOK; + + if (dev->open_flag & RT_DEVICE_FLAG_INT_RX) + { + struct rt_serial_rx_fifo* rx_fifo; - if (int_flags) - { - serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)int_flags); - } + rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + rt_free(rx_fifo); + serial->serial_rx = RT_NULL; + dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX; + /* configure low level device */ + serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX); + } + else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX) + { + struct rt_serial_rx_dma* rx_dma; + + rx_dma = (struct rt_serial_rx_dma*)serial->serial_tx; + RT_ASSERT(rx_dma != RT_NULL); + + rt_free(rx_dma); + serial->serial_rx = RT_NULL; + dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX; + } + + if (dev->open_flag & RT_DEVICE_FLAG_INT_TX) + { + struct rt_serial_tx_fifo* tx_fifo; + + tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_rx; + RT_ASSERT(tx_fifo != RT_NULL); + + rt_free(tx_fifo); + serial->serial_tx = RT_NULL; + dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX; + /* configure low level device */ + serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX); + } + else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX) + { + struct rt_serial_tx_dma* tx_dma; + + tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx; + RT_ASSERT(tx_dma != RT_NULL); + + rt_free(tx_dma); + serial->serial_tx = RT_NULL; + dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX; + } return RT_EOK; } @@ -214,53 +398,23 @@ static rt_size_t rt_serial_read(struct rt_device *dev, void *buffer, rt_size_t size) { - rt_uint8_t *ptr; - rt_uint32_t read_nbytes; struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); - - if (size == 0) - return 0; + if (size == 0) return 0; serial = (struct rt_serial_device *)dev; - ptr = (rt_uint8_t *)buffer; + if (dev->open_flag & RT_DEVICE_FLAG_INT_RX) + { + return _serial_int_rx(serial, buffer, size); + } + else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX) + { + return _serial_dma_rx(serial, buffer, size); + } - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* interrupt mode Rx */ - while (size) - { - int ch; - - ch = serial_ringbuffer_getc(serial->int_rx); - if (ch == -1) - break; - - *ptr = ch & 0xff; - ptr ++; - size --; - } - } - else - { - /* polling mode */ - while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) - { - *ptr = serial->ops->getc(serial); - ptr ++; - } - } - - read_nbytes = (rt_uint32_t)ptr - (rt_uint32_t)buffer; - /* set error code */ - if (read_nbytes == 0) - { - rt_set_errno(-RT_EEMPTY); - } - - return read_nbytes; + return _serial_poll_rx(serial, buffer, size); } static rt_size_t rt_serial_write(struct rt_device *dev, @@ -268,90 +422,23 @@ static rt_size_t rt_serial_write(struct rt_device *dev, const void *buffer, rt_size_t size) { - rt_uint8_t *ptr; - rt_size_t write_nbytes = 0; struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); - - if (size == 0) - return 0; + if (size == 0) return 0; serial = (struct rt_serial_device *)dev; - ptr = (rt_uint8_t*)buffer; + if (dev->open_flag & RT_DEVICE_FLAG_INT_TX) + { + _serial_int_tx(serial, buffer, size); + } + else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX) + { + _serial_dma_tx(serial, buffer, size); + } - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - /* warning: data will be discarded if buffer is full */ - while (size) - { - if (serial_ringbuffer_putchar(serial->int_tx, *ptr) != -1) - { - ptr ++; - size --; - } - else - break; - } - } - else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) - { - rt_base_t level; - rt_err_t result; - - RT_ASSERT(0 == (dev->flag & RT_DEVICE_FLAG_STREAM)); - - result = rt_data_queue_push(&(serial->tx_dq), buffer, size, 20); - if (result == RT_EOK) - { - level = rt_hw_interrupt_disable(); - if (serial->dma_flag == RT_FALSE) - { - serial->dma_flag = RT_TRUE; - rt_hw_interrupt_enable(level); - serial->ops->dma_transmit(serial, buffer, size); - } - else - rt_hw_interrupt_enable(level); - - return size; - } - else - { - rt_set_errno(result); - - return 0; - } - } - else - { - /* polling mode */ - while (size) - { - /* - * to be polite with serial console add a line feed - * to the carriage return character - */ - if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) - { - serial->ops->putc(serial, '\r'); - } - - serial->ops->putc(serial, *ptr); - - ++ ptr; - -- size; - } - } - - write_nbytes = (rt_uint32_t)ptr - (rt_uint32_t)buffer; - if (write_nbytes == 0) - { - rt_set_errno(-RT_EFULL); - } - - return write_nbytes; + return _serial_poll_tx(serial, buffer, size); } static rt_err_t rt_serial_control(struct rt_device *dev, @@ -419,56 +506,108 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, } /* ISR for serial interrupt */ -void rt_hw_serial_isr(struct rt_serial_device *serial) +void rt_hw_serial_isr(struct rt_serial_device *serial, int event) { - int ch = -1; + switch (event & 0xff) + { + case RT_SERIAL_EVENT_RX_IND: + { + int ch = -1; + rt_base_t level; + struct rt_serial_rx_fifo* rx_fifo; - /* interrupt mode receive */ - RT_ASSERT(serial->parent.flag & RT_DEVICE_FLAG_INT_RX); + rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; + RT_ASSERT(rx_fifo != RT_NULL); + + /* interrupt mode receive */ + RT_ASSERT(serial->parent.open_flag & RT_DEVICE_FLAG_INT_RX); + + while (1) + { + ch = serial->ops->getc(serial); + if (ch == -1) break; - while (1) - { - ch = serial->ops->getc(serial); - if (ch == -1) - break; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + rx_fifo->buffer[rx_fifo->put_index] = ch; + rx_fifo->put_index += 1; + if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0; + + /* if the next position is read index, discard this 'read char' */ + if (rx_fifo->put_index == rx_fifo->get_index) + { + rx_fifo->get_index += 1; + if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + + /* invoke callback */ + if (serial->parent.rx_indicate != RT_NULL) + { + rt_size_t rx_length; + + /* get rx length */ + level = rt_hw_interrupt_disable(); + rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index): + (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index)); + rt_hw_interrupt_enable(level); - serial_ringbuffer_putc(serial->int_rx, ch); - } + serial->parent.rx_indicate(&serial->parent, rx_length); + } + break; + } + case RT_SERIAL_EVENT_TX_DONE: + { + struct rt_serial_tx_fifo* tx_fifo; - /* invoke callback */ - if (serial->parent.rx_indicate != RT_NULL) - { - rt_size_t rx_length; + tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx; + rt_completion_done(&(tx_fifo->completion)); + break; + } + case RT_SERIAL_EVENT_TX_DMADONE: + { + const void *data_ptr; + rt_size_t data_size; + const void *last_data_ptr; + struct rt_serial_tx_dma* tx_dma; - /* get rx length */ - rx_length = serial_ringbuffer_size(serial->int_rx); - serial->parent.rx_indicate(&serial->parent, rx_length); - } -} - -/* - * ISR for DMA mode Tx - */ -void rt_hw_serial_dma_tx_isr(struct rt_serial_device *serial) -{ - const void *data_ptr; - rt_size_t data_size; - const void *last_data_ptr; - - rt_data_queue_pop(&(serial->tx_dq), &last_data_ptr, &data_size, 0); - if (RT_EOK == rt_data_queue_peak(&(serial->tx_dq), &data_ptr, &data_size)) - { - /* transmit next data node */ - serial->ops->dma_transmit(serial, data_ptr, data_size); - } - else - { - serial->dma_flag = RT_FALSE; - } - - /* invoke callback */ - if (serial->parent.tx_complete != RT_NULL) - { - serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr); - } + tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx; + + rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0); + if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) + { + /* transmit next data node */ + tx_dma->activated = RT_TRUE; + serial->ops->dma_transmit(serial, data_ptr, data_size, RT_SERIAL_DMA_TX); + } + else + { + tx_dma->activated = RT_FALSE; + } + + /* invoke callback */ + if (serial->parent.tx_complete != RT_NULL) + { + serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr); + } + break; + } + case RT_SERIAL_EVENT_RX_DMADONE: + { + int length; + struct rt_serial_rx_dma* rx_dma; + + rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; + /* get DMA rx length */ + length = (event & (~0xff)) >> 8; + serial->parent.rx_indicate(&(serial->parent), length); + rx_dma->activated = RT_FALSE; + break; + } + } } diff --git a/components/finsh/shell.c b/components/finsh/shell.c index ae099e7e7c..5489cedf3d 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -306,8 +306,8 @@ void finsh_thread_entry(void* parameter) #ifdef RT_USING_CONSOLE shell->device = rt_console_get_device(); RT_ASSERT(shell->device); - rt_device_open(shell->device, RT_DEVICE_OFLAG_RDWR); rt_device_set_rx_indicate(shell->device, finsh_rx_ind); + rt_device_open(shell->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); #else RT_ASSERT(shell->device); #endif