drivers/serial: The upper half serial driver configuration CONFIG_SERIAL_DMA used to enable DMA on both RX and TX streams. This was replaced with CONFIG_SERIAL_RXDMA and CONFIG_SERIAKL_TXDMA which will permit supporting DMA on only one or both streams.

This commit is contained in:
Gregory Nutt 2019-04-24 12:11:40 -06:00
parent 2609b0dff3
commit 0d203fd535
7 changed files with 78 additions and 36 deletions

View File

@ -85,7 +85,11 @@ config SERIAL_OFLOWCONTROL
bool
default n
config SERIAL_DMA
config SERIAL_TXDMA
bool
default n
config SERIAL_RXDMA
bool
default n
@ -466,10 +470,17 @@ config UART_OFLOWCONTROL
---help---
Enable UART CTS flow control
config UART_DMA
bool "UART DMA support"
config UART_TXDMA
bool "UART Tx DMA support"
default n
select SERIAL_DMA
select SERIAL_TXDMA
---help---
Enable DMA transfers on UART
config UART_RXDMA
bool "UART Rx DMA support"
default n
select SERIAL_RXDMA
---help---
Enable DMA transfers on UART

View File

@ -37,7 +37,9 @@
CSRCS += serial.c serial_io.c lowconsole.c
ifeq ($(CONFIG_SERIAL_DMA),y)
ifeq ($(CONFIG_SERIAL_RXDMA),y)
CSRCS += serial_dma.c
else ifeq ($(CONFIG_SERIAL_TXDMA),y)
CSRCS += serial_dma.c
endif

View File

@ -302,7 +302,7 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
* the semaphore.
*/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
uart_dmatxavail(dev);
#endif
uart_enabletxint(dev);
@ -485,7 +485,7 @@ static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout)
* the semaphore.
*/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
uart_dmatxavail(dev);
#endif
uart_enabletxint(dev);
@ -624,7 +624,7 @@ static int uart_open(FAR struct file *filep)
goto errout_with_sem;
}
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
/* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev);
@ -887,7 +887,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
else
{
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
/* Disable all interrupts and test again...
* uart_disablerxint() is insufficient for the check in DMA mode.
*/
@ -910,7 +910,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
* additional data to be received.
*/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
/* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev);
@ -991,7 +991,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
* the loop.
*/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
leave_critical_section(flags);
#else
uart_enablerxint(dev);
@ -1000,7 +1000,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
}
}
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
/* Notify DMA that there is free space in the RX buffer */
flags = enter_critical_section();
@ -1008,7 +1008,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
leave_critical_section(flags);
#endif
#ifndef CONFIG_SERIAL_DMA
#ifndef CONFIG_SERIAL_RXDMA
/* RX interrupt could be disabled by RX buffer overflow. Enable it now. */
uart_enablerxint(dev);
@ -1224,7 +1224,7 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
if (dev->xmit.head != dev->xmit.tail)
{
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
uart_dmatxavail(dev);
#endif
uart_enabletxint(dev);

View File

@ -46,7 +46,7 @@
#include <nuttx/serial/serial.h>
#ifdef CONFIG_SERIAL_DMA
#if defined(CONFIG_SERIAL_TXDMA) || defined(CONFIG_SERIAL_RXDMA)
/************************************************************************************
* Private Functions
@ -105,7 +105,8 @@ static int uart_check_signo(const char *buf, size_t size)
*
************************************************************************************/
#if defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGSTP)
#if defined(CONFIG_SERIAL_RXDMA) && \
(defined(CONFIG_TTY_SIGINT) || defined(CONFIG_TTY_SIGSTP))
static int uart_recvchars_signo(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
@ -144,6 +145,7 @@ static int uart_recvchars_signo(FAR uart_dev_t *dev)
*
************************************************************************************/
#ifdef CONFIG_SERIAL_TXDMA
void uart_xmitchars_dma(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmatx;
@ -172,6 +174,7 @@ void uart_xmitchars_dma(FAR uart_dev_t *dev)
uart_dmasend(dev);
}
#endif
/************************************************************************************
* Name: uart_xmitchars_done
@ -183,6 +186,7 @@ void uart_xmitchars_dma(FAR uart_dev_t *dev)
*
************************************************************************************/
#ifdef CONFIG_SERIAL_TXDMA
void uart_xmitchars_done(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmatx;
@ -204,6 +208,7 @@ void uart_xmitchars_done(FAR uart_dev_t *dev)
uart_datasent(dev);
}
}
#endif
/************************************************************************************
* Name: uart_recvchars_dma
@ -213,6 +218,7 @@ void uart_xmitchars_done(FAR uart_dev_t *dev)
*
************************************************************************************/
#ifdef CONFIG_SERIAL_RXDMA
void uart_recvchars_dma(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
@ -331,6 +337,7 @@ void uart_recvchars_dma(FAR uart_dev_t *dev)
uart_dmareceive(dev);
}
#endif
/************************************************************************************
* Name: uart_recvchars_done
@ -342,6 +349,7 @@ void uart_recvchars_dma(FAR uart_dev_t *dev)
*
************************************************************************************/
#ifdef CONFIG_SERIAL_RXDMA
void uart_recvchars_done(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
@ -383,5 +391,6 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
}
#endif
}
#endif
#endif /* CONFIG_SERIAL_DMA */
#endif /* CONFIG_SERIAL_TXDMA || CONFIG_SERIAL_RXDMA */

View File

@ -103,11 +103,13 @@ static bool u16550_rxavailable(FAR struct uart_dev_s *dev);
static bool u16550_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
bool upper);
#endif
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
static void u16550_dmasend(FAR struct uart_dev_s *dev);
static void u16550_dmatxavail(FAR struct uart_dev_s *dev);
#endif
#ifdef CONFIG_SERIAL_RXDMA
static void u16550_dmareceive(FAR struct uart_dev_s *dev);
static void u16550_dmarxfree(FAR struct uart_dev_s *dev);
static void u16550_dmatxavail(FAR struct uart_dev_s *dev);
#endif
static void u16550_send(FAR struct uart_dev_s *dev, int ch);
static void u16550_txint(FAR struct uart_dev_s *dev, bool enable);
@ -131,10 +133,14 @@ static const struct uart_ops_s g_uart_ops =
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rxflowcontrol = u16550_rxflowcontrol,
#endif
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
.dmasend = u16550_dmasend,
#endif
#ifdef CONFIG_SERIAL_RXDMA
.dmareceive = u16550_dmareceive,
.dmarxfree = u16550_dmarxfree,
#endif
#ifdef CONFIG_SERIAL_TXDMA
.dmatxavail = u16550_dmatxavail,
#endif
.send = u16550_send,
@ -1164,11 +1170,13 @@ static bool u16550_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
*
****************************************************************************/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
static void u16550_dmasend(FAR struct uart_dev_s *dev)
{
}
#endif
#ifdef CONFIG_SERIAL_RXDMA
static void u16550_dmareceive(FAR struct uart_dev_s *dev)
{
}
@ -1176,7 +1184,9 @@ static void u16550_dmareceive(FAR struct uart_dev_s *dev)
static void u16550_dmarxfree(FAR struct uart_dev_s *dev)
{
}
#endif
#ifdef CONFIG_SERIAL_TXDMA
static void u16550_dmatxavail(FAR struct uart_dev_s *dev)
{
}

View File

@ -281,10 +281,14 @@ static const struct uart_ops_s g_uartops =
#ifdef CONFIG_SERIAL_IFLOWCONTROL
cdcuart_rxflowcontrol, /* rxflowcontrol */
#endif
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
NULL, /* dmasend */
#endif
#ifdef CONFIG_SERIAL_RXDMA
NULL, /* dmareceive */
NULL, /* dmarxfree */
#endif
#ifdef CONFIG_SERIAL_TXDMA
NULL, /* dmatxavail */
#endif
NULL, /* send */

View File

@ -105,19 +105,20 @@
#define uart_send(dev,ch) dev->ops->send(dev,ch)
#define uart_receive(dev,s) dev->ops->receive(dev,s)
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
#define uart_dmasend(dev) \
((dev)->ops->dmasend ? (dev)->ops->dmasend(dev) : -ENOSYS)
#define uart_dmatxavail(dev) \
((dev)->ops->dmatxavail ? (dev)->ops->dmatxavail(dev) : -ENOSYS)
#endif
#ifdef CONFIG_SERIAL_RXDMA
#define uart_dmareceive(dev) \
((dev)->ops->dmareceive ? (dev)->ops->dmareceive(dev) : -ENOSYS)
#define uart_dmarxfree(dev) \
((dev)->ops->dmarxfree ? (dev)->ops->dmarxfree(dev) : -ENOSYS)
#define uart_dmatxavail(dev) \
((dev)->ops->dmatxavail ? (dev)->ops->dmatxavail(dev) : -ENOSYS)
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL
@ -143,7 +144,7 @@ struct uart_buffer_s
FAR char *buffer; /* Pointer to the allocated buffer memory */
};
#ifdef CONFIG_SERIAL_DMA
#if defined(CONFIG_SERIAL_RXDMA) || defined(CONFIG_SERIAL_TXDMA)
struct uart_dmaxfer_s
{
FAR char *buffer; /* First DMA buffer */
@ -152,7 +153,7 @@ struct uart_dmaxfer_s
size_t nlength; /* Length of next DMA buffer */
size_t nbytes; /* Bytes actually transferred by DMA from both buffers */
};
#endif /* CONFIG_SERIAL_DMA */
#endif /* CONFIG_SERIAL_RXDMA || CONFIG_SERIAL_TXDMA */
/* This structure defines all of the operations providd by the architecture specific
* logic. All fields must be provided with non-NULL function pointers by the
@ -226,11 +227,13 @@ struct uart_ops_s
unsigned int nbuffered, bool upper);
#endif
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
/* Start transfer bytes from the TX circular buffer using DMA */
CODE void (*dmasend)(FAR struct uart_dev_s *dev);
#endif
#ifdef CONFIG_SERIAL_RXDMA
/* Start transfer bytes from the TX circular buffer using DMA */
CODE void (*dmareceive)(FAR struct uart_dev_s *dev);
@ -238,7 +241,9 @@ struct uart_ops_s
/* Notify DMA that there is free space in the RX buffer */
CODE void (*dmarxfree)(FAR struct uart_dev_s *dev);
#endif
#ifdef CONFIG_SERIAL_TXDMA
/* Notify DMA that there is data to be transferred in the TX buffer */
CODE void (*dmatxavail)(FAR struct uart_dev_s *dev);
@ -314,11 +319,12 @@ struct uart_dev_s
struct uart_buffer_s xmit; /* Describes transmit buffer */
struct uart_buffer_s recv; /* Describes receive buffer */
#ifdef CONFIG_SERIAL_DMA
/* DMA transfers */
#ifdef CONFIG_SERIAL_TXDMA
struct uart_dmaxfer_s dmatx; /* Describes transmit DMA transfer */
#endif
#ifdef CONFIG_SERIAL_RXDMA
struct uart_dmaxfer_s dmarx; /* Describes receive DMA transfer */
#endif
@ -449,7 +455,7 @@ void uart_connected(FAR uart_dev_t *dev, bool connected);
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
void uart_xmitchars_dma(FAR uart_dev_t *dev);
#endif
@ -463,7 +469,7 @@ void uart_xmitchars_dma(FAR uart_dev_t *dev);
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_TXDMA
void uart_xmitchars_done(FAR uart_dev_t *dev);
#endif
@ -475,7 +481,7 @@ void uart_xmitchars_done(FAR uart_dev_t *dev);
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
void uart_recvchars_dma(FAR uart_dev_t *dev);
#endif
@ -489,7 +495,7 @@ void uart_recvchars_dma(FAR uart_dev_t *dev);
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
#ifdef CONFIG_SERIAL_RXDMA
void uart_recvchars_done(FAR uart_dev_t *dev);
#endif