Implement serial receive DMA for the F1xx. This is not quite working right yet. Some clients work, others not so much.

This commit is contained in:
px4dev 2013-01-10 01:57:50 -08:00
parent e2f7a46812
commit 469d13fdfe
4 changed files with 100 additions and 36 deletions

View File

@ -95,4 +95,25 @@ __EXPORT void stm32_boardinitialize(void)
stm32_configgpio(GPIO_ADC_VBATT);
stm32_configgpio(GPIO_ADC_IN5);
/* set up the serial DMA polling */
#ifdef SERIAL_HAVE_DMA
{
static struct hrt_call serial_dma_call;
struct timespec ts;
/*
* Poll at 1ms intervals for received bytes that have not triggered
* a DMA event.
*/
ts.tv_sec = 0;
ts.tv_nsec = 1000000;
hrt_call_every(&serial_dma_call,
ts_to_abstime(&ts),
ts_to_abstime(&ts),
(hrt_callout)stm32_serial_dma_poll,
NULL);
}
#endif
}

View File

@ -79,50 +79,74 @@
#if SERIAL_HAVE_DMA
/* Verify that DMA has been enabled an the DMA channel has been defined.
* NOTE: These assignments may only be true for the F4.
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
/* Verify that DMA has been enabled and the DMA channel has been defined.
*/
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART6_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART1/6 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
# endif
# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \
# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \
defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART2/3/4/5 receive DMA requires CONFIG_STM32_DMA1
# ifndef CONFIG_STM32_DMA1
# error STM32 USART2/3/4/5 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
# endif
/* For the F4, there are alternate DMA channels for USART1 and 6.
* Logic in the board.h file make the DMA channel selection by defining
* the following in the board.h file.
*/
# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX)
# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)"
# endif
# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX)
# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)"
# endif
# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX)
# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)"
# endif
# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX)
# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)"
# endif
# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX)
# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)"
# endif
# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX)
# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)"
# endif
# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX)
# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)"
# endif
# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX)
# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)"
# endif
# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX)
# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)"
# endif
# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX)
# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)"
# endif
# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX)
# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)"
# endif
# elif defined(CONFIG_STM32_STM32F10XX)
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \
defined(CONFIG_USART3_RXDMA)
# ifndef CONFIG_STM32_DMA1
# error STM32 USART1/2/3 receive DMA requires CONFIG_STM32_DMA1
# endif
# endif
# if defined(CONFIG_UART4_RXDMA)
# ifndef CONFIG_STM32_DMA2
# error STM32 USART4 receive DMA requires CONFIG_STM32_DMA2
# endif
# endif
/* There are no optional DMA channel assignments for the F1 */
# define DMAMAP_USART1_RX DMACHAN_USART1_RX
# define DMAMAP_USART2_RX DMACHAN_USART2_RX
# define DMAMAP_USART3_RX DMACHAN_USART3_RX
# define DMAMAP_UART4_RX DMACHAN_USART4_RX
# if defined(CONFIG_USART6_RXDMA) && !defined(DMAMAP_USART6_RX)
# error "USART6 DMA channel not defined (DMAMAP_USART6_RX)"
# endif
/* The DMA buffer size when using RX DMA to emulate a FIFO.
@ -156,6 +180,27 @@
# error "Unknown STM32 DMA"
# endif
/* DMA control word */
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
# define SERIAL_DMA_CONTROL_WORD \
(DMA_SCR_DIR_P2M | \
DMA_SCR_CIRC | \
DMA_SCR_MINC | \
DMA_SCR_PSIZE_8BITS | \
DMA_SCR_MSIZE_8BITS | \
CONFIG_USART_DMAPRIO | \
DMA_SCR_PBURST_SINGLE | \
DMA_SCR_MBURST_SINGLE)
# else
# define SERIAL_DMA_CONTROL_WORD \
(DMA_CCR_CIRC | \
DMA_CCR_MINC | \
DMA_CCR_PSIZE_8BITS | \
DMA_CCR_MSIZE_8BITS | \
CONFIG_USART_DMAPRIO)
# endif
#endif
/* Power management definitions */
@ -1037,14 +1082,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
priv->usartbase + STM32_USART_DR_OFFSET,
(uint32_t)priv->rxfifo,
RXDMA_BUFFER_SIZE,
DMA_SCR_DIR_P2M |
DMA_SCR_CIRC |
DMA_SCR_MINC |
DMA_SCR_PSIZE_8BITS |
DMA_SCR_MSIZE_8BITS |
CONFIG_USART_DMAPRIO |
DMA_SCR_PBURST_SINGLE |
DMA_SCR_MBURST_SINGLE);
SERIAL_DMA_CONTROL_WORD);
/* Reset our DMA shadow pointer to match the address just
* programmed above.

View File

@ -145,7 +145,7 @@
* extended to the F1 and F2 with a little effort in the DMA code.
*/
#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) || !defined(CONFIG_STM32_STM32F40XX)
#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA)
# undef CONFIG_USART1_RXDMA
# undef CONFIG_USART2_RXDMA
# undef CONFIG_USART3_RXDMA

View File

@ -188,6 +188,11 @@ CONFIG_USART1_2STOP=0
CONFIG_USART2_2STOP=0
CONFIG_USART3_2STOP=0
CONFIG_USART1_RXDMA=y
SERIAL_HAVE_CONSOLE_DMA=y
CONFIG_USART2_RXDMA=y
CONFIG_USART3_RXDMA=y
#
# PX4IO specific driver settings
#