kinetis:Serial use eDMA

kinetis:serial mark priv->rxdma after use
This commit is contained in:
David Sidrane 2021-06-25 14:02:56 -07:00 committed by Xiang Xiao
parent e5a1b2e797
commit 78584b4569
1 changed files with 37 additions and 26 deletions

View File

@ -53,7 +53,7 @@
#include "hardware/kinetis_uart.h"
#include "hardware/kinetis_pinmux.h"
#include "kinetis.h"
#include "kinetis_dma.h"
#include "kinetis_edma.h"
#include "kinetis_uart.h"
/****************************************************************************
@ -270,9 +270,6 @@
# define RXDMA_BUFFER_SIZE ((CONFIG_KINETIS_SERIAL_RXDMA_BUFFER_SIZE \
+ RXDMA_BUFFER_MASK) & ~RXDMA_BUFFER_MASK)
# define SERIAL_DMA_CONTROL_WORD \
(DMA_TCD_CSR_MAJORELINK | \
DMA_TCD_CSR_INTHALF)
#endif /* SERIAL_HAVE_DMA */
/****************************************************************************
@ -306,7 +303,7 @@ struct up_dev_s
#endif
#ifdef SERIAL_HAVE_DMA
const uint8_t rxdma_reqsrc;
DMA_HANDLE rxdma; /* currently-open receive DMA stream */
DMACH_HANDLE rxdma; /* currently-open receive DMA stream */
uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */
char *const rxfifo; /* Receive DMA buffer */
#endif
@ -347,7 +344,8 @@ static void up_dma_shutdown(struct uart_dev_s *dev);
static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status);
static bool up_dma_rxavailable(struct uart_dev_s *dev);
static uint8_t get_and_clear_uart_status(struct up_dev_s *priv);
static void up_dma_rxcallback(DMA_HANDLE handle, void *arg, int result);
static void up_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
int result);
#endif
/****************************************************************************
@ -928,7 +926,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
int result;
uint8_t regval;
DMA_HANDLE rxdma = NULL;
DMACH_HANDLE rxdma = NULL;
/* Do the basic UART setup first, unless we are the console */
@ -943,10 +941,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
/* Acquire the DMA channel. */
rxdma = kinetis_dmachannel(priv->rxdma_reqsrc,
priv->uartbase + KINETIS_UART_D_OFFSET,
KINETIS_DMA_DATA_SZ_8BIT,
KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY);
rxdma = kinetis_dmach_alloc(priv->rxdma_reqsrc | DMAMUX_CHCFG_ENBL, 0);
if (rxdma == NULL)
{
return -EBUSY;
@ -954,8 +949,21 @@ static int up_dma_setup(struct uart_dev_s *dev)
/* Configure for circular DMA reception into the RX FIFO */
kinetis_dmasetup(rxdma, (uint32_t)priv->rxfifo, RXDMA_BUFFER_SIZE,
SERIAL_DMA_CONTROL_WORD);
struct kinetis_edma_xfrconfig_s config;
config.saddr = priv->uartbase + KINETIS_UART_D_OFFSET;
config.daddr = (uint32_t) priv->rxfifo;
config.soff = 0;
config.doff = 1;
config.iter = RXDMA_BUFFER_SIZE;
config.flags = EDMA_CONFIG_LINKTYPE_LINKNONE | EDMA_CONFIG_LOOPDEST;
config.ssize = EDMA_8BIT;
config.dsize = EDMA_8BIT;
config.ttype = EDMA_PERIPH2MEM;
config.nbytes = 1;
#ifdef CONFIG_KINETIS_EDMA_ELINK
config.linkch = NULL;
#endif
kinetis_dmach_xfrsetup(rxdma, &config);
/* Reset our DMA shadow pointer to match the address just programmed
* above.
@ -974,7 +982,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
* worth of time to claim bytes before they are overwritten.
*/
kinetis_dmastart(rxdma, up_dma_rxcallback, (void *)dev);
kinetis_dmach_start(rxdma, up_dma_rxcallback, (void *)dev);
priv->rxdma = rxdma;
return OK;
}
@ -1015,8 +1023,7 @@ static void up_shutdown(struct uart_dev_s *dev)
static void up_dma_shutdown(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
DMA_HANDLE rxdma = priv->rxdma;
priv->rxdma = NULL;
DMACH_HANDLE rxdma = priv->rxdma;
/* Perform the normal UART shutdown */
@ -1024,11 +1031,14 @@ static void up_dma_shutdown(struct uart_dev_s *dev)
/* Stop the DMA channel */
kinetis_dmastop(rxdma);
kinetis_dmach_stop(rxdma);
/* Release the DMA channel */
kinetis_dmafree(rxdma);
kinetis_dmach_free(rxdma);
priv->rxdma = NULL;
}
#endif
@ -1821,7 +1831,7 @@ static int up_dma_nextrx(struct up_dev_s *priv)
{
size_t dmaresidual;
dmaresidual = kinetis_dmaresidual(priv->rxdma);
dmaresidual = kinetis_dmach_getcount(priv->rxdma);
return (RXDMA_BUFFER_SIZE - (int)dmaresidual) % RXDMA_BUFFER_SIZE;
}
@ -1942,7 +1952,8 @@ static bool up_txempty(struct uart_dev_s *dev)
****************************************************************************/
#ifdef SERIAL_HAVE_DMA
static void up_dma_rxcallback(DMA_HANDLE handle, void *arg, int result)
static void up_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
int result)
{
struct uart_dev_s *dev = (struct uart_dev_s *)arg;
@ -2079,42 +2090,42 @@ void kinetis_serial_dma_poll(void)
#ifdef CONFIG_KINETIS_UART0_RXDMA
if (g_uart0priv.rxdma != NULL)
{
up_dma_rxcallback(g_uart0priv.rxdma, (void *)&g_uart0port, 0);
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, 0);
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, 0);
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, 0);
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, 0);
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, 0);
up_dma_rxcallback(g_uart5priv.rxdma, (void *)&g_uart5port, false, 0);
}
#endif