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
+99 -3
View File
@@ -1,7 +1,7 @@
/************************************************************************************
* 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>
*
* 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_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
#define uart_rxflowcontrol(dev,n,u) \
(dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u))
# define uart_rxflowcontrol(dev,n,u) \
(dev->ops->rxflowcontrol && dev->ops->rxflowcontrol(dev,n,u))
#endif
/************************************************************************************
@@ -127,6 +134,17 @@ struct uart_buffer_s
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
* logic. All fields must be provided with non-NULL function pointers by the
* caller of uart_register().
@@ -199,6 +217,24 @@ struct uart_ops_s
unsigned int nbuffered, bool upper);
#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 */
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 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 */
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);
#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
#if defined(__cplusplus)
}