diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c index 3047b1fb6ea..55ab9af370c 100644 --- a/arch/arm/src/kinetis/kinetis_serial.c +++ b/arch/arm/src/kinetis/kinetis_serial.c @@ -1252,22 +1252,6 @@ static int up_interrupts(int irq, void *context, FAR void *arg) uart_xmitchars(dev); handled = true; } - -#if defined(SERIAL_HAVE_DMA) && !defined(CONFIG_KINETIS_UARTFIFOS) - /* Check if the receiver has detected IDLE. If so - * then flush any partail data in the SW rx fifo. - */ - - if ((s1 & UART_S1_IDLE) != 0) - { - up_serialin(priv, KINETIS_UART_D_OFFSET); - up_dma_rxcallback(priv->rxdma, dev , false, 0); - - /* Exit ASAP */ - - handled = false; - } -#endif } return OK; @@ -1689,9 +1673,6 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) #ifndef CONFIG_SUPPRESS_SERIAL_INTS priv->ie |= UART_C2_RIE; -#if defined(SERIAL_HAVE_DMA) && !defined(CONFIG_KINETIS_UARTFIFOS) - priv->ie |= UART_C2_RIE | UART_C2_ILIE; -#endif up_setuartint(priv); #endif } @@ -2087,6 +2068,70 @@ unsigned int kinetis_uart_serialinit(unsigned int first) return first; } +/**************************************************************************** + * Name: kinetis_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void kinetis_serial_dma_poll(void) +{ + irqstate_t flags; + + flags = enter_critical_section(); + +#ifdef CONFIG_KINETIS_UART0_RXDMA + if (g_uart0priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart0priv.rxdma, (void *)&g_uart0port, false, 0); + } +#endif + +#ifdef CONFIG_KINETIS_UART1_RXDMA + if (g_uart1priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart1priv.rxdma, (void *)&g_uart1port, false, 0); + } +#endif + +#ifdef CONFIG_KINETIS_UART2_RXDMA + if (g_uart2priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart2priv.rxdma, (void *)&g_uart2port, false, 0); + } +#endif + +#ifdef CONFIG_KINETIS_UART3_RXDMA + if (g_uart3priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart3priv.rxdma, (void *)&g_uart3port, false, 0); + } +#endif + +#ifdef CONFIG_KINETIS_UART4_RXDMA + if (g_uart4priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart4priv.rxdma, (void *)&g_uart4port, false, 0); + } +#endif + +#ifdef CONFIG_KINETIS_UART5_RXDMA + if (g_uart5priv.rxdma != NULL) + { + up_dma_rxcallback(g_uart5priv.rxdma, (void *)&g_uart5port, false, 0); + } +#endif + + leave_critical_section(flags); +} +#endif + /**************************************************************************** * Name: up_putc * diff --git a/arch/arm/src/kinetis/kinetis_uart.h b/arch/arm/src/kinetis/kinetis_uart.h index 39b9aa9d7ec..f4d396b7001 100644 --- a/arch/arm/src/kinetis/kinetis_uart.h +++ b/arch/arm/src/kinetis/kinetis_uart.h @@ -52,5 +52,51 @@ # endif #endif +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_serial_dma_poll + * + * Description: + * Must be called periodically if any Kinetis UART is configured for DMA. + * The DMA callback is triggered for each fifo size/2 bytes, but this can + * result in some bytes being transferred but not collected if the incoming + * data is not a whole multiple of half the FIFO size. + * + * May be safely called from either interrupt or thread context. + * + ****************************************************************************/ + +#ifdef SERIAL_HAVE_DMA +void kinetis_serial_dma_poll(void); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ #endif /* HAVE_UART_DEVICE && USE_SERIALDRIVER) */ #endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H */