samv7: add support for USART TX DMA transfers

This commit adds support for TX DMA transfers for USART peripheral. Code
refactor in sam_serial.h was also required in order to have correct
defines for all possible cases (both RX and TX DMA used, just one used,
none used).

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
This commit is contained in:
Michal Lenc
2024-03-04 15:14:42 +01:00
committed by Xiang Xiao
parent dcad39a962
commit 44a087111d
5 changed files with 480 additions and 65 deletions
+4 -4
View File
@@ -284,10 +284,10 @@ The peripheral implements four timer counter modules, each supporting three inde
Universal Synchronous Asynchronous Receiver Transceiver (USART)
---------------------------------------------------------------
The MCU supports both UART and USART controllers. USART peripheral can be used with RX DMA support.
For this purpose it is required to configure idle bus timeout value in ``CONFIG_SAMV7_SERIAL_DMA_TIMEOUT``.
This option ensures data are read from the DMA buffer even if it is not full yet. TX DMA support is not
implemented as well as entire DMA support for UART peripheral.
The MCU supports both UART and USART controllers. USART peripheral can be used with TX and RX DMA support.
For RX DMA it is required to configure idle bus timeout value in ``CONFIG_SAMV7_SERIAL_DMA_TIMEOUT``.
This option ensures data are read from the DMA buffer even if it is not full yet. DMA support is
implemented only for USART peripheral and not for UART.
There are several modes in which USART peripheral can operate (ISO7816, IrDA, RS485, SPI, LIN and LON).
Currently RS485 and SPI master are supported by NuttX.
File diff suppressed because it is too large Load Diff
+84 -30
View File
@@ -44,45 +44,99 @@
# define SERIAL_HAVE_RS485 1
#endif
/* Is RX DMA used on the console UART? */
/* Is RX/TX DMA used on the console UART? */
#undef SERIAL_HAVE_CONSOLE_RXDMA
#if defined(CONFIG_USART0_SERIAL_CONSOLE) && defined(CONFIG_USART0_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA
#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA
#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_CONSOLE_RXDMA
#undef SERIAL_HAVE_CONSOLE_DMA
#if defined(CONFIG_USART0_SERIAL_CONSOLE) && \
(defined(CONFIG_USART0_RXDMA) || defined(CONFIG_USART0_TXDMA))
# define SERIAL_HAVE_CONSOLE_DMA
#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && \
(defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART1_TXDMA))
# define SERIAL_HAVE_CONSOLE_DMA
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && \
(defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART2_TXDMA))
# define SERIAL_HAVE_CONSOLE_DMA
#endif
/* RX DMA ops */
/* RX/TX DMA ops */
#undef SERIAL_HAVE_NORXDMA_OPS
#if !defined(CONFIG_USART0_RXDMA) && defined(CONFIG_SAMV7_USART0)
# define SERIAL_HAVE_NORXDMA_OPS
#elif !defined(CONFIG_USART1_RXDMA) && defined(CONFIG_SAMV7_USART1)
# define SERIAL_HAVE_NORXDMA_OPS
#elif !defined(CONFIG_USART2_RXDMA) && defined(CONFIG_SAMV7_USART2)
# define SERIAL_HAVE_NORXDMA_OPS
#endif
#undef SERIAL_HAVE_NOTXDMA_OPS
#if !defined(CONFIG_USART0_TXDMA) && defined(CONFIG_SAMV7_USART0)
# define SERIAL_HAVE_NOTXDMA_OPS
#elif !defined(CONFIG_USART1_TXDMA) && defined(CONFIG_SAMV7_USART1)
# define SERIAL_HAVE_NOTXDMA_OPS
#elif !defined(CONFIG_USART2_TXDMA) && defined(CONFIG_SAMV7_USART2)
# define SERIAL_HAVE_NOTXDMA_OPS
#endif
#undef SERIAL_HAVE_RXTXDMA_OPS
#if defined(CONFIG_USART0_TXDMA) && defined(CONFIG_USART0_RXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART0_TXDMA) && !defined(CONFIG_USART0_RXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART0_TXDMA) && defined(CONFIG_USART0_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#endif
#if defined(CONFIG_USART1_TXDMA) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART1_TXDMA) && !defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART1_TXDMA) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#endif
#if defined(CONFIG_USART2_TXDMA) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_RXTXDMA_OPS
#elif defined(CONFIG_USART2_TXDMA) && !defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_TXDMA_OPS
#elif !defined(CONFIG_USART2_TXDMA) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#endif
/* No DMA ops */
#undef SERIAL_HAVE_NODMA_OPS
#if !defined(CONFIG_USART0_RXDMA) && defined(CONFIG_SAMV7_USART0)
#if !defined(CONFIG_USART0_TXDMA) && !defined(CONFIG_USART0_RXDMA) && \
defined(CONFIG_SAMV7_USART0)
# define SERIAL_HAVE_NODMA_OPS
#elif !defined(CONFIG_USART1_RXDMA) && defined(CONFIG_SAMV7_USART1)
#endif
#if !defined(CONFIG_USART1_TXDMA) && !defined(CONFIG_USART1_RXDMA) && \
defined(CONFIG_SAMV7_USART1)
# define SERIAL_HAVE_NODMA_OPS
#elif !defined(CONFIG_USART2_RXDMA) && defined(CONFIG_SAMV7_USART2)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_SAMV7_UART0)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_SAMV7_UART1)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_SAMV7_UART2)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_SAMV7_UART3)
# define SERIAL_HAVE_NODMA_OPS
#elif defined(CONFIG_SAMV7_UART4)
#endif
#if !defined(CONFIG_USART2_TXDMA) && !defined(CONFIG_USART2_RXDMA) && \
defined(CONFIG_SAMV7_USART2)
# define SERIAL_HAVE_NODMA_OPS
#endif
#undef SERIAL_HAVE_RXDMA_OPS
#if defined(CONFIG_USART0_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#elif defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_RXDMA_OPS
#if defined(CONFIG_SAMV7_UART0)
# define SERIAL_HAVE_NODMA_OPS
# define SERIAL_HAVE_NORXDMA_OPS
# define SERIAL_HAVE_NOTXDMA_OPS
#elif defined(CONFIG_SAMV7_UART1)
# define SERIAL_HAVE_NODMA_OPS
# define SERIAL_HAVE_NORXDMA_OPS
# define SERIAL_HAVE_NOTXDMA_OPS
#elif defined(CONFIG_SAMV7_UART2)
# define SERIAL_HAVE_NODMA_OPS
# define SERIAL_HAVE_NORXDMA_OPS
# define SERIAL_HAVE_NOTXDMA_OPS
#elif defined(CONFIG_SAMV7_UART3)
# define SERIAL_HAVE_NODMA_OPS
# define SERIAL_HAVE_NORXDMA_OPS
# define SERIAL_HAVE_NOTXDMA_OPS
#elif defined(CONFIG_SAMV7_UART4)
# define SERIAL_HAVE_NODMA_OPS
# define SERIAL_HAVE_NORXDMA_OPS
# define SERIAL_HAVE_NOTXDMA_OPS
#endif
/****************************************************************************
@@ -101,7 +155,7 @@
****************************************************************************/
#ifdef SERIAL_HAVE_RXDMA
void sam_serial_dma_poll(void)
void sam_serial_dma_poll(void);
#endif
#endif /* __ARCH_ARM_SRC_SAMV7_SAM_SERIAL_H */
+19
View File
@@ -2118,6 +2118,25 @@ size_t sam_destaddr(DMA_HANDLE handle)
return sam_getdmach(xdmach, SAM_XDMACH_CDA_OFFSET);
}
/****************************************************************************
* Name: sam_dmaresidual
*
* Description:
* Returns the number of bytes remaining to be transferred
*
* Assumptions:
* - DMA handle allocated by sam_dmachannel()
*
****************************************************************************/
size_t sam_dmaresidual(DMA_HANDLE handle)
{
struct sam_xdmach_s *xdmach = (struct sam_xdmach_s *)handle;
uint32_t cubc = sam_getdmach(xdmach, SAM_XDMACH_CUBC_OFFSET);
return cubc & XDMACH_CUBC_UBLEN_MASK;
}
/****************************************************************************
* Name: sam_dmasample
*
+13
View File
@@ -238,6 +238,19 @@ extern "C"
size_t sam_destaddr(DMA_HANDLE handle);
/****************************************************************************
* Name: sam_dmaresidual
*
* Description:
* Returns the number of bytes remaining to be transferred
*
* Assumptions:
* - DMA handle allocated by sam_dmachannel()
*
****************************************************************************/
size_t sam_dmaresidual(DMA_HANDLE handle);
/****************************************************************************
* Name: sam_dmachannel
*