Added support for DMA channels sharing IRQs.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8126 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
bbacae2118
commit
5e5cb6651a
|
@ -0,0 +1,29 @@
|
||||||
|
STM32 DMAv1 driver.
|
||||||
|
|
||||||
|
Driver capability:
|
||||||
|
|
||||||
|
- The driver supports the STM32 traditional DMA controller in the following
|
||||||
|
configurations: 5ch, 7ch, 7ch+5ch.
|
||||||
|
- Support for automatic the channel selection through the CSELR register.
|
||||||
|
- For devices without CSELR register it is possible to select channels but
|
||||||
|
the SYSCFG CFGR register is not configured, the user has to configure it
|
||||||
|
before starting the DMA driver.
|
||||||
|
- The driver supports shared ISR handlers with a quirk: the IRQ priority is
|
||||||
|
established by the first allocated channel among the channels sharing the
|
||||||
|
ISR.
|
||||||
|
|
||||||
|
The file registry must export:
|
||||||
|
|
||||||
|
STM32_ADVANCED_DMA - TRUE if CSELR is present.
|
||||||
|
STM32_DMAn_NUM_CHANNELS - Number of channels in DMA1.
|
||||||
|
STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x".
|
||||||
|
STM32_DMAn_CHxyz_HANDLER - Vector name for shared IRQs "x", "y" and "z".
|
||||||
|
STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x".
|
||||||
|
STM32_DMAn_CHxyz_NUMBER - Vector number for shared IRQs "x", "y" and "z".
|
||||||
|
|
||||||
|
Currently supported shared combinations are:
|
||||||
|
|
||||||
|
STM32_DMA1_CH23_HANDLER
|
||||||
|
STM32_DMA1_CH23_NUMBER
|
||||||
|
STM32_DMA1_CH4567_HANDLER
|
||||||
|
STM32_DMA1_CH4567_NUMBER
|
|
@ -78,6 +78,34 @@
|
||||||
#define ADDR_DMA2_CSELR NULL
|
#define ADDR_DMA2_CSELR NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR collision masks.
|
||||||
|
*/
|
||||||
|
#define DMA1_CH1_CMASK 0x00000001U
|
||||||
|
#if !defined(STM32_DMA1_CH23_NUMBER)
|
||||||
|
#define DMA1_CH2_CMASK 0x00000002U
|
||||||
|
#define DMA1_CH3_CMASK 0x00000004U
|
||||||
|
#else
|
||||||
|
#define DMA1_CH2_CMASK 0x00000006U
|
||||||
|
#define DMA1_CH3_CMASK 0x00000006U
|
||||||
|
#endif
|
||||||
|
#if !defined(STM32_DMA1_CH4567_NUMBER)
|
||||||
|
#define DMA1_CH4_CMASK 0x00000008U
|
||||||
|
#define DMA1_CH5_CMASK 0x00000010U
|
||||||
|
#define DMA1_CH6_CMASK 0x00000020U
|
||||||
|
#define DMA1_CH7_CMASK 0x00000040U
|
||||||
|
#else
|
||||||
|
#define DMA1_CH4_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH5_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH6_CMASK 0x00000078U
|
||||||
|
#define DMA1_CH7_CMASK 0x00000078U
|
||||||
|
#endif
|
||||||
|
#define DMA2_CH1_CMASK 0x00000080U
|
||||||
|
#define DMA3_CH2_CMASK 0x00000100U
|
||||||
|
#define DMA3_CH3_CMASK 0x00000200U
|
||||||
|
#define DMA4_CH4_CMASK 0x00000400U
|
||||||
|
#define DMA5_CH5_CMASK 0x00000800U
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver exported variables. */
|
/* Driver exported variables. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -90,23 +118,23 @@
|
||||||
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
|
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
|
||||||
*/
|
*/
|
||||||
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||||
{DMA1_Channel1, &DMA1->IFCR, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER},
|
{DMA1_Channel1, DMA1_CH1_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER},
|
||||||
{DMA1_Channel2, &DMA1->IFCR, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER},
|
{DMA1_Channel2, DMA1_CH2_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER},
|
||||||
{DMA1_Channel3, &DMA1->IFCR, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER},
|
{DMA1_Channel3, DMA1_CH3_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER},
|
||||||
{DMA1_Channel4, &DMA1->IFCR, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER},
|
{DMA1_Channel4, DMA1_CH4_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER},
|
||||||
{DMA1_Channel5, &DMA1->IFCR, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER},
|
{DMA1_Channel5, DMA1_CH5_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER},
|
||||||
#if STM32_DMA1_NUM_CHANNELS > 5
|
#if STM32_DMA1_NUM_CHANNELS > 5
|
||||||
{DMA1_Channel6, &DMA1->IFCR, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER},
|
{DMA1_Channel6, DMA1_CH6_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER},
|
||||||
#endif
|
#endif
|
||||||
#if STM32_DMA1_NUM_CHANNELS > 6
|
#if STM32_DMA1_NUM_CHANNELS > 6
|
||||||
{DMA1_Channel7, &DMA1->IFCR, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER},
|
{DMA1_Channel7, DMA1_CH7_CMASK, &DMA1->IFCR, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER},
|
||||||
#endif
|
#endif
|
||||||
#if STM32_DMA2_NUM_CHANNELS > 0
|
#if STM32_DMA2_NUM_CHANNELS > 0
|
||||||
{DMA2_Channel1, &DMA2->IFCR, ADDR_DMA2_CSELR, 0, 8, STM32_DMA2_CH1_NUMBER},
|
{DMA2_Channel1, DMA2_CH1_CMASK, &DMA2->IFCR, ADDR_DMA2_CSELR, 0, 8, STM32_DMA2_CH1_NUMBER},
|
||||||
{DMA2_Channel2, &DMA2->IFCR, ADDR_DMA2_CSELR, 4, 9, STM32_DMA2_CH2_NUMBER},
|
{DMA2_Channel2, DMA2_CH2_CMASK, &DMA2->IFCR, ADDR_DMA2_CSELR, 4, 9, STM32_DMA2_CH2_NUMBER},
|
||||||
{DMA2_Channel3, &DMA2->IFCR, ADDR_DMA2_CSELR, 8, 10, STM32_DMA2_CH3_NUMBER},
|
{DMA2_Channel3, DMA2_CH3_CMASK, &DMA2->IFCR, ADDR_DMA2_CSELR, 8, 10, STM32_DMA2_CH3_NUMBER},
|
||||||
{DMA2_Channel4, &DMA2->IFCR, ADDR_DMA2_CSELR, 12, 11, STM32_DMA2_CH4_NUMBER},
|
{DMA2_Channel4, DMA2_CH4_CMASK, &DMA2->IFCR, ADDR_DMA2_CSELR, 12, 11, STM32_DMA2_CH4_NUMBER},
|
||||||
{DMA2_Channel5, &DMA2->IFCR, ADDR_DMA2_CSELR, 16, 13, STM32_DMA2_CH5_NUMBER},
|
{DMA2_Channel5, DMA2_CH5_CMASK, &DMA2->IFCR, ADDR_DMA2_CSELR, 16, 13, STM32_DMA2_CH5_NUMBER},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -505,10 +533,9 @@ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||||
if ((dma_streams_mask & (1U << dmastp->selfindex)) != 0U)
|
if ((dma_streams_mask & (1U << dmastp->selfindex)) != 0U)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Marks the stream as allocated.*/
|
/* Installs the DMA handler.*/
|
||||||
dma_isr_redir[dmastp->selfindex].dma_func = func;
|
dma_isr_redir[dmastp->selfindex].dma_func = func;
|
||||||
dma_isr_redir[dmastp->selfindex].dma_param = param;
|
dma_isr_redir[dmastp->selfindex].dma_param = param;
|
||||||
dma_streams_mask |= (1U << dmastp->selfindex);
|
|
||||||
|
|
||||||
/* Enabling DMA clocks required by the current streams set.*/
|
/* Enabling DMA clocks required by the current streams set.*/
|
||||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0U)
|
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0U)
|
||||||
|
@ -522,9 +549,15 @@ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||||
dmaStreamDisable(dmastp);
|
dmaStreamDisable(dmastp);
|
||||||
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
|
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
|
||||||
|
|
||||||
/* Enables the associated IRQ vector if a callback is defined.*/
|
/* Enables the associated IRQ vector if not alread enabled and if a
|
||||||
if (func != NULL)
|
callback is defined.*/
|
||||||
|
if (((dma_streams_mask & dmastp->cmask) != 0U) &&
|
||||||
|
(func != NULL)) {
|
||||||
nvicEnableVector(dmastp->vector, priority);
|
nvicEnableVector(dmastp->vector, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Marks the stream as allocated.*/
|
||||||
|
dma_streams_mask |= (1U << dmastp->selfindex);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -550,12 +583,18 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
||||||
osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0U,
|
osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0U,
|
||||||
"not allocated");
|
"not allocated");
|
||||||
|
|
||||||
/* Disables the associated IRQ vector.*/
|
|
||||||
nvicDisableVector(dmastp->vector);
|
|
||||||
|
|
||||||
/* Marks the stream as not allocated.*/
|
/* Marks the stream as not allocated.*/
|
||||||
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
||||||
|
|
||||||
|
/* Disables the associated IRQ vector if it is no more in use.*/
|
||||||
|
if ((dma_streams_mask & dmastp->cmask) == 0U) {
|
||||||
|
nvicDisableVector(dmastp->vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Removes the DMA handler.*/
|
||||||
|
dma_isr_redir[dmastp->selfindex].dma_func = NULL;
|
||||||
|
dma_isr_redir[dmastp->selfindex].dma_param = NULL;
|
||||||
|
|
||||||
/* Shutting down clocks that are no more required, if any.*/
|
/* Shutting down clocks that are no more required, if any.*/
|
||||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0U)
|
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0U)
|
||||||
rccDisableDMA1(false);
|
rccDisableDMA1(false);
|
||||||
|
|
|
@ -201,6 +201,8 @@
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
|
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
|
||||||
|
uint32_t cmask; /**< @brief Mask of streams sharing
|
||||||
|
the same ISR. */
|
||||||
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
||||||
volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
|
volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
|
||||||
uint8_t shift; /**< @brief Bit offset in IFCR and
|
uint8_t shift; /**< @brief Bit offset in IFCR and
|
||||||
|
|
|
@ -74,7 +74,12 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 3.1.0 ***
|
*** 3.1.0 ***
|
||||||
|
- HAL: STM32F0xx and STM32L0xx devices now share the same ADCv1 and DMAv1
|
||||||
|
drivers.
|
||||||
- HAL: Introduced preliminary support for STM32L0xx devices.
|
- HAL: Introduced preliminary support for STM32L0xx devices.
|
||||||
|
- HAL: New STM32 DMAv1 driver supporting channel selection and fixing the
|
||||||
|
behavior with shared IRQs.
|
||||||
|
- HAL: New STM32 ADCv1 driver supporting small STM32 devices.
|
||||||
- HAL: Introduced support for TIM21 and TIM22 in STM32 ST driver.
|
- HAL: Introduced support for TIM21 and TIM22 in STM32 ST driver.
|
||||||
- HAL: Updated STM32F0xx headers to STM32CubeF0 version 1.3.0. Added support
|
- HAL: Updated STM32F0xx headers to STM32CubeF0 version 1.3.0. Added support
|
||||||
for STM32F030xC, STM32F070x6, STM32F070xB devices.
|
for STM32F030xC, STM32F070x6, STM32F070xB devices.
|
||||||
|
|
Loading…
Reference in New Issue