stm32/dma: Always deinit/reinit DMA channels on L4 MCUs.
The problem is the existing code which tries to optimise the reinitialisation of the DMA breaks the abstraction of the HAL. For the STM32L4 the HAL's DMA setup code maintains two private vars (ChannelIndex, DmaBaseAddress) and updates a hardware register (CCR). In HAL_DMA_Init(), the CCR is updated to set the direction of the DMA. This is a problem because, when using the SD Card interface, the same DMA channel is used in both directions, so the direction bit in the CCR must follow that. A quick and effective fix for the L4 is to simply call HAL_DMA_DeInit() and HAL_DMA_Init() every time.
This commit is contained in:
parent
4c0f664b1a
commit
266446624f
@ -498,6 +498,14 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
|
||||
|
||||
dma_enable_clock(dma_id);
|
||||
|
||||
#if defined(STM32L4)
|
||||
// Always reset and configure the L4 DMA peripheral
|
||||
// (dma->State is set to HAL_DMA_STATE_RESET by memset above)
|
||||
// TODO: understand how L4 DMA works so this is not needed
|
||||
HAL_DMA_DeInit(dma);
|
||||
HAL_DMA_Init(dma);
|
||||
HAL_NVIC_SetPriority(dma_irqn[dma_id], IRQ_PRI_DMA, IRQ_SUBPRI_DMA);
|
||||
#else
|
||||
// if this stream was previously configured for this channel/request then we
|
||||
// can skip most of the initialisation
|
||||
uint8_t sub_inst = DMA_SUB_INSTANCE_AS_UINT8(dma_descr->sub_instance);
|
||||
@ -518,6 +526,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
|
||||
DMA_CalcBaseAndBitshift(dma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
HAL_NVIC_EnableIRQ(dma_irqn[dma_id]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user