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
master
gdisirio 2011-08-28 08:53:14 +00:00
parent fe0093f795
commit d2e9a52cf6
20 changed files with 632 additions and 329 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
/**

View File

@ -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;
};
/*===========================================================================*/

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};
/*===========================================================================*/

View File

@ -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

View File

@ -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
/**

View File

@ -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
/**

View File

@ -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
/**

View File

@ -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

View File

@ -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
/**

View File

@ -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) {

View File

@ -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