Implement high level DMA infrastructure for serial devices

This commit is contained in:
Max Neklyudov 2015-11-12 14:16:19 -06:00 committed by Gregory Nutt
parent ef59f83a38
commit d54a39832a
6 changed files with 553 additions and 44 deletions

View File

@ -11084,4 +11084,7 @@
* drivers/mtd/mtd_progmem.c: Add an upper half MTD device that can * drivers/mtd/mtd_progmem.c: Add an upper half MTD device that can
use the interfaces defined in included/nuttx/progmem.h to provide use the interfaces defined in included/nuttx/progmem.h to provide
a standard MTD interface (2015-11-12). a standard MTD interface (2015-11-12).
* drivers/serial/serial.c, serialirq.c and include/nuttx/serial/serial.h:
Implement high level DMA infrastructure for serial devices. From
Max Neklyudov (2015-11-12).

@ -1 +1 @@
Subproject commit 758aa6d23647d98fb1a6064175a8abd6c9cc28b2 Subproject commit 4d23ce39bf6bbf3ca0161ff6247fc9fe1610890f

View File

@ -540,6 +540,10 @@ config SERIAL_OFLOWCONTROL
bool bool
default n default n
config SERIAL_DMA
bool
default n
config SERIAL_IFLOWCONTROL_WATERMARKS config SERIAL_IFLOWCONTROL_WATERMARKS
bool "RX flow control watermarks" bool "RX flow control watermarks"
default n default n
@ -762,6 +766,13 @@ config UART_OFLOWCONTROL
---help--- ---help---
Enable UART CTS flow control Enable UART CTS flow control
config UART_DMA
bool "UART DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART
endmenu endmenu
menu "UART0 Configuration" menu "UART0 Configuration"
@ -820,6 +831,13 @@ config UART0_OFLOWCONTROL
---help--- ---help---
Enable UART0 CTS flow control Enable UART0 CTS flow control
config UART0_DMA
bool "UART0 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART0
endmenu endmenu
menu "USART0 Configuration" menu "USART0 Configuration"
@ -878,6 +896,13 @@ config USART0_OFLOWCONTROL
---help--- ---help---
Enable USART0 CTS flow control Enable USART0 CTS flow control
config USART0_DMA
bool "USART0 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART0
endmenu endmenu
menu "UART1 Configuration" menu "UART1 Configuration"
@ -936,6 +961,13 @@ config UART1_OFLOWCONTROL
---help--- ---help---
Enable UART1 CTS flow control Enable UART1 CTS flow control
config UART1_DMA
bool "UART1 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART1
endmenu endmenu
menu "USART1 Configuration" menu "USART1 Configuration"
@ -994,6 +1026,13 @@ config USART1_OFLOWCONTROL
---help--- ---help---
Enable USART1 CTS flow control Enable USART1 CTS flow control
config USART1_DMA
bool "USART1 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART1
endmenu endmenu
menu "UART2 Configuration" menu "UART2 Configuration"
@ -1052,6 +1091,13 @@ config UART2_OFLOWCONTROL
---help--- ---help---
Enable UART2 CTS flow control Enable UART2 CTS flow control
config UART2_DMA
bool "UART2 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART2
endmenu endmenu
menu "USART2 Configuration" menu "USART2 Configuration"
@ -1110,6 +1156,12 @@ config USART2_OFLOWCONTROL
---help--- ---help---
Enable USART2 CTS flow control Enable USART2 CTS flow control
config USART2_DMA
bool "USART2 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART2
endmenu endmenu
menu "UART3 Configuration" menu "UART3 Configuration"
@ -1168,6 +1220,13 @@ config UART3_OFLOWCONTROL
---help--- ---help---
Enable UART3 CTS flow control Enable UART3 CTS flow control
config UART3_DMA
bool "UART3 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART3
endmenu endmenu
menu "USART3 Configuration" menu "USART3 Configuration"
@ -1226,6 +1285,13 @@ config USART3_OFLOWCONTROL
---help--- ---help---
Enable USART3 CTS flow control Enable USART3 CTS flow control
config USART3_DMA
bool "USART3 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART3
endmenu endmenu
menu "UART4 Configuration" menu "UART4 Configuration"
@ -1284,6 +1350,13 @@ config UART4_OFLOWCONTROL
---help--- ---help---
Enable UART4 CTS flow control Enable UART4 CTS flow control
config UART4_DMA
bool "UART4 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART4
endmenu endmenu
menu "USART4 Configuration" menu "USART4 Configuration"
@ -1342,6 +1415,13 @@ config USART4_OFLOWCONTROL
---help--- ---help---
Enable USART4 CTS flow control Enable USART4 CTS flow control
config USART4_DMA
bool "USART4 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART4
endmenu endmenu
menu "UART5 Configuration" menu "UART5 Configuration"
@ -1400,6 +1480,13 @@ config UART5_OFLOWCONTROL
---help--- ---help---
Enable UART5 CTS flow control Enable UART5 CTS flow control
config UART5_DMA
bool "UART5 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART5
endmenu endmenu
menu "USART5 Configuration" menu "USART5 Configuration"
@ -1458,6 +1545,13 @@ config USART5_OFLOWCONTROL
---help--- ---help---
Enable USART5 CTS flow control Enable USART5 CTS flow control
config USART5_DMA
bool "USART5 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART5
endmenu endmenu
menu "USART6 Configuration" menu "USART6 Configuration"
@ -1516,6 +1610,13 @@ config USART6_OFLOWCONTROL
---help--- ---help---
Enable USART6 CTS flow control Enable USART6 CTS flow control
config USART6_DMA
bool "USART6 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART6
endmenu endmenu
menu "UART6 Configuration" menu "UART6 Configuration"
@ -1574,6 +1675,13 @@ config UART6_OFLOWCONTROL
---help--- ---help---
Enable UART6 CTS flow control Enable UART6 CTS flow control
config UART6_DMA
bool "UART6 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART6
endmenu endmenu
menu "USART7 Configuration" menu "USART7 Configuration"
@ -1632,6 +1740,13 @@ config USART7_OFLOWCONTROL
---help--- ---help---
Enable USART7 CTS flow control Enable USART7 CTS flow control
config USART7_DMA
bool "USART7 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART7
endmenu endmenu
menu "UART7 Configuration" menu "UART7 Configuration"
@ -1690,6 +1805,13 @@ config UART7_OFLOWCONTROL
---help--- ---help---
Enable UART7 CTS flow control Enable UART7 CTS flow control
config UART7_DMA
bool "UART7 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART7
endmenu endmenu
menu "USART8 Configuration" menu "USART8 Configuration"
@ -1748,6 +1870,13 @@ config USART8_OFLOWCONTROL
---help--- ---help---
Enable USART8 CTS flow control Enable USART8 CTS flow control
config USART8_DMA
bool "USART8 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on USART8
endmenu endmenu
menu "UART8 Configuration" menu "UART8 Configuration"
@ -1806,6 +1935,13 @@ config UART8_OFLOWCONTROL
---help--- ---help---
Enable UART8 CTS flow control Enable UART8 CTS flow control
config UART8_DMA
bool "UART8 DMA support"
default n
select SERIAL_DMA
---help---
Enable DMA transfers on UART8
endmenu endmenu
menu "SCI0 Configuration" menu "SCI0 Configuration"

View File

@ -249,6 +249,9 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
*/ */
dev->xmitwaiting = true; dev->xmitwaiting = true;
#ifdef CONFIG_SERIAL_DMA
uart_dmatxavail(dev);
#endif
uart_enabletxint(dev); uart_enabletxint(dev);
ret = uart_takesem(&dev->xmitsem, true); ret = uart_takesem(&dev->xmitsem, true);
uart_disabletxint(dev); uart_disabletxint(dev);
@ -507,6 +510,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer,
if (dev->xmit.head != dev->xmit.tail) if (dev->xmit.head != dev->xmit.tail)
{ {
#ifdef CONFIG_SERIAL_DMA
uart_dmatxavail(dev);
#endif
uart_enabletxint(dev); uart_enabletxint(dev);
} }
@ -707,6 +713,20 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
*/ */
flags = irqsave(); flags = irqsave();
#ifdef CONFIG_SERIAL_DMA
/* If RX buffer is empty move tail and head to zero position */
if (rxbuf->head == rxbuf->tail)
{
rxbuf->head = rxbuf->tail = 0;
}
/* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev);
#endif
uart_enablerxint(dev); uart_enablerxint(dev);
#ifdef CONFIG_SERIAL_REMOVABLE #ifdef CONFIG_SERIAL_REMOVABLE
@ -778,6 +798,27 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
} }
} }
#ifdef CONFIG_SERIAL_DMA
flags = irqsave();
/* If RX buffer is empty move tail and head to zero position */
if (rxbuf->head == rxbuf->tail)
{
rxbuf->head = rxbuf->tail = 0;
}
irqrestore(flags);
/* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev);
/* RX interrupt could be disabled by RX buffer overflow. Enable it now. */
uart_enablerxint(dev);
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
/* How many bytes are now buffered */ /* How many bytes are now buffered */
@ -1281,6 +1322,12 @@ static int uart_open(FAR struct file *filep)
} }
#endif #endif
#ifdef CONFIG_SERIAL_DMA
/* Notify DMA that there is free space in the RX buffer */
uart_dmarxfree(dev);
#endif
/* Enable the RX interrupt */ /* Enable the RX interrupt */
uart_enablerxint(dev); uart_enablerxint(dev);

View File

@ -1,7 +1,7 @@
/************************************************************************************ /************************************************************************************
* drivers/serial/serialirq.c * drivers/serial/serialirq.c
* *
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -65,10 +65,269 @@
* Private Functions * Private Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************
* Name: uart_dorxflowcontrol
*
* Description:
* Handle RX flow control using watermark levels or not
*
************************************************************************************/
#ifdef CONFIG_SERIAL_IFLOWCONTROL
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
static inline bool uart_dorxflowcontrol(FAR uart_dev_t *dev,
FAR struct uart_buffer_s *rxbuf,
unsigned int watermark)
{
unsigned int nbuffered;
/* How many bytes are buffered */
if (rxbuf->head >= rxbuf->tail)
{
nbuffered = rxbuf->head - rxbuf->tail;
}
else
{
nbuffered = rxbuf->size - rxbuf->tail + rxbuf->head;
}
/* Is the level now above the watermark level that we need to report? */
if (nbuffered >= watermark)
{
/* Let the lower level driver know that the watermark level has been
* crossed. It will probably activate RX flow control.
*/
if (uart_rxflowcontrol(dev, nbuffered, true))
{
/* Low-level driver activated RX flow control, exit loop now. */
return true;
}
}
return false;
}
#else
static inline bool uart_dorxflowcontrol(FAR uart_dev_t *dev,
FAR struct uart_buffer_s *rxbuf,
bool is_full)
{
/* Check if RX buffer is full and allow serial low-level driver to pause
* processing. This allows proper utilization of hardware flow control.
*/
if (is_full)
{
if (uart_rxflowcontrol(dev, rxbuf->size, true))
{
/* Low-level driver activated RX flow control, exit loop now. */
return true;
}
}
return false;
}
#endif
#endif
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************
* Name: uart_xmitchars_dma
*
* Description:
* Set up to transfer bytes from the TX circular buffer using DMA
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_xmitchars_dma(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmatx;
if (dev->xmit.head == dev->xmit.tail)
{
/* No data to transfer. */
return;
}
if (dev->xmit.tail < dev->xmit.head)
{
xfer->buffer = &dev->xmit.buffer[dev->xmit.tail];
xfer->length = dev->xmit.head - dev->xmit.tail;
xfer->nbuffer = NULL;
xfer->nlength = 0;
}
else
{
xfer->buffer = &dev->xmit.buffer[dev->xmit.tail];
xfer->length = dev->xmit.size - dev->xmit.tail;
xfer->nbuffer = dev->xmit.buffer;
xfer->nlength = dev->xmit.head;
}
uart_dmasend(dev);
}
#endif /* CONFIG_SERIAL_DMA */
/************************************************************************************
* Name: uart_xmitchars_done
*
* Description:
* Perform operations necessary at the complete of DMA including adjusting the
* TX circular buffer indices and waking up of any threads that may have been
* waiting for space to become available in the TX circular buffer.
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_xmitchars_done(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmatx;
size_t nbytes = xfer->nbytes;
struct uart_buffer_s *txbuf = &dev->xmit;
/* Move tail for nbytes. */
txbuf->tail = (txbuf->tail + nbytes) % txbuf->size;
xfer->nbytes = 0;
xfer->length = xfer->nlength = 0;
/* If any bytes were removed from the buffer, inform any waiters there there is
* space available.
*/
if (nbytes)
{
uart_datasent(dev);
}
}
#endif /* CONFIG_SERIAL_DMA */
/************************************************************************************
* Name: uart_recvchars_dma
*
* Description:
* Set up to receive bytes into the RX circular buffer using DMA
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_recvchars_dma(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
FAR struct uart_buffer_s *rxbuf = &dev->recv;
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
unsigned int watermark;
#endif
bool is_full;
int nexthead = rxbuf->head + 1;
if (nexthead >= rxbuf->size)
{
nexthead = 0;
}
is_full = nexthead == rxbuf->tail;
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
/* Pre-calcuate the watermark level that we will need to test against. */
watermark = (CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK * rxbuf->size) / 100;
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
if (uart_dorxflowcontrol(dev, rxbuf, watermark))
{
return;
}
#else
if (uart_dorxflowcontrol(dev, rxbuf, is_full))
{
return;
}
#endif
#endif
if (is_full)
{
/* If there is no free space in receive buffer we cannot start DMA
* transfer.
*/
return;
}
if (rxbuf->tail <= rxbuf->head)
{
xfer->buffer = &rxbuf->buffer[rxbuf->head];
xfer->nbuffer = rxbuf->buffer;
if (rxbuf->tail > 0)
{
xfer->length = rxbuf->size - rxbuf->head;
xfer->nlength = rxbuf->tail - 1;
}
else
{
xfer->length = rxbuf->size - rxbuf->head - 1;
xfer->nlength = 0;
}
}
else
{
xfer->buffer = &rxbuf->buffer[rxbuf->head];
xfer->length = rxbuf->tail - rxbuf->head - 1;
xfer->nbuffer = NULL;
xfer->nlength = 0;
}
uart_dmareceive(dev);
}
#endif /* CONFIG_SERIAL_DMA */
/************************************************************************************
* Name: uart_recvchars_done
*
* Description:
* Perform operations necessary at the complete of DMA including adjusting the
* RX circular buffer indices and waking up of any threads that may have been
* waiting for new data to become available in the RX circular buffer.
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_recvchars_done(FAR uart_dev_t *dev)
{
FAR struct uart_dmaxfer_s *xfer = &dev->dmarx;
FAR struct uart_buffer_s *rxbuf = &dev->recv;
size_t nbytes = xfer->nbytes;
/* Move head for nbytes. */
rxbuf->head = (rxbuf->head + nbytes) % rxbuf->size;
xfer->nbytes = 0;
xfer->length = xfer->nlength = 0;
/* If any bytes were added to the buffer, inform any waiters there is new
* incoming data available.
*/
if (nbytes)
{
uart_datareceived(dev);
}
}
#endif /* CONFIG_SERIAL_DMA */
/************************************************************************************ /************************************************************************************
* Name: uart_xmitchars * Name: uart_xmitchars
* *
@ -145,6 +404,7 @@ void uart_recvchars(FAR uart_dev_t *dev)
unsigned int status; unsigned int status;
int nexthead = rxbuf->head + 1; int nexthead = rxbuf->head + 1;
uint16_t nbytes = 0; uint16_t nbytes = 0;
bool is_full;
if (nexthead >= rxbuf->size) if (nexthead >= rxbuf->size)
{ {
@ -163,52 +423,19 @@ void uart_recvchars(FAR uart_dev_t *dev)
while (uart_rxavailable(dev)) while (uart_rxavailable(dev))
{ {
bool is_full = (nexthead == rxbuf->tail); is_full = (nexthead == rxbuf->tail);
char ch; char ch;
#ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
unsigned int nbuffered; if (uart_dorxflowcontrol(dev, rxbuf, watermark))
/* How many bytes are buffered */
if (rxbuf->head >= rxbuf->tail)
{ {
nbuffered = rxbuf->head - rxbuf->tail; break;
}
else
{
nbuffered = rxbuf->size - rxbuf->tail + rxbuf->head;
}
/* Is the level now above the watermark level that we need to report? */
if (nbuffered >= watermark)
{
/* Let the lower level driver know that the watermark level has been
* crossed. It will probably activate RX flow control.
*/
if (uart_rxflowcontrol(dev, nbuffered, true))
{
/* Low-level driver activated RX flow control, exit loop now. */
break;
}
} }
#else #else
/* Check if RX buffer is full and allow serial low-level driver to pause if (uart_dorxflowcontrol(dev, rxbuf, is_full))
* processing. This allows proper utilization of hardware flow control.
*/
if (is_full)
{ {
if (uart_rxflowcontrol(dev, rxbuf->size, true)) break;
{
/* Low-level driver activated RX flow control, exit loop now. */
break;
}
} }
#endif #endif
#endif #endif
@ -240,7 +467,7 @@ void uart_recvchars(FAR uart_dev_t *dev)
} }
} }
/* If any bytes were added to the buffer, inform any waiters there there is new /* If any bytes were added to the buffer, inform any waiters there is new
* incoming data available. * incoming data available.
*/ */

View File

@ -1,7 +1,7 @@
/************************************************************************************ /************************************************************************************
* include/nuttx/serial/serial.h * include/nuttx/serial/serial.h
* *
* Copyright (C) 2007-2008, 2012-2014 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2008, 2012-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -104,9 +104,16 @@
#define uart_send(dev,ch) dev->ops->send(dev,ch) #define uart_send(dev,ch) dev->ops->send(dev,ch)
#define uart_receive(dev,s) dev->ops->receive(dev,s) #define uart_receive(dev,s) dev->ops->receive(dev,s)
#ifdef CONFIG_SERIAL_DMA
# define uart_dmasend(dev) dev->ops->dmasend(dev)
# define uart_dmareceive(dev) dev->ops->dmareceive(dev)
# define uart_dmarxfree(dev) dev->ops->dmarxfree(dev)
# define uart_dmatxavail(dev) dev->ops->dmatxavail(dev)
#endif
#ifdef CONFIG_SERIAL_IFLOWCONTROL #ifdef CONFIG_SERIAL_IFLOWCONTROL
#define uart_rxflowcontrol(dev,n,u) \ # define uart_rxflowcontrol(dev,n,u) \
(dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u)) (dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u))
#endif #endif
/************************************************************************************ /************************************************************************************
@ -127,6 +134,17 @@ struct uart_buffer_s
FAR char *buffer; /* Pointer to the allocated buffer memory */ FAR char *buffer; /* Pointer to the allocated buffer memory */
}; };
#ifdef CONFIG_SERIAL_DMA
struct uart_dmaxfer_s
{
FAR char *buffer; /* First DMA buffer */
FAR char *nbuffer; /* Next DMA buffer */
size_t length; /* Length of first DMA buffer */
size_t nlength; /* Length of next DMA buffer */
size_t nbytes; /* Bytes actually transferred by DMA from both buffers */
};
#endif /* CONFIG_SERIAL_DMA */
/* This structure defines all of the operations providd by the architecture specific /* 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 * logic. All fields must be provided with non-NULL function pointers by the
* caller of uart_register(). * caller of uart_register().
@ -199,6 +217,24 @@ struct uart_ops_s
unsigned int nbuffered, bool upper); unsigned int nbuffered, bool upper);
#endif #endif
#ifdef CONFIG_SERIAL_DMA
/* Start transfer bytes from the TX circular buffer using DMA */
CODE void (*dmasend)(FAR struct uart_dev_s *dev);
/* Start transfer bytes from the TX circular buffer using DMA */
CODE void (*dmareceive)(FAR struct uart_dev_s *dev);
/* Notify DMA that there is free space in the RX buffer */
CODE void (*dmarxfree)(FAR struct uart_dev_s *dev);
/* Notify DMA that there is data to be transferred in the TX buffer */
CODE void (*dmatxavail)(FAR struct uart_dev_s *dev);
#endif
/* This method will send one byte on the UART */ /* This method will send one byte on the UART */
CODE void (*send)(FAR struct uart_dev_s *dev, int ch); CODE void (*send)(FAR struct uart_dev_s *dev, int ch);
@ -266,6 +302,14 @@ struct uart_dev_s
struct uart_buffer_s xmit; /* Describes transmit buffer */ struct uart_buffer_s xmit; /* Describes transmit buffer */
struct uart_buffer_s recv; /* Describes receive buffer */ struct uart_buffer_s recv; /* Describes receive buffer */
#ifdef CONFIG_SERIAL_DMA
/* DMA transfers */
struct uart_dmaxfer_s dmatx; /* Describes transmit DMA transfer */
struct uart_dmaxfer_s dmarx; /* Describes receive DMA transfer */
#endif
/* Driver interface */ /* Driver interface */
FAR const struct uart_ops_s *ops; /* Arch-specific operations */ FAR const struct uart_ops_s *ops; /* Arch-specific operations */
@ -385,6 +429,58 @@ void uart_datasent(FAR uart_dev_t *dev);
void uart_connected(FAR uart_dev_t *dev, bool connected); void uart_connected(FAR uart_dev_t *dev, bool connected);
#endif #endif
/************************************************************************************
* Name: uart_xmitchars_dma
*
* Description:
* Set up to transfer bytes from the TX circular buffer using DMA
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_xmitchars_dma(FAR uart_dev_t *dev);
#endif
/************************************************************************************
* Name: uart_xmitchars_done
*
* Description:
* Perform operations necessary at the complete of DMA including adjusting the
* TX circular buffer indices and waking up of any threads that may have been
* waiting for space to become available in the TX circular buffer.
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_xmitchars_done(FAR uart_dev_t *dev);
#endif
/************************************************************************************
* Name: uart_recvchars_dma
*
* Description:
* Set up to receive bytes into the RX circular buffer using DMA
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_recvchars_dma(FAR uart_dev_t *dev);
#endif
/************************************************************************************
* Name: uart_recvchars_done
*
* Description:
* Perform operations necessary at the complete of DMA including adjusting the
* RX circular buffer indices and waking up of any threads that may have been
* waiting for new data to become available in the RX circular buffer.
*
************************************************************************************/
#ifdef CONFIG_SERIAL_DMA
void uart_recvchars_done(FAR uart_dev_t *dev);
#endif
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
} }