From 49964fe43f25e2d07edc46536ca8107b5e434caf Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 19 May 2015 12:12:53 +0000 Subject: Fixed bug #596. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7988 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/USARTv1/uart_lld.c | 23 +++++++++++++++-------- os/hal/ports/STM32/LLD/USARTv2/uart_lld.c | 23 +++++++++++++++-------- 2 files changed, 30 insertions(+), 16 deletions(-) (limited to 'os/hal/ports') diff --git a/os/hal/ports/STM32/LLD/USARTv1/uart_lld.c b/os/hal/ports/STM32/LLD/USARTv1/uart_lld.c index 44324fc7e..b346dba82 100644 --- a/os/hal/ports/STM32/LLD/USARTv1/uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv1/uart_lld.c @@ -291,12 +291,6 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { dmaStreamDisable(uartp->dmatx); - /* Only enable TC interrupt if there's a callback attached to it. - We have to do it here, rather than earlier, because TC flag is set - until transmission starts.*/ - if (uartp->config->txend2_cb != NULL) - uartp->usart->CR1 |= USART_CR1_TCIE; - /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) @@ -749,11 +743,20 @@ void uart_lld_stop(UARTDriver *uartp) { */ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { - /* TX DMA channel preparation and start.*/ + /* TX DMA channel preparation.*/ dmaStreamSetMemory0(uartp->dmatx, txbuf); dmaStreamSetTransactionSize(uartp->dmatx, n); dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); + + /* Only enable TC interrupt if there's a callback attached to it. + Also we need to clear TC flag which could be set before. */ + if (uartp->config->txend2_cb != NULL) { + uartp->usart->SR = ~USART_SR_TC; + uartp->usart->CR1 |= USART_CR1_TCIE; + } + + /* Starting transfer.*/ dmaStreamEnable(uartp->dmatx); } @@ -771,6 +774,7 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { size_t uart_lld_stop_send(UARTDriver *uartp) { dmaStreamDisable(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); } @@ -790,11 +794,13 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ dmaStreamDisable(uartp->dmarx); - /* RX DMA channel preparation and start.*/ + /* RX DMA channel preparation.*/ dmaStreamSetMemory0(uartp->dmarx, rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, n); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); + + /* Starting transfer.*/ dmaStreamEnable(uartp->dmarx); } @@ -815,6 +821,7 @@ size_t uart_lld_stop_receive(UARTDriver *uartp) { dmaStreamDisable(uartp->dmarx); n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); + return n; } diff --git a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c index 1cce68503..95e80594d 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c @@ -245,12 +245,6 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { dmaStreamDisable(uartp->dmatx); - /* Only enable TC interrupt if there's a callback attached to it. - We have to do it here, rather than earlier, because TC flag is set - until transmission starts.*/ - if (uartp->config->txend2_cb != NULL) - uartp->usart->CR1 |= USART_CR1_TCIE; - /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) @@ -526,11 +520,20 @@ void uart_lld_stop(UARTDriver *uartp) { */ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { - /* TX DMA channel preparation and start.*/ + /* TX DMA channel preparation.*/ dmaStreamSetMemory0(uartp->dmatx, txbuf); dmaStreamSetTransactionSize(uartp->dmatx, n); dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); + + /* Only enable TC interrupt if there's a callback attached to it. + Also we need to clear TC flag which could be set before. */ + if (uartp->config->txend2_cb != NULL) { + uartp->usart->ICR = USART_ICR_TCCF; + uartp->usart->CR1 |= USART_CR1_TCIE; + } + + /* Starting transfer.*/ dmaStreamEnable(uartp->dmatx); } @@ -548,6 +551,7 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { size_t uart_lld_stop_send(UARTDriver *uartp) { dmaStreamDisable(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); } @@ -567,11 +571,13 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ dmaStreamDisable(uartp->dmarx); - /* RX DMA channel preparation and start.*/ + /* RX DMA channel preparation.*/ dmaStreamSetMemory0(uartp->dmarx, rxbuf); dmaStreamSetTransactionSize(uartp->dmarx, n); dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); + + /* Starting transfer.*/ dmaStreamEnable(uartp->dmarx); } @@ -592,6 +598,7 @@ size_t uart_lld_stop_receive(UARTDriver *uartp) { dmaStreamDisable(uartp->dmarx); n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); + return n; } -- cgit v1.2.3