From 14728ff4ae1745b662a8227ff6582f3fdb760acc Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 24 May 2017 08:51:00 +0800 Subject: [PATCH 1/4] [DeviceDriver] Add full flag to rt_serial_rx_fifo. --- components/drivers/include/drivers/serial.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/drivers/include/drivers/serial.h b/components/drivers/include/drivers/serial.h index c7e99ed472..ae6ad5c1fe 100644 --- a/components/drivers/include/drivers/serial.h +++ b/components/drivers/include/drivers/serial.h @@ -122,6 +122,8 @@ struct rt_serial_rx_fifo rt_uint8_t *buffer; rt_uint16_t put_index, get_index; + + rt_bool_t is_full; }; struct rt_serial_tx_fifo From 99911a4c6fecf77f405be039982a34d4f9bf3494 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 24 May 2017 08:59:33 +0800 Subject: [PATCH 2/4] [DeviceDriver] Make uart rx DMA FIFO to use the FIFO full flag. --- components/drivers/serial/serial.c | 43 ++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index cc6a8bfe91..6aa8da6493 100644 --- a/components/drivers/serial/serial.c +++ b/components/drivers/serial/serial.c @@ -168,14 +168,21 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t * */ static rt_size_t rt_dma_calc_recved_len(struct rt_serial_device *serial) { - rt_size_t rx_length; struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); - 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)); - return rx_length; + if (rx_fifo->put_index > rx_fifo->get_index) + return rx_fifo->put_index - rx_fifo->get_index; + else if (rx_fifo->put_index < rx_fifo->get_index) + return serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index); + else + { + if (rx_fifo->is_full) + return serial->config.bufsz; + else + return 0; + } } /** @@ -191,10 +198,12 @@ static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_siz RT_ASSERT(rx_fifo != RT_NULL); RT_ASSERT(len <= rt_dma_calc_recved_len(serial)); + if (rx_fifo->is_full && len != 0) rx_fifo->is_full = RT_FALSE; + rx_fifo->get_index += len; if (rx_fifo->get_index > serial->config.bufsz) { - rx_fifo->get_index -= serial->config.bufsz; + rx_fifo->get_index %= serial->config.bufsz; } } @@ -220,7 +229,8 @@ static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_siz /* force overwrite get index */ if (rx_fifo->put_index >= rx_fifo->get_index) { - rx_fifo->get_index = rx_fifo->put_index + 1; + rx_fifo->get_index = rx_fifo->put_index; + rx_fifo->is_full = RT_TRUE; } } } @@ -235,7 +245,8 @@ static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_siz rx_fifo->put_index %= serial->config.bufsz; } /* force overwrite get index */ - rx_fifo->get_index = rx_fifo->put_index + 1; + rx_fifo->get_index = rx_fifo->put_index; + rx_fifo->is_full = RT_TRUE; } } if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; @@ -252,7 +263,8 @@ rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, level = rt_hw_interrupt_disable(); - if (serial->config.bufsz == 0) { + if (serial->config.bufsz == 0) + { int result = RT_EOK; struct rt_serial_rx_dma *rx_dma; @@ -272,21 +284,23 @@ rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, rt_set_errno(result); return 0; - } else { + } + else + { struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial); RT_ASSERT(rx_fifo != RT_NULL); - if (length < fifo_recved_len) { + if (length < fifo_recved_len) recv_len = length; - } else { + else recv_len = fifo_recved_len; - } - if (rx_fifo->get_index + recv_len < serial->config.bufsz) { + if (rx_fifo->get_index + recv_len < serial->config.bufsz) rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len); - } else { + else + { rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, serial->config.bufsz - rx_fifo->get_index); rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer, @@ -398,6 +412,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) rt_memset(rx_fifo->buffer, 0, serial->config.bufsz); rx_fifo->put_index = 0; rx_fifo->get_index = 0; + rx_fifo->is_full = RT_FALSE; serial->serial_rx = rx_fifo; /* configure fifo address and length to low level device */ serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX); From 9b7d2023bb719ff47a132a964fbe7f423dfd3ef5 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 24 May 2017 09:06:23 +0800 Subject: [PATCH 3/4] [BSP] Fix a bug on stm32f10x uart rx DMA driver when first receive data filled the FIFO. --- bsp/stm32f10x/drivers/usart.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/bsp/stm32f10x/drivers/usart.c b/bsp/stm32f10x/drivers/usart.c index 60f34562ba..898a0135c8 100644 --- a/bsp/stm32f10x/drivers/usart.c +++ b/bsp/stm32f10x/drivers/usart.c @@ -199,15 +199,7 @@ static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) { level = rt_hw_interrupt_disable(); recv_total_index = uart->dma.setting_recv_len - DMA_GetCurrDataCounter(uart->dma.rx_ch); - if (recv_total_index >= uart->dma.last_recv_index) - { - recv_len = recv_total_index - uart->dma.last_recv_index; - } - else - { - recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index + recv_total_index; - } - + recv_len = recv_total_index - uart->dma.last_recv_index; uart->dma.last_recv_index = recv_total_index; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -226,23 +218,15 @@ static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) { */ static void dma_rx_done_isr(struct rt_serial_device *serial) { struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data; - rt_size_t recv_total_index, recv_len; + rt_size_t recv_len; rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); - recv_total_index = uart->dma.setting_recv_len - DMA_GetCurrDataCounter(uart->dma.rx_ch); - if (recv_total_index >= uart->dma.last_recv_index) - { - recv_len = recv_total_index - uart->dma.last_recv_index; - } - else - { - recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index + recv_total_index; - } - - uart->dma.last_recv_index = recv_total_index; + recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index; + /* reset last recv index */ + uart->dma.last_recv_index = 0; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -535,7 +519,7 @@ static void NVIC_Configuration(struct stm32_uart* uart) /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart->irq; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } @@ -577,7 +561,7 @@ static void DMA_Configuration(struct rt_serial_device *serial) { /* rx dma interrupt config */ NVIC_InitStructure.NVIC_IRQChannel = uart->dma.rx_irq_ch; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } From 98c830f3dede0b6d6744167e49e2340ba3416088 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 24 May 2017 09:09:55 +0800 Subject: [PATCH 4/4] [BSP] Fix a bug on stm32f4xx uart rx DMA driver when first receive data filled the FIFO. --- bsp/stm32f40x/drivers/usart.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/bsp/stm32f40x/drivers/usart.c b/bsp/stm32f40x/drivers/usart.c index d9d0f74c6c..d0ce27172c 100644 --- a/bsp/stm32f40x/drivers/usart.c +++ b/bsp/stm32f40x/drivers/usart.c @@ -242,15 +242,7 @@ static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) { level = rt_hw_interrupt_disable(); recv_total_index = uart->dma.setting_recv_len - DMA_GetCurrDataCounter(uart->dma.rx_stream); - if (recv_total_index >= uart->dma.last_recv_index) - { - recv_len = recv_total_index - uart->dma.last_recv_index; - } - else - { - recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index + recv_total_index; - } - + recv_len = recv_total_index - uart->dma.last_recv_index; uart->dma.last_recv_index = recv_total_index; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -269,7 +261,7 @@ static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) { static void dma_rx_done_isr(struct rt_serial_device *serial) { struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data; - rt_size_t recv_total_index, recv_len; + rt_size_t recv_len; rt_base_t level; if (DMA_GetFlagStatus(uart->dma.rx_stream, uart->dma.rx_flag) != RESET) @@ -277,17 +269,9 @@ static void dma_rx_done_isr(struct rt_serial_device *serial) /* disable interrupt */ level = rt_hw_interrupt_disable(); - recv_total_index = uart->dma.setting_recv_len - DMA_GetCurrDataCounter(uart->dma.rx_stream); - if (recv_total_index >= uart->dma.last_recv_index) - { - recv_len = recv_total_index - uart->dma.last_recv_index; - } - else - { - recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index + recv_total_index; - } - - uart->dma.last_recv_index = recv_total_index; + recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index; + /* reset last recv index */ + uart->dma.last_recv_index = 0; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -639,8 +623,8 @@ static void NVIC_Configuration(struct stm32_uart *uart) /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart->irq; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } @@ -668,7 +652,7 @@ static void DMA_Configuration(struct rt_serial_device *serial) { /* rx dma interrupt config */ NVIC_InitStructure.NVIC_IRQChannel = uart->dma.rx_irq_ch; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }