stm32: add support for serial TX DMA

This commit is contained in:
raiden00pl 2021-03-29 09:02:52 +02:00 committed by Alan Carvalho de Assis
parent 0cca102d41
commit 3c34337064
2 changed files with 721 additions and 96 deletions

View File

@ -206,7 +206,7 @@
/* DMA control word */
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
# define SERIAL_DMA_CONTROL_WORD \
# define SERIAL_RXDMA_CONTROL_WORD \
(DMA_SCR_DIR_P2M | \
DMA_SCR_CIRC | \
DMA_SCR_MINC | \
@ -216,7 +216,7 @@
DMA_SCR_PBURST_SINGLE | \
DMA_SCR_MBURST_SINGLE)
# else
# define SERIAL_DMA_CONTROL_WORD \
# define SERIAL_RXDMA_CONTROL_WORD \
(DMA_CCR_CIRC | \
DMA_CCR_MINC | \
DMA_CCR_PSIZE_8BITS | \
@ -224,7 +224,163 @@
CONFIG_USART_RXDMAPRIO)
# endif
#endif
#endif /* SERIAL_HAVE_RXDMA */
#ifdef SERIAL_HAVE_TXDMA
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
/* Verify that DMA has been enabled and the DMA channel has been defined.
*/
# if defined(CONFIG_USART1_TXDMA) || defined(CONFIG_USART6_TXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
# if defined(CONFIG_USART2_TXDMA) || defined(CONFIG_USART3_TXDMA) || \
defined(CONFIG_UART4_TXDMA) || defined(CONFIG_UART5_TXDMA) || \
defined(CONFIG_UART7_TXDMA) || defined(CONFIG_UART8_TXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART2/3/4/5/7/8 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
/* Currently RS-485 support cannot be enabled when TXDMA is in use due to
* lack of testing - RS-485 support was developed on STM32F1x
*/
# if (defined(CONFIG_USART1_TXDMA) && defined(CONFIG_USART1_RS485)) || \
(defined(CONFIG_USART2_TXDMA) && defined(CONFIG_USART2_RS485)) || \
(defined(CONFIG_USART3_TXDMA) && defined(CONFIG_USART3_RS485)) || \
(defined(CONFIG_UART4_TXDMA) && defined(CONFIG_UART4_RS485)) || \
(defined(CONFIG_UART5_TXDMA) && defined(CONFIG_UART5_RS485)) || \
(defined(CONFIG_USART6_TXDMA) && defined(CONFIG_USART6_RS485)) || \
(defined(CONFIG_UART7_TXDMA) && defined(CONFIG_UART7_RS485)) || \
(defined(CONFIG_UART8_TXDMA) && defined(CONFIG_UART8_RS485))
# error "TXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART"
# endif
# if defined(CONFIG_USART1_TXDMA) && !defined(DMAMAP_USART1_TX)
# error "USART1 DMA channel not defined (DMAMAP_USART1_TX)"
# endif
# if defined(CONFIG_USART2_TXDMA) && !defined(DMAMAP_USART2_TX)
# error "USART2 DMA channel not defined (DMAMAP_USART2_TX)"
# endif
# if defined(CONFIG_USART3_TXDMA) && !defined(DMAMAP_USART3_TX)
# error "USART3 DMA channel not defined (DMAMAP_USART3_TX)"
# endif
# if defined(CONFIG_UART4_TXDMA) && !defined(DMAMAP_UART4_TX)
# error "UART4 DMA channel not defined (DMAMAP_UART4_TX)"
# endif
# if defined(CONFIG_UART5_TXDMA) && !defined(DMAMAP_UART5_TX)
# error "UART5 DMA channel not defined (DMAMAP_UART5_TX)"
# endif
# if defined(CONFIG_USART6_TXDMA) && !defined(DMAMAP_USART6_TX)
# error "USART6 DMA channel not defined (DMAMAP_USART6_TX)"
# endif
# if defined(CONFIG_UART7_TXDMA) && !defined(DMAMAP_UART7_TX)
# error "UART7 DMA channel not defined (DMAMAP_UART7_TX)"
# endif
# if defined(CONFIG_UART8_TXDMA) && !defined(DMAMAP_UART8_TX)
# error "UART8 DMA channel not defined (DMAMAP_UART8_TX)"
# endif
# elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
# if defined(CONFIG_USART1_TXDMA) || defined(CONFIG_USART2_TXDMA) || \
defined(CONFIG_USART3_TXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART1/2/3 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
# if defined(CONFIG_UART4_TXDMA) || defined(CONFIG_UART5_TXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 UART4/5 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
# define DMAMAP_USART1_TX DMACHAN_USART1_TX
# define DMAMAP_USART2_TX DMACHAN_USART2_TX
# define DMAMAP_USART3_TX DMACHAN_USART3_TX
# define DMAMAP_UART4_TX DMACHAN_UART4_TX
# define DMAMAP_UART5_TX DMACHAN_UART5_TX
# endif
/* DMA priority */
# ifndef CONFIG_USART_TXDMAPRIO
# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
# define CONFIG_USART_TXDMAPRIO DMA_CCR_PRIMED
# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
# define CONFIG_USART_TXDMAPRIO DMA_SCR_PRIMED
# else
# error "Unknown STM32 DMA"
# endif
# endif
# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
# if (CONFIG_USART_TXDMAPRIO & ~DMA_CCR_PL_MASK) != 0
# error "Illegal value for CONFIG_USART_TXDMAPRIO"
# endif
# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
# if (CONFIG_USART_TXDMAPRIO & ~DMA_SCR_PL_MASK) != 0
# error "Illegal value for CONFIG_USART_TXDMAPRIO"
# endif
# else
# error "Unknown STM32 DMA"
# endif
/* DMA control word */
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
# define SERIAL_TXDMA_CONTROL_WORD \
(DMA_SCR_DIR_M2P | \
DMA_SCR_MINC | \
DMA_SCR_PSIZE_8BITS | \
DMA_SCR_MSIZE_8BITS | \
CONFIG_USART_TXDMAPRIO | \
DMA_SCR_PBURST_SINGLE | \
DMA_SCR_MBURST_SINGLE)
# else
# define SERIAL_TXDMA_CONTROL_WORD \
(DMA_CCR_DIR | \
DMA_CCR_MINC | \
DMA_CCR_PSIZE_8BITS | \
DMA_CCR_MSIZE_8BITS | \
CONFIG_USART_TXDMAPRIO)
# endif
/* DMA ISR status */
# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
# define DMA_ISR_HTIF_BIT DMA_CHAN_HTIF_BIT
# define DMA_ISR_TCIF_BIT DMA_CHAN_TCIF_BIT
# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F4XXX)
# define DMA_ISR_HTIF_BIT DMA_STREAM_HTIF_BIT
# define DMA_ISR_TCIF_BIT DMA_STREAM_TCIF_BIT
# else
# error "Unknown STM32 DMA"
# endif
#endif /* SERIAL_HAVE_TXDMA */
/* Power management definitions */
@ -235,6 +391,14 @@
# define PM_IDLE_DOMAIN 0 /* Revisit */
#endif
/* Since RX DMA or TX DMA or both may be enabled for a given U[S]ART.
* We need runtime detection in up_dma_setup and up_dma_shutdown
* We use the default struct default init value of 0 which maps to
* STM32_DMA_MAP(DMA1,DMA_STREAM0,DMA_CHAN0) which is not a U[S]ART.
*/
#define INVALID_SERIAL_DMA_CHANNEL 0
/* Keep track if a Break was set
*
* Note:
@ -308,6 +472,13 @@ struct up_dev_s
const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */
#endif
/* TX DMA state */
#ifdef SERIAL_HAVE_TXDMA
const unsigned int txdma_channel; /* DMA channel assigned */
DMA_HANDLE txdma; /* currently-open trasnmit DMA stream */
#endif
#ifdef SERIAL_HAVE_RXDMA
const unsigned int rxdma_channel; /* DMA channel assigned */
#endif
@ -338,7 +509,7 @@ static int up_attach(struct uart_dev_s *dev);
static void up_detach(struct uart_dev_s *dev);
static int up_interrupt(int irq, void *context, void *arg);
static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
#ifndef SERIAL_HAVE_ONLY_DMA
#if defined(SERIAL_HAVE_TXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static int up_receive(struct uart_dev_s *dev, unsigned int *status);
static void up_rxint(struct uart_dev_s *dev, bool enable);
static bool up_rxavailable(struct uart_dev_s *dev);
@ -348,12 +519,24 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
bool upper);
#endif
static void up_send(struct uart_dev_s *dev, int ch);
#if defined(SERIAL_HAVE_RXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static void up_txint(struct uart_dev_s *dev, bool enable);
#endif
static bool up_txready(struct uart_dev_s *dev);
#ifdef SERIAL_HAVE_RXDMA
#ifdef SERIAL_HAVE_TXDMA
static void up_dma_send(struct uart_dev_s *dev);
static void up_dma_txint(struct uart_dev_s *dev, bool enable);
static void up_dma_txavailable(struct uart_dev_s *dev);
static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg);
#endif
#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
static int up_dma_setup(struct uart_dev_s *dev);
static void up_dma_shutdown(struct uart_dev_s *dev);
#endif
#ifdef SERIAL_HAVE_RXDMA
static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status);
static void up_dma_rxint(struct uart_dev_s *dev, bool enable);
static bool up_dma_rxavailable(struct uart_dev_s *dev);
@ -372,7 +555,7 @@ static int up_pm_prepare(struct pm_callback_s *cb, int domain,
* Private Data
****************************************************************************/
#ifndef SERIAL_HAVE_ONLY_DMA
#ifdef SERIAL_HAVE_NODMA_OPS
static const struct uart_ops_s g_uart_ops =
{
.setup = up_setup,
@ -393,8 +576,31 @@ static const struct uart_ops_s g_uart_ops =
};
#endif
#ifdef SERIAL_HAVE_RXDMA
static const struct uart_ops_s g_uart_dma_ops =
#ifdef SERIAL_HAVE_RXTXDMA_OPS
static const struct uart_ops_s g_uart_rxtxdma_ops =
{
.setup = up_dma_setup,
.shutdown = up_dma_shutdown,
.attach = up_attach,
.detach = up_detach,
.ioctl = up_ioctl,
.receive = up_dma_receive,
.rxint = up_dma_rxint,
.rxavailable = up_dma_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rxflowcontrol = up_rxflowcontrol,
#endif
.send = up_send,
.txint = up_dma_txint,
.txready = up_txready,
.txempty = up_txready,
.dmatxavail = up_dma_txavailable,
.dmasend = up_dma_send,
};
#endif
#ifdef SERIAL_HAVE_RXDMA_OPS
static const struct uart_ops_s g_uart_rxdma_ops =
{
.setup = up_dma_setup,
.shutdown = up_dma_shutdown,
@ -414,6 +620,29 @@ static const struct uart_ops_s g_uart_dma_ops =
};
#endif
#ifdef SERIAL_HAVE_TXDMA_OPS
static const struct uart_ops_s g_uart_txdma_ops =
{
.setup = up_dma_setup,
.shutdown = up_dma_shutdown,
.attach = up_attach,
.detach = up_detach,
.ioctl = up_ioctl,
.receive = up_receive,
.rxint = up_rxint,
.rxavailable = up_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rxflowcontrol = up_rxflowcontrol,
#endif
.send = up_send,
.txint = up_dma_txint,
.txready = up_txready,
.txempty = up_txready,
.dmatxavail = up_dma_txavailable,
.dmasend = up_dma_send,
};
#endif
/* I/O buffers */
#ifdef CONFIG_STM32_USART1_SERIALDRIVER
@ -500,8 +729,12 @@ static struct up_dev_s g_usart1priv =
.size = CONFIG_USART1_TXBUFSIZE,
.buffer = g_usart1txbuffer,
},
#ifdef CONFIG_USART1_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_USART1_RXDMA) && !defined(CONFIG_USART1_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
#endif
@ -529,6 +762,9 @@ static struct up_dev_s g_usart1priv =
.iflow = true,
.rts_gpio = GPIO_USART1_RTS,
#endif
#ifdef CONFIG_USART1_TXDMA
.txdma_channel = DMAMAP_USART1_TX,
#endif
#ifdef CONFIG_USART1_RXDMA
.rxdma_channel = DMAMAP_USART1_RX,
.rxfifo = g_usart1rxfifo,
@ -565,8 +801,12 @@ static struct up_dev_s g_usart2priv =
.size = CONFIG_USART2_TXBUFSIZE,
.buffer = g_usart2txbuffer,
},
#ifdef CONFIG_USART2_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_USART2_RXDMA) && !defined(CONFIG_USART2_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
#endif
@ -590,6 +830,9 @@ static struct up_dev_s g_usart2priv =
.iflow = true,
.rts_gpio = GPIO_USART2_RTS,
#endif
#ifdef CONFIG_USART2_TXDMA
.txdma_channel = DMAMAP_USART2_TX,
#endif
#ifdef CONFIG_USART2_RXDMA
.rxdma_channel = DMAMAP_USART2_RX,
.rxfifo = g_usart2rxfifo,
@ -626,8 +869,12 @@ static struct up_dev_s g_usart3priv =
.size = CONFIG_USART3_TXBUFSIZE,
.buffer = g_usart3txbuffer,
},
#ifdef CONFIG_USART3_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_USART3_RXDMA) && !defined(CONFIG_USART3_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
#endif
@ -651,6 +898,9 @@ static struct up_dev_s g_usart3priv =
.iflow = true,
.rts_gpio = GPIO_USART3_RTS,
#endif
#ifdef CONFIG_USART3_TXDMA
.txdma_channel = DMAMAP_USART3_TX,
#endif
#ifdef CONFIG_USART3_RXDMA
.rxdma_channel = DMAMAP_USART3_RX,
.rxfifo = g_usart3rxfifo,
@ -687,8 +937,12 @@ static struct up_dev_s g_uart4priv =
.size = CONFIG_UART4_TXBUFSIZE,
.buffer = g_uart4txbuffer,
},
#ifdef CONFIG_UART4_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_UART4_RXDMA) && !defined(CONFIG_UART4_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
#endif
@ -712,6 +966,9 @@ static struct up_dev_s g_uart4priv =
.usartbase = STM32_UART4_BASE,
.tx_gpio = GPIO_UART4_TX,
.rx_gpio = GPIO_UART4_RX,
#ifdef CONFIG_UART4_TXDMA
.txdma_channel = DMAMAP_UART4_TX,
#endif
#ifdef CONFIG_UART4_RXDMA
.rxdma_channel = DMAMAP_UART4_RX,
.rxfifo = g_uart4rxfifo,
@ -748,10 +1005,14 @@ static struct up_dev_s g_uart5priv =
.size = CONFIG_UART5_TXBUFSIZE,
.buffer = g_uart5txbuffer,
},
#ifdef CONFIG_UART5_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_UART5_RXDMA) && !defined(CONFIG_UART5_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
.ops = &g_uart_ops,
#endif
.priv = &g_uart5priv,
},
@ -773,6 +1034,9 @@ static struct up_dev_s g_uart5priv =
.usartbase = STM32_UART5_BASE,
.tx_gpio = GPIO_UART5_TX,
.rx_gpio = GPIO_UART5_RX,
#ifdef CONFIG_UART5_TXDMA
.txdma_channel = DMAMAP_UART5_TX,
#endif
#ifdef CONFIG_UART5_RXDMA
.rxdma_channel = DMAMAP_UART5_RX,
.rxfifo = g_uart5rxfifo,
@ -809,10 +1073,14 @@ static struct up_dev_s g_usart6priv =
.size = CONFIG_USART6_TXBUFSIZE,
.buffer = g_usart6txbuffer,
},
#ifdef CONFIG_USART6_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_USART6_RXDMA) && !defined(CONFIG_USART6_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
.ops = &g_uart_ops,
#endif
.priv = &g_usart6priv,
},
@ -834,6 +1102,9 @@ static struct up_dev_s g_usart6priv =
.iflow = true,
.rts_gpio = GPIO_USART6_RTS,
#endif
#ifdef CONFIG_USART6_TXDMA
.txdma_channel = DMAMAP_USART6_TX,
#endif
#ifdef CONFIG_USART6_RXDMA
.rxdma_channel = DMAMAP_USART6_RX,
.rxfifo = g_usart6rxfifo,
@ -870,10 +1141,14 @@ static struct up_dev_s g_uart7priv =
.size = CONFIG_UART7_TXBUFSIZE,
.buffer = g_uart7txbuffer,
},
#ifdef CONFIG_UART7_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_UART7_RXDMA) && !defined(CONFIG_UART7_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
.ops = &g_uart_ops,
#endif
.priv = &g_uart7priv,
},
@ -895,6 +1170,9 @@ static struct up_dev_s g_uart7priv =
.iflow = true,
.rts_gpio = GPIO_UART7_RTS,
#endif
#ifdef CONFIG_UART7_TXDMA
.txdma_channel = DMAMAP_UART7_TX,
#endif
#ifdef CONFIG_UART7_RXDMA
.rxdma_channel = DMAMAP_UART7_RX,
.rxfifo = g_uart7rxfifo,
@ -931,10 +1209,14 @@ static struct up_dev_s g_uart8priv =
.size = CONFIG_UART8_TXBUFSIZE,
.buffer = g_uart8txbuffer,
},
#ifdef CONFIG_UART8_RXDMA
.ops = &g_uart_dma_ops,
#if defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_TXDMA)
.ops = &g_uart_rxtxdma_ops,
#elif defined(CONFIG_UART8_RXDMA) && !defined(CONFIG_UART8_TXDMA)
.ops = &g_uart_rxdma_ops,
#elif !defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_TXDMA)
.ops = &g_uart_txdma_ops,
#else
.ops = &g_uart_ops,
.ops = &g_uart_ops,
#endif
.priv = &g_uart8priv,
},
@ -956,6 +1238,9 @@ static struct up_dev_s g_uart8priv =
.iflow = true,
.rts_gpio = GPIO_UART8_RTS,
#endif
#ifdef CONFIG_UART8_TXDMA
.txdma_channel = DMAMAP_UART8_TX,
#endif
#ifdef CONFIG_UART8_RXDMA
.rxdma_channel = DMAMAP_UART8_RX,
.rxfifo = g_uart8rxfifo,
@ -1567,12 +1852,11 @@ static int up_setup(struct uart_dev_s *dev)
*
****************************************************************************/
#ifdef SERIAL_HAVE_RXDMA
#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
static int up_dma_setup(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
int result;
uint32_t regval;
/* Do the basic UART setup first, unless we are the console */
@ -1585,36 +1869,54 @@ static int up_dma_setup(struct uart_dev_s *dev)
}
}
#if defined(SERIAL_HAVE_TXDMA)
/* Acquire the Tx DMA channel. This should always succeed. */
if (priv->txdma_channel != INVALID_SERIAL_DMA_CHANNEL)
{
priv->txdma = stm32_dmachannel(priv->txdma_channel);
/* Enable receive Tx DMA for the UART */
modifyreg32(priv->usartbase + STM32_USART_CR3_OFFSET,
0, USART_CR3_DMAT);
}
#endif
#if defined(SERIAL_HAVE_RXDMA)
/* Acquire the DMA channel. This should always succeed. */
priv->rxdma = stm32_dmachannel(priv->rxdma_channel);
if (priv->rxdma_channel != INVALID_SERIAL_DMA_CHANNEL)
{
priv->rxdma = stm32_dmachannel(priv->rxdma_channel);
/* Configure for circular DMA reception into the RX fifo */
/* Configure for circular DMA reception into the RX fifo */
stm32_dmasetup(priv->rxdma,
priv->usartbase + STM32_USART_RDR_OFFSET,
(uint32_t)priv->rxfifo,
RXDMA_BUFFER_SIZE,
SERIAL_DMA_CONTROL_WORD);
stm32_dmasetup(priv->rxdma,
priv->usartbase + STM32_USART_RDR_OFFSET,
(uint32_t)priv->rxfifo,
RXDMA_BUFFER_SIZE,
SERIAL_RXDMA_CONTROL_WORD);
/* Reset our DMA shadow pointer to match the address just
* programmed above.
*/
/* Reset our DMA shadow pointer to match the address just
* programmed above.
*/
priv->rxdmanext = 0;
priv->rxdmanext = 0;
/* Enable receive DMA for the UART */
/* Enable receive Rx DMA for the UART */
regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
regval |= USART_CR3_DMAR;
up_serialout(priv, STM32_USART_CR3_OFFSET, regval);
modifyreg32(priv->usartbase + STM32_USART_CR3_OFFSET,
0, USART_CR3_DMAR);
/* Start the DMA channel, and arrange for callbacks at the half and
* full points in the FIFO. This ensures that we have half a FIFO
* worth of time to claim bytes before they are overwritten.
*/
/* Start the DMA channel, and arrange for callbacks at the half and
* full points in the FIFO. This ensures that we have half a FIFO
* worth of time to claim bytes before they are overwritten.
*/
stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true);
stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true);
}
#endif
return OK;
}
@ -1694,7 +1996,7 @@ static void up_shutdown(struct uart_dev_s *dev)
*
****************************************************************************/
#ifdef SERIAL_HAVE_RXDMA
#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
static void up_dma_shutdown(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
@ -1703,14 +2005,33 @@ static void up_dma_shutdown(struct uart_dev_s *dev)
up_shutdown(dev);
/* Stop the DMA channel */
#if defined(SERIAL_HAVE_RXDMA)
/* Stop the RX DMA channel */
stm32_dmastop(priv->rxdma);
if (priv->rxdma_channel != INVALID_SERIAL_DMA_CHANNEL)
{
stm32_dmastop(priv->rxdma);
/* Release the DMA channel */
/* Release the RX DMA channel */
stm32_dmafree(priv->rxdma);
priv->rxdma = NULL;
stm32_dmafree(priv->rxdma);
priv->rxdma = NULL;
}
#endif
#if defined(SERIAL_HAVE_TXDMA)
/* Stop the TX DMA channel */
if (priv->txdma_channel != INVALID_SERIAL_DMA_CHANNEL)
{
stm32_dmastop(priv->txdma);
/* Release the TX DMA channel */
stm32_dmafree(priv->txdma);
priv->txdma = NULL;
}
#endif
}
#endif
@ -2175,7 +2496,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
*
****************************************************************************/
#ifndef SERIAL_HAVE_ONLY_DMA
#if defined(SERIAL_HAVE_TXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static int up_receive(struct uart_dev_s *dev, unsigned int *status)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
@ -2204,7 +2525,7 @@ static int up_receive(struct uart_dev_s *dev, unsigned int *status)
*
****************************************************************************/
#ifndef SERIAL_HAVE_ONLY_DMA
#if defined(SERIAL_HAVE_TXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static void up_rxint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
@ -2262,7 +2583,7 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
*
****************************************************************************/
#ifndef SERIAL_HAVE_ONLY_DMA
#if defined(SERIAL_HAVE_TXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static bool up_rxavailable(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
@ -2443,6 +2764,121 @@ static bool up_dma_rxavailable(struct uart_dev_s *dev)
}
#endif
/****************************************************************************
* Name: up_dma_txcallback
*
* Description:
* This function clears dma buffer at complete of DMA transfer and wakes up
* threads waiting for space in buffer.
*
****************************************************************************/
#ifdef SERIAL_HAVE_TXDMA
static void up_dma_txcallback(DMA_HANDLE handle, uint8_t status, void *arg)
{
struct up_dev_s *priv = (struct up_dev_s *)arg;
/* Update 'nbytes' indicating number of bytes actually transferred by DMA.
* This is important to free TX buffer space by 'uart_xmitchars_done'.
*/
if (status & DMA_ISR_TCIF_BIT)
{
priv->dev.dmatx.nbytes += priv->dev.dmatx.length;
if (priv->dev.dmatx.nlength)
{
/* Set up DMA on next buffer */
stm32_dmasetup(priv->txdma,
priv->usartbase + STM32_USART_TDR_OFFSET,
(uint32_t) priv->dev.dmatx.nbuffer,
(size_t) priv->dev.dmatx.nlength,
SERIAL_TXDMA_CONTROL_WORD);
/* Set length for the next completion */
priv->dev.dmatx.length = priv->dev.dmatx.nlength;
priv->dev.dmatx.nlength = 0;
/* Start transmission with the callback on DMA completion */
stm32_dmastart(priv->txdma, up_dma_txcallback,
(void *)priv, false);
return;
}
}
else if (status & DMA_ISR_HTIF_BIT)
{
priv->dev.dmatx.nbytes += priv->dev.dmatx.length / 2;
}
/* Adjust the pointers */
uart_xmitchars_done(&priv->dev);
}
#endif
/****************************************************************************
* Name: up_dma_txavailable
*
* Description:
* Informs DMA that Tx data is available and is ready for transfer.
*
****************************************************************************/
#ifdef SERIAL_HAVE_TXDMA
static void up_dma_txavailable(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Only send when the DMA is idle */
if (stm32_dmaresidual(priv->txdma) == 0)
{
uart_xmitchars_dma(dev);
}
}
#endif
/****************************************************************************
* Name: up_dma_send
*
* Description:
* Called (usually) from the interrupt level to start DMA transfer.
* (Re-)Configures DMA Stream updating buffer and buffer length.
*
****************************************************************************/
#ifdef SERIAL_HAVE_TXDMA
static void up_dma_send(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* We need to stop DMA before reconfiguration */
stm32_dmastop(priv->txdma);
/* Reset the number sent */
dev->dmatx.nbytes = 0;
/* Make use of setup function to update buffer and its length for
* next transfer
*/
stm32_dmasetup(priv->txdma,
priv->usartbase + STM32_USART_TDR_OFFSET,
(uint32_t) dev->dmatx.buffer,
(size_t) dev->dmatx.length,
SERIAL_TXDMA_CONTROL_WORD);
/* Start transmission with the callback on DMA completion */
stm32_dmastart(priv->txdma, up_dma_txcallback, (void *)priv, false);
}
#endif
/****************************************************************************
* Name: up_send
*
@ -2464,6 +2900,28 @@ static void up_send(struct uart_dev_s *dev, int ch)
up_serialout(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch);
}
/****************************************************************************
* Name: up_dma_txint
*
* Description:
* Call to enable or disable TX interrupts from the UART.
*
****************************************************************************/
#ifdef SERIAL_HAVE_TXDMA
static void up_dma_txint(struct uart_dev_s *dev, bool enable)
{
/* Nothing to do. */
/* In case of DMA transfer we do not want to make use of UART interrupts.
* Instead, we use DMA interrupts that are activated once during boot
* sequence. Furthermore we can use up_dma_txcallback() to handle staff at
* half DMA transfer or after transfer completion (depending configuration,
* see stm32_dmastart(...) ).
*/
}
#endif
/****************************************************************************
* Name: up_txint
*
@ -2472,6 +2930,7 @@ static void up_send(struct uart_dev_s *dev, int ch)
*
****************************************************************************/
#if defined(SERIAL_HAVE_RXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS)
static void up_txint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
@ -2530,6 +2989,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
leave_critical_section(flags);
}
#endif
/****************************************************************************
* Name: up_txready
@ -2782,7 +3242,7 @@ void arm_serialinit(void)
minor = 1;
#endif
#ifdef SERIAL_HAVE_CONSOLE_DMA
#if defined(SERIAL_HAVE_CONSOLE_RXDMA) || defined(SERIAL_HAVE_CONSOLE_TXDMA)
/* If we need to re-initialise the console to enable DMA do that here. */
up_dma_setup(&g_uart_devs[CONSOLE_UART - 1]->dev);

View File

@ -282,47 +282,63 @@
#if !defined(HAVE_SERIALDRIVER) || !defined(CONFIG_ARCH_DMA)
# undef CONFIG_USART1_RXDMA
# undef CONFIG_USART1_TXDMA
# undef CONFIG_USART2_RXDMA
# undef CONFIG_USART2_TXDMA
# undef CONFIG_USART3_RXDMA
# undef CONFIG_USART3_TXDMA
# undef CONFIG_UART4_RXDMA
# undef CONFIG_UART4_TXDMA
# undef CONFIG_UART5_RXDMA
# undef CONFIG_UART5_TXDMA
# undef CONFIG_USART6_RXDMA
# undef CONFIG_USART6_TXDMA
# undef CONFIG_UART7_RXDMA
# undef CONFIG_UART7_TXDMA
# undef CONFIG_UART8_RXDMA
# undef CONFIG_UART8_TXDMA
#endif
/* Disable the DMA configuration on all unused USARTs */
#ifndef CONFIG_STM32_USART1_SERIALDRIVER
# undef CONFIG_USART1_RXDMA
# undef CONFIG_USART1_TXDMA
#endif
#ifndef CONFIG_STM32_USART2_SERIALDRIVER
# undef CONFIG_USART2_RXDMA
# undef CONFIG_USART2_TXDMA
#endif
#ifndef CONFIG_STM32_USART3_SERIALDRIVER
# undef CONFIG_USART3_RXDMA
# undef CONFIG_USART3_TXDMA
#endif
#ifndef CONFIG_STM32_UART4_SERIALDRIVER
# undef CONFIG_UART4_RXDMA
# undef CONFIG_UART4_TXDMA
#endif
#ifndef CONFIG_STM32_UART5_SERIALDRIVER
# undef CONFIG_UART5_RXDMA
# undef CONFIG_UART5_TXDMA
#endif
#ifndef CONFIG_STM32_USART6_SERIALDRIVER
# undef CONFIG_USART6_RXDMA
# undef CONFIG_USART6_TXDMA
#endif
#ifndef CONFIG_STM32_UART7_SERIALDRIVER
# undef CONFIG_UART7_RXDMA
# undef CONFIG_UART7_TXDMA
#endif
#ifndef CONFIG_STM32_UART8_SERIALDRIVER
# undef CONFIG_UART8_RXDMA
# undef CONFIG_UART8_TXDMA
#endif
/* Is DMA available on any (enabled) USART? */
@ -335,46 +351,195 @@
# define SERIAL_HAVE_RXDMA 1
#endif
/* Is DMA used on the console UART? */
/* Is TX DMA available on any (enabled) USART? */
#undef SERIAL_HAVE_CONSOLE_DMA
#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#undef SERIAL_HAVE_TXDMA
#if defined(CONFIG_USART1_TXDMA) || defined(CONFIG_USART2_TXDMA) || \
defined(CONFIG_USART3_TXDMA) || defined(CONFIG_UART4_TXDMA) || \
defined(CONFIG_UART5_TXDMA) || defined(CONFIG_USART6_TXDMA) || \
defined(CONFIG_UART7_TXDMA) || defined(CONFIG_UART8_TXDMA)
# define SERIAL_HAVE_TXDMA 1
#endif
/* Is DMA used on all (enabled) USARTs */
/* Is RX DMA used on the console UART? */
#define SERIAL_HAVE_ONLY_DMA 1
#if defined(CONFIG_STM32_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_USART2_SERIALDRIVER) && !defined(CONFIG_USART2_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_USART3_SERIALDRIVER) && !defined(CONFIG_USART3_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_UART4_SERIALDRIVER) && !defined(CONFIG_UART4_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_UART5_SERIALDRIVER) && !defined(CONFIG_UART5_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_USART6_SERIALDRIVER) && !defined(CONFIG_USART6_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_UART7_SERIALDRIVER) && !defined(CONFIG_UART7_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32_UART8_SERIALDRIVER) && !defined(CONFIG_UART8_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#undef SERIAL_HAVE_CONSOLE_RXDMA
#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA 1
#endif
/* Is TX DMA used on the console UART? */
#undef SERIAL_HAVE_CONSOLE_TXDMA
#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_USART6_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_UART7_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_UART8_TXDMA)
# define SERIAL_HAVE_CONSOLE_TXDMA 1
#endif
/* Is RX DMA used on all (enabled) USARTs */
#define SERIAL_HAVE_ONLY_RXDMA 1
#if defined(CONFIG_STM32_USART1) && !defined(CONFIG_USART1_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_USART2) && !defined(CONFIG_USART2_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_USART3) && !defined(CONFIG_USART3_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_UART4) && !defined(CONFIG_UART4_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_UART5) && !defined(CONFIG_UART5_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_USART6) && !defined(CONFIG_USART6_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_UART7) && !defined(CONFIG_UART7_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#elif defined(CONFIG_STM32_UART8) && !defined(CONFIG_UART8_RXDMA)
# undef SERIAL_HAVE_ONLY_RXDMA
#endif
/* Is TX DMA used on all (enabled) USARTs */
#define SERIAL_HAVE_ONLY_TXDMA 1
#if defined(CONFIG_STM32_USART1) && !defined(CONFIG_USART1_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_USART2) && !defined(CONFIG_USART2_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_USART3) && !defined(CONFIG_USART3_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_UART4) && !defined(CONFIG_UART4_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_UART5) && !defined(CONFIG_UART5_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_USART6) && !defined(CONFIG_USART6_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_UART7) && !defined(CONFIG_UART7_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#elif defined(CONFIG_STM32_UART8) && !defined(CONFIG_UART8_TXDMA)
# undef SERIAL_HAVE_ONLY_TXDMA
#endif
#undef SERIAL_HAVE_ONLY_DMA
#if defined(SERIAL_HAVE_ONLY_RXDMA) && defined(SERIAL_HAVE_ONLY_TXDMA)
# define SERIAL_HAVE_ONLY_DMA 1
#endif
/* No DMA ops */
#undef SERIAL_HAVE_NODMA_OPS
#if defined(CONFIG_STM32_USART1) && !defined(CONFIG_USART1_RXDMA) && \
!defined(CONFIG_USART1_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_USART2) && !defined(CONFIG_USART2_RXDMA) && \
!defined(CONFIG_USART2_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_USART3) && !defined(CONFIG_USART3_RXDMA) && \
!defined(CONFIG_USART3_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_UART4) && !defined(CONFIG_USART4_RXDMA) && \
!defined(CONFIG_USART4_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_UART5) && !defined(CONFIG_USART5_RXDMA) && \
!defined(CONFIG_USART5_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_USART6) && !defined(CONFIG_USART6_RXDMA) && \
!defined(CONFIG_USART6_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_UART7) && !defined(CONFIG_USART7_RXDMA) && \
!defined(CONFIG_USART7_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_STM32_UART8) && !defined(CONFIG_USART8_RXDMA) && \
!defined(CONFIG_USART8_TXDMA)
# define SERIAL_HAVE_NODMA_OPS
#endif
/* RX+TX DMA ops */
#undef SERIAL_HAVE_RXTXDMA_OPS
#if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART4_RXDMA) && defined(CONFIG_USART4_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART5_RXDMA) && defined(CONFIG_USART5_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART7_RXDMA) && defined(CONFIG_USART7_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART8_RXDMA) && defined(CONFIG_USART8_TXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#endif
/* TX DMA ops */
#undef SERIAL_HAVE_TXDMA_OPS
#if !defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART4_RXDMA) && defined(CONFIG_USART4_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART5_RXDMA) && defined(CONFIG_USART5_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART7_RXDMA) && defined(CONFIG_USART7_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART8_RXDMA) && defined(CONFIG_USART8_TXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#endif
/* RX DMA ops */
#undef SERIAL_HAVE_RXDMA_OPS
#if defined(CONFIG_USART1_RXDMA) && !defined(CONFIG_USART1_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART2_RXDMA) && !defined(CONFIG_USART2_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART3_RXDMA) && !defined(CONFIG_USART3_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART4_RXDMA) && !defined(CONFIG_USART4_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART5_RXDMA) && !defined(CONFIG_USART5_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART6_RXDMA) && !defined(CONFIG_USART6_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART7_RXDMA) && !defined(CONFIG_USART7_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART8_RXDMA) && !defined(CONFIG_USART8_TXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#endif
/* Is RS-485 used? */