From d2e9a52cf6b2997b9b6320434ea296bde79b3727 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Aug 2011 08:53:14 +0000 Subject: New DMA helper driver for STM32F1xx and STM32L1xx. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3255 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 2 +- os/hal/platforms/STM32/DMAv1/sdc_lld.c | 86 ++++---- os/hal/platforms/STM32/DMAv1/spi_lld.c | 169 ++++++++------- os/hal/platforms/STM32/DMAv1/spi_lld.h | 32 +-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c | 303 +++++++++++++++++++++++++-- os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h | 33 ++- os/hal/platforms/STM32/DMAv1/uart_lld.c | 180 ++++++++-------- os/hal/platforms/STM32/DMAv1/uart_lld.h | 12 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 6 +- os/hal/platforms/STM32/DMAv2/stm32_dma.h | 19 +- os/hal/platforms/STM32F1xx/adc_lld.c | 50 ++--- os/hal/platforms/STM32F1xx/adc_lld.h | 8 +- readme.txt | 3 + testhal/STM32F1xx/ADC/chconf.h | 12 +- testhal/STM32F1xx/SDIO/chconf.h | 12 +- testhal/STM32F1xx/SPI/chconf.h | 12 +- testhal/STM32F1xx/SPI/mcuconf.h | 2 +- testhal/STM32F1xx/UART/chconf.h | 12 +- testhal/STM32F1xx/UART/main.c | 4 +- testhal/STM32F1xx/UART/mcuconf.h | 4 +- 20 files changed, 632 insertions(+), 329 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 466c48fa6..8de6de823 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -242,7 +242,7 @@ extern "C" { uint8_t *buffer, uint32_t n); bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buffer, uint32_t n); - bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp); + bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.c b/os/hal/platforms/STM32/DMAv1/sdc_lld.c index a88ad53fa..b9e02a815 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.c +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.c @@ -78,15 +78,17 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -100,7 +102,7 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -123,14 +125,14 @@ static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -156,15 +158,17 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for reading.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for reading.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Setting up data transfer. Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ @@ -178,7 +182,7 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Read single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -201,14 +205,14 @@ static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -235,15 +239,17 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write multiple blocks command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -265,7 +271,7 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -282,14 +288,14 @@ static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -316,15 +322,17 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, uint32_t resp[1]; /* Checks for errors and waits for the card to be ready for writing.*/ - if (sdc_wait_for_transfer_state(sdcp)) + if (_sdc_wait_for_transfer_state(sdcp)) return TRUE; /* Prepares the DMA channel for writing.*/ - dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], - SDC_BLOCK_SIZE / sizeof (uint32_t), buf, - (STM32_SDC_SDIO_DMA_PRIORITY << 12) | - DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | - DMA_CCR1_MINC | DMA_CCR1_DIR); + dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); + dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, + SDC_BLOCK_SIZE / sizeof (uint32_t)); + dmaStreamSetMode(STM32_DMA2_STREAM4, + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); /* Write single block command.*/ if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) @@ -346,7 +354,7 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DTEN; /* DMA channel activation.*/ - dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamEnable(STM32_DMA2_STREAM4); /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ @@ -363,14 +371,14 @@ static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, chSysUnlock(); goto error; } - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->DCTRL = 0; chSysUnlock(); return FALSE; error: - dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4); + dmaStreamDisable(STM32_DMA2_STREAM4); SDIO->ICR = 0xFFFFFFFF; SDIO->MASK = 0; SDIO->DCTRL = 0; @@ -431,8 +439,8 @@ void sdc_lld_start(SDCDriver *sdcp) { if (sdcp->state == SDC_STOP) { /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL); - dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO); + dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); + dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); NVICEnableVector(SDIO_IRQn, CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); RCC->AHBENR |= RCC_AHBENR_SDIOEN; @@ -461,7 +469,7 @@ void sdc_lld_stop(SDCDriver *sdcp) { /* Clock deactivation.*/ NVICDisableVector(SDIO_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4); + dmaStreamRelease(STM32_DMA2_STREAM4); } } diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.c b/os/hal/platforms/STM32/DMAv1/spi_lld.c index d8ae657a7..9302b0102 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.c +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.c @@ -67,8 +67,8 @@ static uint16_t dummyrx; * @param[in] spip pointer to the @p SPIDriver object */ #define dma_stop(spip) { \ - dmaChannelDisable(spip->dmatx); \ - dmaChannelDisable(spip->dmarx); \ + dmaStreamDisable(spip->dmatx); \ + dmaStreamDisable(spip->dmarx); \ } /** @@ -91,7 +91,7 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -117,7 +117,7 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_SPI_DMA_ERROR_HOOK) (void)spip; - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_SPI_DMA_ERROR_HOOK(spip); } #else @@ -147,24 +147,24 @@ void spi_lld_init(void) { spiObjectInit(&SPID1); SPID1.thread = NULL; SPID1.spi = SPI1; - SPID1.dmarx = STM32_DMA1_CH2; - SPID1.dmatx = STM32_DMA1_CH3; + SPID1.dmarx = STM32_DMA1_STREAM2; + SPID1.dmatx = STM32_DMA1_STREAM3; #endif #if STM32_SPI_USE_SPI2 spiObjectInit(&SPID2); SPID2.thread = NULL; SPID2.spi = SPI2; - SPID2.dmarx = STM32_DMA1_CH4; - SPID2.dmatx = STM32_DMA1_CH5; + SPID2.dmarx = STM32_DMA1_STREAM4; + SPID2.dmatx = STM32_DMA1_STREAM5; #endif #if STM32_SPI_USE_SPI3 spiObjectInit(&SPID3); SPID3.thread = NULL; SPID3.spi = SPI3; - SPID3.dmarx = STM32_DMA2_CH1; - SPID3.dmatx = STM32_DMA2_CH2; + SPID3.dmarx = STM32_DMA2_STREAM1; + SPID3.dmatx = STM32_DMA2_STREAM2; #endif } @@ -181,60 +181,69 @@ void spi_lld_start(SPIDriver *spip) { if (spip->state == SPI_STOP) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI1_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_SPI_SPI1_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #2", "stream already allocated"); RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI2_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_SPI_SPI2_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #4", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); - NVICEnableVector(DMA2_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); - NVICEnableVector(DMA2_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SPI_SPI3_IRQ_PRIORITY)); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM1, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_SPI_SPI3_IRQ_PRIORITY, + (stm32_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + chDbgAssert(!b, "spi_lld_start(), #6", "stream already allocated"); RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; } #endif /* DMA setup.*/ - dmaChannelSetPeripheral(spip->dmarx, &spip->spi->DR); - dmaChannelSetPeripheral(spip->dmatx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); } /* More DMA setup.*/ if ((spip->config->cr1 & SPI_CR1_DFF) == 0) - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE; /* 8 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_BYTE | + STM32_DMA_CR_MSIZE_BYTE; /* 8 bits transfers. */ else - spip->dmaccr = (STM32_SPI_SPI2_DMA_PRIORITY << 12) | - DMA_CCR1_TEIE | DMA_CCR1_MSIZE_0 | - DMA_CCR1_PSIZE_0; /* 16 bits transfers. */ + spip->dmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) | + STM32_DMA_CR_TEIE | + STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MSIZE_HWORD; /* 16 bits transfers. */ /* SPI setup and enable.*/ spip->spi->CR1 = 0; @@ -261,28 +270,22 @@ void spi_lld_stop(SPIDriver *spip) { #if STM32_SPI_USE_SPI1 if (&SPID1 == spip) { - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; } #endif #if STM32_SPI_USE_SPI2 if (&SPID2 == spip) { - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; } #endif #if STM32_SPI_USE_SPI3 if (&SPID3 == spip) { - NVICDisableVector(DMA2_Channel1_IRQn); - NVICDisableVector(DMA2_Channel2_IRQn); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1); - dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2); + dmaStreamRelease(STM32_DMA1_STREAM1); + dmaStreamRelease(STM32_DMA1_STREAM2); RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN; } #endif @@ -327,10 +330,14 @@ void spi_lld_unselect(SPIDriver *spip) { */ void spi_lld_ignore(SPIDriver *spip, size_t n) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** @@ -351,12 +358,15 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -374,11 +384,14 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - dmaChannelSetup(spip->dmarx, n, &dummyrx, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, txbuf, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, &dummyrx); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_EN); } /** @@ -396,11 +409,15 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - dmaChannelSetup(spip->dmarx, n, rxbuf, - spip->dmaccr | DMA_CCR1_TCIE | DMA_CCR1_MINC | - DMA_CCR1_EN); - dmaChannelSetup(spip->dmatx, n, &dummytx, - spip->dmaccr | DMA_CCR1_DIR | DMA_CCR1_EN); + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_TCIE | STM32_DMA_CR_MINC | + STM32_DMA_CR_EN); + dmaStreamSetMemory0(spip->dmatx, &dummytx); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_EN); } /** diff --git a/os/hal/platforms/STM32/DMAv1/spi_lld.h b/os/hal/platforms/STM32/DMAv1/spi_lld.h index 6f1e94096..c8c1e0661 100644 --- a/os/hal/platforms/STM32/DMAv1/spi_lld.h +++ b/os/hal/platforms/STM32/DMAv1/spi_lld.h @@ -174,20 +174,20 @@ typedef struct { /** * @brief Operation complete callback or @p NULL. */ - spicallback_t end_cb; + spicallback_t end_cb; /* End of the mandatory fields.*/ /** * @brief The chip select line port. */ - ioportid_t ssport; + ioportid_t ssport; /** * @brief The chip select line pad number. */ - uint16_t sspad; + uint16_t sspad; /** * @brief SPI initialization data. */ - uint16_t cr1; + uint16_t cr1; } SPIConfig; /** @@ -197,25 +197,25 @@ struct SPIDriver{ /** * @brief Driver state. */ - spistate_t state; + spistate_t state; /** * @brief Current configuration data. */ - const SPIConfig *config; + const SPIConfig *config; #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waiting thread. */ - Thread *thread; + Thread *thread; #endif /* SPI_USE_WAIT */ #if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Mutex protecting the bus. */ - Mutex mutex; + Mutex mutex; #elif CH_USE_SEMAPHORES - Semaphore semaphore; + Semaphore semaphore; #endif #endif /* SPI_USE_MUTUAL_EXCLUSION */ #if defined(SPI_DRIVER_EXT_FIELDS) @@ -225,19 +225,19 @@ struct SPIDriver{ /** * @brief Pointer to the SPIx registers block. */ - SPI_TypeDef *spi; + SPI_TypeDef *spi; /** - * @brief Pointer to the receive DMA channel registers block. + * @brief Receive DMA channel. */ - stm32_dma_channel_t *dmarx; + const stm32_dma_stream_t *dmarx; /** - * @brief Pointer to the transmit DMA channel registers block. + * @brief Transmit DMA channel. */ - stm32_dma_channel_t *dmatx; + const stm32_dma_stream_t *dmatx; /** - * @brief DMA priority bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c index a1ade4409..1df93bb2f 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c @@ -54,6 +54,11 @@ */ #define STM32_DMA2_STREAMS_MASK 0x00000F80 +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -66,20 +71,25 @@ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. */ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {0, DMA1, DMA1_Channel1, &DMA1->IFCR, 0}, - {1, DMA1, DMA1_Channel2, &DMA1->IFCR, 4}, - {2, DMA1, DMA1_Channel3, &DMA1->IFCR, 8}, - {3, DMA1, DMA1_Channel4, &DMA1->IFCR, 12}, - {4, DMA1, DMA1_Channel5, &DMA1->IFCR, 16}, - {5, DMA1, DMA1_Channel6, &DMA1->IFCR, 20}, - {6, DMA1, DMA1_Channel7, &DMA1->IFCR, 24}, + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn}, + {DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn}, + {DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}, #if STM32_HAS_DMA2 || defined(__DOXYGEN__) - {7, DMA2, DMA2_Channel1, &DMA2->IFCR, 0}, - {8, DMA2, DMA2_Channel2, &DMA2->IFCR, 4}, - {9, DMA2, DMA2_Channel3, &DMA2->IFCR, 8}, - {10, DMA2, DMA2_Channel4, &DMA2->IFCR, 12}, - {11, DMA2, DMA2_Channel5, &DMA2->IFCR, 16}, -#endif + {DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn}, + {DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn}, + {DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn}, +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn}, +#else /* !STM32F10X_CL */ + {DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_5_IRQn}, + {DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel4_5_IRQn}, +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ }; /*===========================================================================*/ @@ -130,6 +140,239 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { CH_IRQ_EPILOGUE(); } +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if STM32_HAS_DMA2 || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[7].dma_func) + dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 4; + if (dma_isr_redir[8].dma_func) + dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[9].dma_func) + dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +#if defined(STM32F10X_CL) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} +#else /* !STM32F10X_CL */ +/** + * @brief DMA2 streams 4 and 5 shared interrupt handler. + * @note This IRQ is shared between DMA2 channels 4 and 5 so it is a + * bit less efficient because an extra check. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Ch4_5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 12; + if (dma_isr_redir[10].dma_func) + dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags); + } + + /* Check on channel 5.*/ + flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA2->IFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} +#endif /* !STM32F10X_CL */ +#endif /* STM32_HAS_DMA2 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -143,7 +386,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].channel->CCR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -156,13 +399,15 @@ void dmaInit(void) { /** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. - * Trying to allocate a stream already allocated is an illegal - * operation and is trapped if assertions are enabled. - * @pre The stream must not be already in use. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. - * @post The stream must be freed using @p dmaRelease() before it can + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. + * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -174,8 +419,10 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param) { +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -196,8 +443,15 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, RCC->AHBENR |= RCC_AHBENR_DMA2EN; #endif - /* Making sure there are no spurious interrupts flags pending.*/ + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + return FALSE; } @@ -206,7 +460,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * @details The stream is freed and, if required, the DMA clock disabled. * Trying to release a unallocated stream is an illegal operation * and is trapped if assertions are enabled. - * @pre The stream must have been allocated using @p dmaRequest(). + * @pre The stream must have been allocated using @p dmaStreamAllocate(). * @post The stream is again available. * @note This function can be invoked in both ISR or thread context. * @@ -214,7 +468,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); @@ -222,6 +476,9 @@ void dmaRelease(stm32_dma_stream_t *dmastp) { chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, "dmaRelease(), #1", "not allocated"); + /* Disables the associated IRQ vector.*/ + NVICDisableVector(dmastp->vector); + /* Marks the stream as not allocated.*/ dma_streams_mask &= ~(1 << dmastp->selfindex); diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h index 45c683c07..0247c63cf 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h @@ -93,7 +93,7 @@ #define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0 #define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1 #define STM32_DMA_CR_PL_MASK DMA_CCR1_PL -#define STM32_DMA_CR_PL(n) ((n) << 16) +#define STM32_DMA_CR_PL(n) ((n) << 12) /** @} */ /** * @name CR register constants only found in enhanced DMA @@ -128,12 +128,12 @@ * @brief STM32 DMA stream descriptor structure. */ typedef struct { - uint32_t selfindex; /**< @brief Index to self in array. */ - DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */ - uint32_t ishift; /**< @brief Bits offset in xIFCR + uint8_t ishift; /**< @brief Bits offset in xIFCR register. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ } stm32_dma_stream_t; /** @@ -176,7 +176,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure @@ -188,6 +188,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmastp)->channel->CNDTR = (uint32_t)(size); \ } +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) + /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. @@ -198,7 +209,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @special */ #define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode2); \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ } /** @@ -209,7 +220,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaStreamEnable(dmachp) { \ +#define dmaStreamEnable(dmastp) { \ (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ } @@ -249,9 +260,11 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, - stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.c b/os/hal/platforms/STM32/DMAv1/uart_lld.c index e2f306302..a9303744d 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.c +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.c @@ -87,17 +87,19 @@ static uartflags_t translate_errors(uint16_t sr) { * @param[in] uartp pointer to the @p UARTDriver object */ static void set_rx_idle_loop(UARTDriver *uartp) { - uint32_t ccr; + uint32_t mode; /* RX DMA channel preparation, if the char callback is defined then the TCIE interrupt is enabled too.*/ if (uartp->config->rxchar_cb == NULL) - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE; + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE; else - ccr = DMA_CCR1_CIRC | DMA_CCR1_TEIE | DMA_CCR1_TCIE; - dmaSetupChannel(uartp->dmap, uartp->dmarx, 1, - &uartp->rxbuf, uartp->dmaccr | ccr); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE; + dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, 1); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | mode); + dmaStreamEnable(uartp->dmarx); } /** @@ -109,10 +111,10 @@ static void set_rx_idle_loop(UARTDriver *uartp) { static void usart_stop(UARTDriver *uartp) { /* Stops RX and TX DMA channels.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); /* Stops USART operations.*/ uartp->usart->CR1 = 0; @@ -154,7 +156,7 @@ static void usart_start(UARTDriver *uartp) { u->CR1 = uartp->config->cr1 | cr1; u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE; u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR | - USART_CR3_EIE; + USART_CR3_EIE; /* Starting the receiver idle loop.*/ set_rx_idle_loop(uartp); @@ -170,7 +172,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else @@ -186,7 +188,7 @@ static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { else { /* Receiver in active state, a callback is generated, if enabled, after a completed transfer.*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); uartp->rxstate = UART_RX_COMPLETE; if (uartp->config->rxend_cb != NULL) uartp->config->rxend_cb(uartp); @@ -209,14 +211,14 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_UART_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_UART_DMA_ERROR_HOOK(uartp); } #else (void)flags; #endif - dmaDisableChannel(uartp->dmap, uartp->dmatx); + dmaStreamDisable(uartp->dmatx); /* A callback is generated, if enabled, after a completed transfer.*/ uartp->txstate = UART_TX_COMPLETE; if (uartp->config->txend1_cb != NULL) @@ -318,28 +320,22 @@ void uart_lld_init(void) { #if STM32_UART_USE_USART1 uartObjectInit(&UARTD1); UARTD1.usart = USART1; - UARTD1.dmap = STM32_DMA1; - UARTD1.dmarx = STM32_DMA_CHANNEL_5; - UARTD1.dmatx = STM32_DMA_CHANNEL_4; - UARTD1.dmaccr = 0; + UARTD1.dmarx = STM32_DMA1_STREAM5; + UARTD1.dmatx = STM32_DMA1_STREAM4; #endif #if STM32_UART_USE_USART2 uartObjectInit(&UARTD2); UARTD2.usart = USART2; - UARTD2.dmap = STM32_DMA1; - UARTD2.dmarx = STM32_DMA_CHANNEL_6; - UARTD2.dmatx = STM32_DMA_CHANNEL_7; - UARTD2.dmaccr = 0; + UARTD2.dmarx = STM32_DMA1_STREAM6; + UARTD2.dmatx = STM32_DMA1_STREAM7; #endif #if STM32_UART_USE_USART3 uartObjectInit(&UARTD3); UARTD3.usart = USART3; - UARTD3.dmap = STM32_DMA1; - UARTD3.dmarx = STM32_DMA_CHANNEL_3; - UARTD3.dmatx = STM32_DMA_CHANNEL_2; - UARTD3.dmaccr = 0; + UARTD3.dmarx = STM32_DMA1_STREAM3; + UARTD3.dmatx = STM32_DMA1_STREAM2; #endif } @@ -355,64 +351,68 @@ void uart_lld_start(UARTDriver *uartp) { if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_4, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_5, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM4, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM5, + STM32_UART_USART1_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; NVICEnableVector(USART1_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel4_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel5_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_6, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_7, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM6, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM7, + STM32_UART_USART2_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; NVICEnableVector(USART2_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel6_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel7_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { - /* Note, the DMA must be enabled before the IRQs.*/ - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_2, - (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_3, - (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); + bool_t b; + b = dmaStreamAllocate(STM32_DMA1_STREAM2, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); + b = dmaStreamAllocate(STM32_DMA1_STREAM3, + STM32_UART_USART3_IRQ_PRIORITY, + (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; NVICEnableVector(USART3_IRQn, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel2_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - NVICEnableVector(DMA1_Channel3_IRQn, - CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ - uartp->dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12; + uartp->dmamode = STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) - uartp->dmaccr |= DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0; - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmarx], - &uartp->usart->DR); - dmaChannelSetPeripheral(&uartp->dmap->channels[uartp->dmatx], - &uartp->usart->DR); + uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); + dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); uartp->rxbuf = 0; } @@ -435,11 +435,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM4); + dmaStreamRelease(STM32_DMA1_STREAM5); NVICDisableVector(USART1_IRQn); - NVICDisableVector(DMA1_Channel4_IRQn); - NVICDisableVector(DMA1_Channel5_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5); RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN; return; } @@ -447,11 +445,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM6); + dmaStreamRelease(STM32_DMA1_STREAM7); NVICDisableVector(USART2_IRQn); - NVICDisableVector(DMA1_Channel6_IRQn); - NVICDisableVector(DMA1_Channel7_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7); RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN; return; } @@ -459,11 +455,9 @@ void uart_lld_stop(UARTDriver *uartp) { #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { + dmaStreamRelease(STM32_DMA1_STREAM2); + dmaStreamRelease(STM32_DMA1_STREAM3); NVICDisableVector(USART3_IRQn); - NVICDisableVector(DMA1_Channel2_IRQn); - NVICDisableVector(DMA1_Channel3_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3); RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN; return; } @@ -485,10 +479,12 @@ void uart_lld_stop(UARTDriver *uartp) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { /* TX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmatx, n, txbuf, - uartp->dmaccr | DMA_CCR1_DIR | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmatx); + dmaStreamSetMemory0(uartp->dmatx, txbuf); + dmaStreamSetTransactionSize(uartp->dmatx, n); + dmaStreamSetMode(uartp->dmatx, uartp->dmamode | STM32_DMA_CR_DIR_M2P | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmatx); } /** @@ -504,9 +500,9 @@ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { */ size_t uart_lld_stop_send(UARTDriver *uartp) { - dmaDisableChannel(uartp->dmap, uartp->dmatx); - dmaClearChannel(uartp->dmap, uartp->dmatx); - return (size_t)uartp->dmap->channels[uartp->dmatx].CNDTR; + dmaStreamDisable(uartp->dmatx); + dmaStreamClearInterrupt(uartp->dmatx); + return dmaStreamGetTransactionSize(uartp->dmatx); } /** @@ -523,14 +519,16 @@ size_t uart_lld_stop_send(UARTDriver *uartp) { void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { /* Stopping previous activity (idle state).*/ - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); /* RX DMA channel preparation and start.*/ - dmaSetupChannel(uartp->dmap, uartp->dmarx, n, rxbuf, - uartp->dmaccr | DMA_CCR1_MINC | - DMA_CCR1_TEIE | DMA_CCR1_TCIE); - dmaEnableChannel(uartp->dmap, uartp->dmarx); + dmaStreamSetMemory0(uartp->dmarx, rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, n); + dmaStreamSetMode(uartp->dmarx, uartp->dmamode | STM32_DMA_CR_DIR_P2M | + STM32_DMA_CR_MINC | STM32_DMA_CR_TEIE | + STM32_DMA_CR_TCIE); + dmaStreamEnable(uartp->dmarx); } /** @@ -547,9 +545,9 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { size_t uart_lld_stop_receive(UARTDriver *uartp) { size_t n; - dmaDisableChannel(uartp->dmap, uartp->dmarx); - dmaClearChannel(uartp->dmap, uartp->dmarx); - n = (size_t)uartp->dmap->channels[uartp->dmarx].CNDTR; + dmaStreamDisable(uartp->dmarx); + dmaStreamClearInterrupt(uartp->dmarx); + n = dmaStreamGetTransactionSize(uartp->dmarx); set_rx_idle_loop(uartp); return n; } diff --git a/os/hal/platforms/STM32/DMAv1/uart_lld.h b/os/hal/platforms/STM32/DMAv1/uart_lld.h index 9321df85c..aff7f52ba 100644 --- a/os/hal/platforms/STM32/DMAv1/uart_lld.h +++ b/os/hal/platforms/STM32/DMAv1/uart_lld.h @@ -260,21 +260,17 @@ struct UARTDriver { */ USART_TypeDef *usart; /** - * @brief Pointer to the DMA registers block. + * @brief DMA mode bit mask. */ - stm32_dma_t *dmap; - /** - * @brief DMA priority bit mask. - */ - uint32_t dmaccr; + uint32_t dmamode; /** * @brief Receive DMA channel. */ - uint8_t dmarx; + const stm32_dma_stream_t *dmarx; /** * @brief Transmit DMA channel. */ - uint8_t dmatx; + const stm32_dma_stream_t *dmatx; /** * @brief Default receive buffer while into @p UART_RX_IDLE state. */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c index 48c0d4e95..5d320dab3 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -415,7 +415,7 @@ void dmaInit(void) { int i; dma_streams_mask = 0; - for (i = 0; i < STM32_DMA_STREAMS; i--) { + for (i = 0; i < STM32_DMA_STREAMS; i++) { _stm32_dma_streams[i].stream->CR = 0; dma_isr_redir[i].dma_func = NULL; } @@ -446,7 +446,7 @@ void dmaInit(void) { * * @special */ -bool_t dmaAllocate(stm32_dma_stream_t *dmastp, +bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); @@ -488,7 +488,7 @@ bool_t dmaAllocate(stm32_dma_stream_t *dmastp, * * @special */ -void dmaRelease(stm32_dma_stream_t *dmastp) { +void dmaRelease(const stm32_dma_stream_t *dmastp) { chDbgCheck(dmastp != NULL, "dmaRelease"); diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h index 5d87e67a9..88f594eec 100644 --- a/os/hal/platforms/STM32/DMAv2/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -217,11 +217,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); } /** - * @brief Associates an alternate memory destination to a DMA stream. + * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the NDTR register + * @param[in] size value to be written in the CNDTR register * * @special */ @@ -229,6 +229,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmastp)->stream->NDTR = (uint32_t)(size); \ } +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR)) + /** * @brief Programs the stream mode settings. * @note This function can be invoked in both ISR or thread context. @@ -303,9 +314,9 @@ extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; extern "C" { #endif void dmaInit(void); - bool_t dmaAllocate(stm32_dma_stream_t *dmastp, + bool_t dmaAllocate(const stm32_dma_stream_t *dmastp, stm32_dmaisr_t func, void *param); - void dmaRelease(stm32_dma_stream_t *dmastp); + void dmaRelease(const stm32_dma_stream_t *dmastp); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c index 8a8027e55..52d43daa9 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.c +++ b/os/hal/platforms/STM32F1xx/adc_lld.c @@ -58,17 +58,17 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_ADC_DMA_ERROR_HOOK) - if ((flags & DMA_ISR_TEIF1) != 0) { + if ((flags & STM32_DMA_ISR_TEIF) != 0) { STM32_ADC_DMA_ERROR_HOOK(spip); } #else (void)flags; #endif - if ((flags & DMA_ISR_HTIF1) != 0) { + if ((flags & STM32_DMA_ISR_HTIF) != 0) { /* Half transfer processing.*/ _adc_isr_half_code(adcp); } - if ((flags & DMA_ISR_TCIF1) != 0) { + if ((flags & STM32_DMA_ISR_TCIF) != 0) { /* Transfer complete processing.*/ _adc_isr_full_code(adcp); } @@ -93,10 +93,11 @@ void adc_lld_init(void) { /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; - ADCD1.dmachp = STM32_DMA1_CH1; - ADCD1.dmaccr = (STM32_ADC_ADC1_DMA_PRIORITY << 12) | - DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | - DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE; + ADCD1.dmastp = STM32_DMA1_STREAM1; + ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | + STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | + STM32_DMA_CR_TEIE | STM32_DMA_CR_EN; /* Temporary activation.*/ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; @@ -132,11 +133,13 @@ void adc_lld_start(ADCDriver *adcp) { if (adcp->state == ADC_STOP) { #if STM32_ADC_USE_ADC1 if (&ADCD1 == adcp) { - dmaAllocate(STM32_DMA1_ID, STM32_DMA_CHANNEL_1, - (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, (void *)adcp); - NVICEnableVector(DMA1_Channel1_IRQn, - CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); - dmaChannelSetPeripheral(adcp->dmachp, &ADC1->DR); + bool_t b; + b = dmaStreamAllocate(adcp->dmastp, + STM32_ADC_ADC1_IRQ_PRIORITY, + (stm32_dmaisr_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR); RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; } #endif @@ -163,8 +166,7 @@ void adc_lld_stop(ADCDriver *adcp) { if (&ADCD1 == adcp) { ADC1->CR1 = 0; ADC1->CR2 = 0; - NVICDisableVector(DMA1_Channel1_IRQn); - dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1); + dmaStreamRelease(adcp->dmastp); RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; } #endif @@ -179,27 +181,28 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { - uint32_t ccr, n; + uint32_t mode, n; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ - ccr = adcp->dmaccr; + mode = adcp->dmamode; if (grpp->circular) - ccr |= DMA_CCR1_CIRC; + mode |= STM32_DMA_CR_CIRC; if (adcp->depth > 1) { /* If the buffer depth is greater than one then the half transfer interrupt interrupt is enabled in order to allows streaming processing.*/ - ccr |= DMA_CCR1_HTIE; + mode |= STM32_DMA_CR_HTIE; n = (uint32_t)grpp->num_channels * (uint32_t)adcp->depth; } else n = (uint32_t)grpp->num_channels; - dmaChannelSetup(adcp->dmachp, n, adcp->samples, ccr); + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, n); + dmaStreamSetMode(adcp->dmastp, mode); /* ADC setup.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN; - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; adcp->adc->SMPR1 = grpp->smpr1; adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; @@ -207,8 +210,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR3 = grpp->sqr3; /* ADC start by writing ADC_CR2_ADON a second time.*/ - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_CONT | ADC_CR2_ADON; + adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON; } /** @@ -220,7 +222,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { */ void adc_lld_stop_conversion(ADCDriver *adcp) { - dmaChannelDisable(adcp->dmachp); + dmaStreamDisable(adcp->dmastp); adcp->adc->CR2 = 0; } diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h index ce93e60ed..43b16b738 100644 --- a/os/hal/platforms/STM32F1xx/adc_lld.h +++ b/os/hal/platforms/STM32F1xx/adc_lld.h @@ -268,13 +268,13 @@ struct ADCDriver { */ ADC_TypeDef *adc; /** - * @brief Pointer to the DMA registers block. + * @brief Pointer to associated SMA channel. */ - stm32_dma_channel_t *dmachp; + const stm32_dma_stream_t *dmastp; /** - * @brief DMA CCR register bit mask. + * @brief DMA mode bit mask. */ - uint32_t dmaccr; + uint32_t dmamode; }; /*===========================================================================*/ diff --git a/readme.txt b/readme.txt index f47fead5a..e0c1066fa 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,9 @@ (backported to 2.2.4). - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) (backported to 2.2.4). +- NEW: New DMA helper driver for STM32, it simplifies the use of the DMA + resources and hides most differences with the new enhanced DMA units + found in the STM32F2xx sub-family. - NEW: Now an error is generated at compile time when trying to enable the options CH_DBG_ENABLE_STACK_CHECK on ports that do not support it. - NEW: Added a kernel-only Cortex-Mx demo as reference project for users not diff --git a/testhal/STM32F1xx/ADC/chconf.h b/testhal/STM32F1xx/ADC/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/ADC/chconf.h +++ b/testhal/STM32F1xx/ADC/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SDIO/chconf.h b/testhal/STM32F1xx/SDIO/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/SDIO/chconf.h +++ b/testhal/STM32F1xx/SDIO/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SPI/chconf.h b/testhal/STM32F1xx/SPI/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/SPI/chconf.h +++ b/testhal/STM32F1xx/SPI/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/SPI/mcuconf.h b/testhal/STM32F1xx/SPI/mcuconf.h index ab96d8eef..558c0773d 100644 --- a/testhal/STM32F1xx/SPI/mcuconf.h +++ b/testhal/STM32F1xx/SPI/mcuconf.h @@ -127,7 +127,7 @@ * SPI driver system settings. */ #define STM32_SPI_USE_SPI1 TRUE -#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI2 TRUE #define STM32_SPI_USE_SPI3 FALSE #define STM32_SPI_SPI1_DMA_PRIORITY 1 #define STM32_SPI_SPI2_DMA_PRIORITY 1 diff --git a/testhal/STM32F1xx/UART/chconf.h b/testhal/STM32F1xx/UART/chconf.h index 9dd831c96..a5d129956 100644 --- a/testhal/STM32F1xx/UART/chconf.h +++ b/testhal/STM32F1xx/UART/chconf.h @@ -361,7 +361,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE #endif /** @@ -372,7 +372,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE #endif /** @@ -384,7 +384,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE #endif /** @@ -395,7 +395,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_TRACE FALSE +#define CH_DBG_ENABLE_TRACE TRUE #endif /** @@ -409,7 +409,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS TRUE #endif /** diff --git a/testhal/STM32F1xx/UART/main.c b/testhal/STM32F1xx/UART/main.c index 924338a77..b3ccd35fd 100644 --- a/testhal/STM32F1xx/UART/main.c +++ b/testhal/STM32F1xx/UART/main.c @@ -26,9 +26,7 @@ static VirtualTimer vt1, vt2; static void restart(void *p) { (void)p; - chSysLockFromIsr(); uartStartSendI(&UARTD2, 14, "Hello World!\r\n"); - chSysUnlockFromIsr(); } static void ledoff(void *p) { @@ -48,7 +46,7 @@ static void txend1(UARTDriver *uartp) { } /* - * This callback is invoked when a transmission has phisically completed. + * This callback is invoked when a transmission has physically completed. */ static void txend2(UARTDriver *uartp) { diff --git a/testhal/STM32F1xx/UART/mcuconf.h b/testhal/STM32F1xx/UART/mcuconf.h index 558c0773d..c8dd60ca1 100644 --- a/testhal/STM32F1xx/UART/mcuconf.h +++ b/testhal/STM32F1xx/UART/mcuconf.h @@ -140,9 +140,9 @@ /* * UART driver system settings. */ -#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART1 TRUE #define STM32_UART_USE_USART2 TRUE -#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_USART3 TRUE #define STM32_UART_USART1_IRQ_PRIORITY 12 #define STM32_UART_USART2_IRQ_PRIORITY 12 #define STM32_UART_USART3_IRQ_PRIORITY 12 -- cgit v1.2.3