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:
Peter D. Gray 2018-04-13 09:14:44 -04:00 committed by Damien George
parent 4c0f664b1a
commit 266446624f

View File

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