aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-08-28 08:53:14 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-08-28 08:53:14 +0000
commitd2e9a52cf6b2997b9b6320434ea296bde79b3727 (patch)
treee7017f554396ca52581b07dcaca59e6fe4aed355 /os/hal
parentfe0093f795b6c88db8f12e2f7e45e11355fc3340 (diff)
downloadChibiOS-d2e9a52cf6b2997b9b6320434ea296bde79b3727.tar.gz
ChibiOS-d2e9a52cf6b2997b9b6320434ea296bde79b3727.tar.bz2
ChibiOS-d2e9a52cf6b2997b9b6320434ea296bde79b3727.zip
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
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/sdc.h2
-rw-r--r--os/hal/platforms/STM32/DMAv1/sdc_lld.c86
-rw-r--r--os/hal/platforms/STM32/DMAv1/spi_lld.c169
-rw-r--r--os/hal/platforms/STM32/DMAv1/spi_lld.h32
-rw-r--r--os/hal/platforms/STM32/DMAv1/stm32_dma_alt.c303
-rw-r--r--os/hal/platforms/STM32/DMAv1/stm32_dma_alt.h33
-rw-r--r--os/hal/platforms/STM32/DMAv1/uart_lld.c180
-rw-r--r--os/hal/platforms/STM32/DMAv1/uart_lld.h12
-rw-r--r--os/hal/platforms/STM32/DMAv2/stm32_dma.c6
-rw-r--r--os/hal/platforms/STM32/DMAv2/stm32_dma.h19
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.c50
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.h8
12 files changed, 601 insertions, 299 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
@@ -189,6 +189,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
}
/**
+ * @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
*/
@@ -230,6 +230,17 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
}
/**
+ * @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;
};
/*===========================================================================*/