Added DMA sharing in the STM32 HAL.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2874 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
8bfbb8d4d9
commit
618a978da8
|
@ -51,7 +51,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -128,9 +128,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -144,9 +142,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -136,9 +136,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -152,9 +150,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -48,40 +48,36 @@ ADCDriver ADCD1;
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Shared ADC DMA ISR service routine.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
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) {
|
||||
STM32_ADC_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
if ((flags & DMA_ISR_HTIF1) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(adcp);
|
||||
}
|
||||
if ((flags & DMA_ISR_TCIF1) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(adcp);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief ADC1 DMA interrupt handler (channel 1).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR;
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
|
||||
if ((isr & DMA_ISR_TEIF1) != 0) {
|
||||
/* DMA error processing.*/
|
||||
STM32_ADC1_DMA_ERROR_HOOK();
|
||||
}
|
||||
if ((isr & DMA_ISR_HTIF1) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(&ADCD1);
|
||||
}
|
||||
if ((isr & DMA_ISR_TCIF1) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(&ADCD1);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -136,7 +132,8 @@ void adc_lld_start(ADCDriver *adcp) {
|
|||
if (adcp->state == ADC_STOP) {
|
||||
#if STM32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
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);
|
||||
|
@ -167,7 +164,7 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
ADC1->CR1 = 0;
|
||||
ADC1->CR2 = 0;
|
||||
NVICDisableVector(DMA1_Channel1_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_1);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -94,12 +94,12 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 DMA error hook.
|
||||
* @brief ADC DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA
|
||||
* error can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -114,6 +114,10 @@
|
|||
#error "ADC driver activated but no ADC peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_DMA_REQUIRED)
|
||||
#define STM32_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -71,7 +71,7 @@ void hal_lld_init(void) {
|
|||
SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk;
|
||||
|
||||
#if HAL_USE_ADC || HAL_USE_SPI || HAL_USE_UART
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -82,11 +82,21 @@ static uint16_t dummyrx;
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Shared end-of-transfer service routine.
|
||||
* @brief Shared end-of-rx service routine.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
static void serve_interrupt(SPIDriver *spip) {
|
||||
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) {
|
||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
|
||||
/* Stop everything.*/
|
||||
dma_stop(spip);
|
||||
|
@ -96,115 +106,29 @@ static void serve_interrupt(SPIDriver *spip) {
|
|||
_spi_isr_code(spip);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shared end-of-tx service routine.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
|
||||
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_SPI_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
STM32_SPI_DMA_ERROR_HOOK(spip);
|
||||
}
|
||||
#else
|
||||
(void)spip;
|
||||
(void)flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI1 RX DMA interrupt handler (channel 2).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
|
||||
STM32_SPI_SPI1_DMA_ERROR_HOOK();
|
||||
}
|
||||
serve_interrupt(&SPID1);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI1 TX DMA interrupt handler (channel 3).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
STM32_SPI_SPI1_DMA_ERROR_HOOK();
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI2 RX DMA interrupt handler (channel 4).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
|
||||
STM32_SPI_SPI2_DMA_ERROR_HOOK();
|
||||
}
|
||||
serve_interrupt(&SPID2);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI2 TX DMA interrupt handler (channel 5).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
STM32_SPI_SPI2_DMA_ERROR_HOOK();
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI3 RX DMA interrupt handler (DMA2, channel 1).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA2->ISR & DMA_ISR_TEIF1) != 0) {
|
||||
STM32_SPI_SPI3_DMA_ERROR_HOOK();
|
||||
}
|
||||
serve_interrupt(&SPID3);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI3 TX DMA2 interrupt handler (DMA2, channel 2).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
STM32_SPI_SPI3_DMA_ERROR_HOOK();
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -256,7 +180,11 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
if (spip->state == SPI_STOP) {
|
||||
#if STM32_SPI_USE_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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,
|
||||
|
@ -266,7 +194,11 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
#endif
|
||||
#if STM32_SPI_USE_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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,
|
||||
|
@ -276,7 +208,11 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
#endif
|
||||
#if STM32_SPI_USE_SPI3
|
||||
if (&SPID3 == spip) {
|
||||
dmaEnable(DMA2_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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,
|
||||
|
@ -324,7 +260,8 @@ void spi_lld_stop(SPIDriver *spip) {
|
|||
if (&SPID1 == spip) {
|
||||
NVICDisableVector(DMA1_Channel2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel3_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -332,7 +269,8 @@ void spi_lld_stop(SPIDriver *spip) {
|
|||
if (&SPID2 == spip) {
|
||||
NVICDisableVector(DMA1_Channel4_IRQn);
|
||||
NVICDisableVector(DMA1_Channel5_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -340,7 +278,8 @@ void spi_lld_stop(SPIDriver *spip) {
|
|||
if (&SPID3 == spip) {
|
||||
NVICDisableVector(DMA2_Channel1_IRQn);
|
||||
NVICDisableVector(DMA2_Channel2_IRQn);
|
||||
dmaDisable(DMA2_ID);
|
||||
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_1);
|
||||
dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_2);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI3EN;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -118,30 +118,12 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI1 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
* @brief SPI DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA
|
||||
* error can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI2 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI3 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_SPI_SPI3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -164,6 +146,10 @@
|
|||
#error "SPI driver activated but no SPI peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_DMA_REQUIRED)
|
||||
#define STM32_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -23,23 +23,43 @@
|
|||
* @brief STM32 DMA helper driver code.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @details DMA sharing helper driver. In the STM32 the DMA channels are a
|
||||
* shared resource, this driver allows to allocate and free DMA
|
||||
* channels at runtime in order to allow all the other device
|
||||
* drivers to coordinate the access to the resource.
|
||||
* @note The DMA ISR handlers are all declared into this module because
|
||||
* sharing, the various device drivers can associate a callback to
|
||||
* IRSs when allocating channels.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables. */
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static cnt_t dmacnt1;
|
||||
/**
|
||||
* @brief DMA ISR redirector type.
|
||||
*/
|
||||
typedef struct {
|
||||
stm32_dmaisr_t dmaisrfunc;
|
||||
void *dmaisrparam;
|
||||
} dma_isr_redir_t;
|
||||
|
||||
static uint32_t dmamsk1;
|
||||
static dma_isr_redir_t dma1[7];
|
||||
|
||||
#if STM32_HAS_DMA2
|
||||
static cnt_t dmacnt2;
|
||||
static uint32_t dmamsk2;
|
||||
static dma_isr_redir_t dma2[5];
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -50,6 +70,224 @@ static cnt_t dmacnt2;
|
|||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_1 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
|
||||
if (dma1[0].dmaisrfunc)
|
||||
dma1[0].dmaisrfunc(dma1[0].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_2 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
|
||||
if (dma1[1].dmaisrfunc)
|
||||
dma1[1].dmaisrfunc(dma1[1].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_3 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
if (dma1[2].dmaisrfunc)
|
||||
dma1[2].dmaisrfunc(dma1[2].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_4 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
|
||||
if (dma1[3].dmaisrfunc)
|
||||
dma1[3].dmaisrfunc(dma1[3].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_5 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
if (dma1[4].dmaisrfunc)
|
||||
dma1[4].dmaisrfunc(dma1[4].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 6 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_6 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
|
||||
if (dma1[5].dmaisrfunc)
|
||||
dma1[5].dmaisrfunc(dma1[5].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA1 channel 7 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA1->ISR >> (STM32_DMA_CHANNEL_7 * 4);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
|
||||
if (dma1[6].dmaisrfunc)
|
||||
dma1[6].dmaisrfunc(dma1[6].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA2 channel 1 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch1_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_1 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_1);
|
||||
if (dma2[0].dmaisrfunc)
|
||||
dma2[0].dmaisrfunc(dma2[0].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 2 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch2_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_2 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_2);
|
||||
if (dma2[1].dmaisrfunc)
|
||||
dma2[1].dmaisrfunc(dma2[1].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 3 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch3_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_3 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_3);
|
||||
if (dma2[2].dmaisrfunc)
|
||||
dma2[2].dmaisrfunc(dma2[2].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 4 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch4_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_4 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
|
||||
if (dma2[3].dmaisrfunc)
|
||||
dma2[3].dmaisrfunc(dma2[3].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA2 channel 5 shared interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA2_Ch5_IRQHandler) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
isr = STM32_DMA2->ISR >> (STM32_DMA_CHANNEL_5 * 4);
|
||||
dmaClearChannel(STM32_DMA2, STM32_DMA_CHANNEL_5);
|
||||
if (dma2[4].dmaisrfunc)
|
||||
dma2[4].dmaisrfunc(dma2[4].dmaisrparam, isr);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* STM32_HAS_DMA2 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -62,66 +300,135 @@ static cnt_t dmacnt2;
|
|||
void dmaInit(void) {
|
||||
int i;
|
||||
|
||||
dmacnt1 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--)
|
||||
dmamsk1 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_7; i >= STM32_DMA_CHANNEL_1; i--) {
|
||||
dmaDisableChannel(STM32_DMA1, i);
|
||||
dma1[i].dmaisrfunc = NULL;
|
||||
}
|
||||
STM32_DMA1->IFCR = 0xFFFFFFFF;
|
||||
#if STM32_HAS_DMA2
|
||||
dmacnt2 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--)
|
||||
dmamsk2 = 0;
|
||||
for (i = STM32_DMA_CHANNEL_5; i >= STM32_DMA_CHANNEL_1; i--) {
|
||||
dmaDisableChannel(STM32_DMA2, i);
|
||||
dma2[i].dmaisrfunc = NULL;
|
||||
}
|
||||
STM32_DMA1->IFCR = 0xFFFFFFFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the specified DMA controller clock.
|
||||
* @brief Allocates a DMA channel.
|
||||
* @details The channel is allocated and, if required, the DMA clock enabled.
|
||||
* Trying to allocate a channel already allocated is an illegal
|
||||
* operation and is trapped if assertions are enabled.
|
||||
* @pre The channel must not be already in use.
|
||||
* @post The channel is allocated and the default ISR handler redirected
|
||||
* to the specified function.
|
||||
* @post The channel must be freed using @p dmaRelease() before it can
|
||||
* be reused with another peripheral.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dma the DMA controller id
|
||||
* @param[in] dma DMA controller id
|
||||
* @param[in] channel requested channel id
|
||||
* @param[in] func handling function pointer, can be @p NULL
|
||||
* @param[in] param a parameter to be passed to the handling function
|
||||
* @return The operation status.
|
||||
* @retval FALSE operation successfully allocated.
|
||||
* @retval TRUE the channel was already in use.
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
void dmaEnable(uint32_t dma) {
|
||||
void dmaAllocate(uint32_t dma, uint32_t channel,
|
||||
stm32_dmaisr_t func, void *param) {
|
||||
|
||||
chDbgCheck(func != NULL, "dmaAllocate");
|
||||
|
||||
#if STM32_HAS_DMA2
|
||||
switch (dma) {
|
||||
case DMA1_ID:
|
||||
if (dmacnt1++ == 0) {
|
||||
case STM32_DMA1_ID:
|
||||
#else
|
||||
(void)dma;
|
||||
#endif
|
||||
/* Check if the channel is already taken.*/
|
||||
chDbgAssert((dmamsk1 & (1 << channel)) == 0,
|
||||
"dmaAllocate(), #1", "already allocated");
|
||||
|
||||
/* If the DMA unit was idle then the clock is enabled.*/
|
||||
if (dmamsk1 == 0) {
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
|
||||
DMA1->IFCR = 0x0FFFFFFF;
|
||||
}
|
||||
break;
|
||||
|
||||
dmamsk1 |= 1 << channel;
|
||||
dma1[channel].dmaisrfunc = func;
|
||||
dma1[channel].dmaisrparam = param;
|
||||
#if STM32_HAS_DMA2
|
||||
case DMA2_ID:
|
||||
if (dmacnt2++ == 0) {
|
||||
break;
|
||||
case STM32_DMA2_ID:
|
||||
/* Check if the channel is already taken.*/
|
||||
chDbgAssert((dmamsk2 & (1 << channel)) == 0,
|
||||
"dmaAllocate(), #2", "already allocated");
|
||||
|
||||
/* If the DMA unit was idle then the clock is enabled.*/
|
||||
if (dmamsk1 == 0) {
|
||||
RCC->AHBENR |= RCC_AHBENR_DMA2EN;
|
||||
DMA2->IFCR = 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
dmamsk2 |= 1 << channel;
|
||||
dma2[channel].dmaisrfunc = func;
|
||||
dma2[channel].dmaisrparam = param;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the specified DMA controller clock.
|
||||
* @brief Releases a DMA channel.
|
||||
* @details The channel is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated channel is an illegal operation
|
||||
* and is trapped if assertions are enabled.
|
||||
* @pre The channel must have been allocated using @p dmaRequest().
|
||||
* @post The channel is again available.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dma the DMA controller id
|
||||
* @param[in] dma DMA controller id
|
||||
* @param[in] channel requested channel id
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
void dmaDisable(uint32_t dma) {
|
||||
void dmaRelease(uint32_t dma, uint32_t channel) {
|
||||
|
||||
switch (dma) {
|
||||
case DMA1_ID:
|
||||
if (--dmacnt1 == 0)
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
||||
break;
|
||||
#if STM32_HAS_DMA2
|
||||
case DMA2_ID:
|
||||
if (--dmacnt2 == 0)
|
||||
switch (dma) {
|
||||
case STM32_DMA1_ID:
|
||||
#else
|
||||
(void)dma;
|
||||
#endif
|
||||
/* Check if the channel is not taken.*/
|
||||
chDbgAssert((dmamsk1 & (1 << channel)) != 0,
|
||||
"dmaRelease(), #1", "not allocated");
|
||||
|
||||
dma1[channel].dmaisrfunc = NULL;
|
||||
dmamsk1 &= ~(1 << channel);
|
||||
if (dmamsk1 == 0)
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
||||
#if STM32_HAS_DMA2
|
||||
break;
|
||||
case STM32_DMA2_ID:
|
||||
/* Check if the channel is not taken.*/
|
||||
chDbgAssert((dmamsk2 & (1 << channel)) != 0,
|
||||
"dmaRelease(), #2", "not allocated");
|
||||
|
||||
dma2[channel].dmaisrfunc = NULL;
|
||||
dmamsk2 &= ~(1 << channel);
|
||||
if (dmamsk2 == 0)
|
||||
RCC->AHBENR &= ~RCC_AHBENR_DMA2EN;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* STM32_DMA_REQUIRED */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -36,11 +36,11 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/** @brief DMA1 identifier.*/
|
||||
#define DMA1_ID 0
|
||||
#define STM32_DMA1_ID 0
|
||||
|
||||
/** @brief DMA2 identifier.*/
|
||||
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
|
||||
#define DMA2_ID 1
|
||||
#define STM32_DMA2_ID 1
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -56,7 +56,7 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA channel memory structure.
|
||||
* @brief STM32 DMA channel memory structure type.
|
||||
*/
|
||||
typedef struct {
|
||||
volatile uint32_t CCR;
|
||||
|
@ -67,7 +67,7 @@ typedef struct {
|
|||
} stm32_dma_channel_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA subsystem memory structure.
|
||||
* @brief STM32 DMA subsystem memory structure type.
|
||||
* @note This structure has been redefined here because it is convenient to
|
||||
* have the channels organized as an array, the ST header does not
|
||||
* do that.
|
||||
|
@ -78,6 +78,14 @@ typedef struct {
|
|||
stm32_dma_channel_t channels[7];
|
||||
} stm32_dma_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 DMA ISR function type.
|
||||
*
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
@ -128,11 +136,12 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief Associates a peripheral data register to a DMA channel.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
* @param[in] cpar value to be written in the CPAR register
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelSetPeripheral(dmachp, cpar) { \
|
||||
(dmachp)->CPAR = (uint32_t)(cpar); \
|
||||
|
@ -143,13 +152,14 @@ typedef struct {
|
|||
* @note This macro does not change the CPAR register because that register
|
||||
* value does not change frequently, it usually points to a peripheral
|
||||
* data register.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
* @param[in] cndtr value to be written in the CNDTR register
|
||||
* @param[in] cmar value to be written in the CMAR register
|
||||
* @param[in] ccr value to be written in the CCR register
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
|
||||
(dmachp)->CNDTR = (uint32_t)(cndtr); \
|
||||
|
@ -159,10 +169,11 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief DMA channel enable by channel pointer.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelEnable(dmachp) { \
|
||||
(dmachp)->CCR |= DMA_CCR1_EN; \
|
||||
|
@ -171,10 +182,11 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief DMA channel disable by channel pointer.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaChannelDisable(dmachp) { \
|
||||
(dmachp)->CCR = 0; \
|
||||
|
@ -187,6 +199,7 @@ typedef struct {
|
|||
* data register.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
|
@ -194,7 +207,7 @@ typedef struct {
|
|||
* @param[in] cmar value to be written in the CMAR register
|
||||
* @param[in] ccr value to be written in the CCR register
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
|
||||
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
|
||||
|
@ -204,11 +217,12 @@ typedef struct {
|
|||
* @brief DMA channel enable by channel ID.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaEnableChannel(dmap, ch) { \
|
||||
dmaChannelEnable(&(dmap)->channels[ch]); \
|
||||
|
@ -218,11 +232,12 @@ typedef struct {
|
|||
* @brief DMA channel disable by channel ID.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaDisableChannel(dmap, ch) { \
|
||||
dmaChannelDisable(&(dmap)->channels[ch]); \
|
||||
|
@ -234,11 +249,12 @@ typedef struct {
|
|||
* withdraw all the pending interrupt bits from the ISR register.
|
||||
* @note Channels are numbered from 0 to 6, use the appropriate macro
|
||||
* as parameter.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
*
|
||||
* @param[in] dmap pointer to a stm32_dma_t structure
|
||||
* @param[in] ch channel number
|
||||
*
|
||||
* @api
|
||||
* @special
|
||||
*/
|
||||
#define dmaClearChannel(dmap, ch){ \
|
||||
(dmap)->IFCR = 1 << ((ch) * 4); \
|
||||
|
@ -252,8 +268,9 @@ typedef struct {
|
|||
extern "C" {
|
||||
#endif
|
||||
void dmaInit(void);
|
||||
void dmaEnable(uint32_t dma);
|
||||
void dmaDisable(uint32_t dma);
|
||||
void dmaAllocate(uint32_t dma, uint32_t channel,
|
||||
stm32_dmaisr_t func, void *param);
|
||||
void dmaRelease(uint32_t dma, uint32_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -164,17 +164,38 @@ static void usart_start(UARTDriver *uartp) {
|
|||
* @brief RX DMA common service routine.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
static void serve_rx_end_irq(UARTDriver *uartp) {
|
||||
static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
|
||||
|
||||
uartp->rxstate = UART_RX_COMPLETE;
|
||||
if (uartp->config->rxend_cb != NULL)
|
||||
uartp->config->rxend_cb(uartp);
|
||||
/* If the callback didn't explicitly change state then the receiver
|
||||
automatically returns to the idle state.*/
|
||||
if (uartp->rxstate == UART_RX_COMPLETE) {
|
||||
uartp->rxstate = UART_RX_IDLE;
|
||||
set_rx_idle_loop(uartp);
|
||||
/* DMA errors handling.*/
|
||||
#if defined(STM32_UART_DMA_ERROR_HOOK)
|
||||
if ((flags & DMA_ISR_TEIF1) != 0) {
|
||||
STM32_UART_DMA_ERROR_HOOK(uartp);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
|
||||
if (uartp->rxstate == UART_RX_IDLE) {
|
||||
/* Receiver in idle state, a callback is generated, if enabled, for each
|
||||
received character and then the driver stays in the same state.*/
|
||||
if (uartp->config->rxchar_cb != NULL)
|
||||
uartp->config->rxchar_cb(uartp, uartp->rxbuf);
|
||||
}
|
||||
else {
|
||||
/* Receiver in active state, a callback is generated, if enabled, after
|
||||
a completed transfer.*/
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmarx);
|
||||
uartp->rxstate = UART_RX_COMPLETE;
|
||||
if (uartp->config->rxend_cb != NULL)
|
||||
uartp->config->rxend_cb(uartp);
|
||||
/* If the callback didn't explicitly change state then the receiver
|
||||
automatically returns to the idle state.*/
|
||||
if (uartp->rxstate == UART_RX_COMPLETE) {
|
||||
uartp->rxstate = UART_RX_IDLE;
|
||||
set_rx_idle_loop(uartp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,9 +203,20 @@ static void serve_rx_end_irq(UARTDriver *uartp) {
|
|||
* @brief TX DMA common service routine.
|
||||
*
|
||||
* @param[in] uartp pointer to the @p UARTDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
static void serve_tx_end_irq(UARTDriver *uartp) {
|
||||
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) {
|
||||
STM32_UART_DMA_ERROR_HOOK(uartp);
|
||||
}
|
||||
#else
|
||||
(void)flags;
|
||||
#endif
|
||||
|
||||
dmaDisableChannel(uartp->dmap, uartp->dmatx);
|
||||
/* A callback is generated, if enabled, after a completed transfer.*/
|
||||
uartp->txstate = UART_TX_COMPLETE;
|
||||
if (uartp->config->txend1_cb != NULL)
|
||||
|
@ -194,6 +226,7 @@ static void serve_tx_end_irq(UARTDriver *uartp) {
|
|||
if (uartp->txstate == UART_TX_COMPLETE)
|
||||
uartp->txstate = UART_TX_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART common service routine.
|
||||
*
|
||||
|
@ -224,58 +257,6 @@ static void serve_usart_irq(UARTDriver *uartp) {
|
|||
/*===========================================================================*/
|
||||
|
||||
#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART1 RX DMA interrupt handler (channel 5).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
|
||||
UARTDriver *uartp;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
uartp = &UARTD1;
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF5) != 0) {
|
||||
STM32_UART_USART1_DMA_ERROR_HOOK();
|
||||
}
|
||||
if (uartp->rxstate == UART_RX_IDLE) {
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
/* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
|
||||
/* Receiver in idle state, a callback is generated, if enabled, for each
|
||||
received character and then the driver stays in the same state.*/
|
||||
if (uartp->config->rxchar_cb != NULL)
|
||||
uartp->config->rxchar_cb(uartp, uartp->rxbuf);
|
||||
}
|
||||
else {
|
||||
/* Receiver in active state, a callback is generated, if enabled, after
|
||||
a completed transfer.*/
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_5);
|
||||
serve_rx_end_irq(uartp);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 TX DMA interrupt handler (channel 4).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF4) != 0) {
|
||||
STM32_UART_USART1_DMA_ERROR_HOOK();
|
||||
}
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_4);
|
||||
serve_tx_end_irq(&UARTD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 IRQ handler.
|
||||
*
|
||||
|
@ -292,58 +273,6 @@ CH_IRQ_HANDLER(USART1_IRQHandler) {
|
|||
#endif /* STM32_UART_USE_USART1 */
|
||||
|
||||
#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART2 RX DMA interrupt handler (channel 6).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
|
||||
UARTDriver *uartp;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
uartp = &UARTD2;
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF6) != 0) {
|
||||
STM32_UART_USART2_DMA_ERROR_HOOK();
|
||||
}
|
||||
if (uartp->rxstate == UART_RX_IDLE) {
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
|
||||
/* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
|
||||
/* Receiver in idle state, a callback is generated, if enabled, for each
|
||||
received character and then the driver stays in the same state.*/
|
||||
if (uartp->config->rxchar_cb != NULL)
|
||||
uartp->config->rxchar_cb(uartp, uartp->rxbuf);
|
||||
}
|
||||
else {
|
||||
/* Receiver in active state, a callback is generated, if enabled, after
|
||||
a completed transfer.*/
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
|
||||
serve_rx_end_irq(uartp);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART2 TX DMA interrupt handler (channel 7).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF7) != 0) {
|
||||
STM32_UART_USART2_DMA_ERROR_HOOK();
|
||||
}
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
|
||||
serve_tx_end_irq(&UARTD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART2 IRQ handler.
|
||||
*
|
||||
|
@ -360,58 +289,6 @@ CH_IRQ_HANDLER(USART2_IRQHandler) {
|
|||
#endif /* STM32_UART_USE_USART2 */
|
||||
|
||||
#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART3 RX DMA interrupt handler (channel 3).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
|
||||
UARTDriver *uartp;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
uartp = &UARTD3;
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF3) != 0) {
|
||||
STM32_UART_USART1_DMA_ERROR_HOOK();
|
||||
}
|
||||
if (uartp->rxstate == UART_RX_IDLE) {
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
/* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
|
||||
/* Receiver in idle state, a callback is generated, if enabled, for each
|
||||
received character and then the driver stays in the same state.*/
|
||||
if (uartp->config->rxchar_cb != NULL)
|
||||
uartp->config->rxchar_cb(uartp, uartp->rxbuf);
|
||||
}
|
||||
else {
|
||||
/* Receiver in active state, a callback is generated, if enabled, after
|
||||
a completed transfer.*/
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_3);
|
||||
serve_rx_end_irq(uartp);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART3 TX DMA interrupt handler (channel 2).
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((STM32_DMA1->ISR & DMA_ISR_TEIF2) != 0) {
|
||||
STM32_UART_USART1_DMA_ERROR_HOOK();
|
||||
}
|
||||
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
|
||||
dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_2);
|
||||
serve_tx_end_irq(&UARTD3);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART3 IRQ handler.
|
||||
*
|
||||
|
@ -478,7 +355,11 @@ void uart_lld_start(UARTDriver *uartp) {
|
|||
if (uartp->state == UART_STOP) {
|
||||
#if STM32_UART_USE_USART1
|
||||
if (&UARTD1 == uartp) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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);
|
||||
NVICEnableVector(USART1_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel4_IRQn,
|
||||
|
@ -491,7 +372,11 @@ void uart_lld_start(UARTDriver *uartp) {
|
|||
|
||||
#if STM32_UART_USE_USART2
|
||||
if (&UARTD2 == uartp) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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);
|
||||
NVICEnableVector(USART2_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel6_IRQn,
|
||||
|
@ -504,7 +389,11 @@ void uart_lld_start(UARTDriver *uartp) {
|
|||
|
||||
#if STM32_UART_USE_USART3
|
||||
if (&UARTD3 == uartp) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
/* 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);
|
||||
NVICEnableVector(USART3_IRQn,
|
||||
CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY));
|
||||
NVICEnableVector(DMA1_Channel2_IRQn,
|
||||
|
@ -549,7 +438,8 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
NVICDisableVector(USART1_IRQn);
|
||||
NVICDisableVector(DMA1_Channel4_IRQn);
|
||||
NVICDisableVector(DMA1_Channel5_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_4);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_5);
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;
|
||||
return;
|
||||
}
|
||||
|
@ -560,7 +450,8 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
NVICDisableVector(USART2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel6_IRQn);
|
||||
NVICDisableVector(DMA1_Channel7_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_6);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_7);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
|
||||
return;
|
||||
}
|
||||
|
@ -571,7 +462,8 @@ void uart_lld_stop(UARTDriver *uartp) {
|
|||
NVICDisableVector(USART3_IRQn);
|
||||
NVICDisableVector(DMA1_Channel2_IRQn);
|
||||
NVICDisableVector(DMA1_Channel3_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_2);
|
||||
dmaRelease(STM32_DMA1_ID, STM32_DMA_CHANNEL_3);
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_USART3EN;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -121,26 +121,8 @@
|
|||
* @note The default action for DMA errors is a system halt because DMA
|
||||
* error can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_UART_USART1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART2 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA
|
||||
* error can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_UART_USART2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART3 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA
|
||||
* error can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_UART_USART3_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -164,6 +146,10 @@
|
|||
#error "UART driver activated but no USART/UART peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_DMA_REQUIRED)
|
||||
#define STM32_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
*** 2.3.2 ***
|
||||
- FIX: Fixed spurious characters generated by Serial over USB driver (bug
|
||||
3276379).
|
||||
- NEW: Now it is possible to share DMA channels in the STM32 HAL thanks
|
||||
to a centralized manager. Channels are allocated when the driver is
|
||||
started and released when it is stopped.
|
||||
- OPT: STM32 PWM driver implementation simplified.
|
||||
- CHANGE: Now pwmChangePeriod() does not implicitly disable the active
|
||||
PWM channels.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
|
@ -129,9 +129,7 @@
|
|||
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
|
||||
#define STM32_SPI_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_SPI3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
|
||||
|
||||
/*
|
||||
* UART driver system settings.
|
||||
|
@ -145,9 +143,7 @@
|
|||
#define STM32_UART_USART1_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART2_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART3_DMA_PRIORITY 0
|
||||
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
|
||||
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
|
|
Loading…
Reference in New Issue