summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter D. Gray <peter@conalgo.com>2018-04-13 09:14:44 -0400
committerDamien George <damien.p.george@gmail.com>2018-05-02 13:41:23 +1000
commit266446624fc055e988782577286fe91efbda438e (patch)
treeadcfa4a00dccf5585989297316db3e386fca95e4
parent4c0f664b1aaa7b4b3253060799113139f5dfd8cb (diff)
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.
-rw-r--r--ports/stm32/dma.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c
index 7ea2eaa3b..35cfba162 100644
--- a/ports/stm32/dma.c
+++ b/ports/stm32/dma.c
@@ -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]);
}