aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Blazewicz2016-09-07 18:40:34 +0200
committerKrzysztof Blazewicz2016-11-16 12:43:27 +0100
commit63ca7a211ac832fb885753ad837a7b3de2aaa5da (patch)
tree9a75cc7e215c465ec6cb460520acd977f16f5b14
parent0280b2c1b1eb761fa66db620c96cdcf276c2cf94 (diff)
stmhal/dma: precalculate register base and bitshift on handle init
Current version of HAL drivers optimize IRQ handler by using precalculated DMA register address and stream bitshift instead of calculating it on every interrupt. Since we skip call to `HAL_DMA_Init` on reused DMA, fields StreamBaseAddress and StreamIndex of DMA handle are not initialized and thus leads to SegFault in `DMA_IRQHandler`. HAL_DMA_Init is a big routine and we do not need to call it on each use of DMA (ex.: series of I2C operations) and DMA_CalcBaseAndBitshift is really small and releasing it increases code size by only 8 bytes.
-rw-r--r--stmhal/dma.c7
-rw-r--r--stmhal/hal/f4/src/stm32f4xx_hal_dma.c4
2 files changed, 9 insertions, 2 deletions
diff --git a/stmhal/dma.c b/stmhal/dma.c
index 7b540f847..60d7b0210 100644
--- a/stmhal/dma.c
+++ b/stmhal/dma.c
@@ -434,6 +434,13 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
HAL_DMA_DeInit(dma);
HAL_DMA_Init(dma);
HAL_NVIC_SetPriority(dma_irqn[dma_id], IRQ_PRI_DMA, IRQ_SUBPRI_DMA);
+ } else {
+ // only necessary initialization
+#if defined(MCU_SERIES_F4)
+ // calculate DMA base address and bitshift to be used in IRQ handler
+ extern uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
+ DMA_CalcBaseAndBitshift(dma);
+#endif
}
HAL_NVIC_EnableIRQ(dma_irqn[dma_id]);
diff --git a/stmhal/hal/f4/src/stm32f4xx_hal_dma.c b/stmhal/hal/f4/src/stm32f4xx_hal_dma.c
index 9f8f4c75d..326aa0afb 100644
--- a/stmhal/hal/f4/src/stm32f4xx_hal_dma.c
+++ b/stmhal/hal/f4/src/stm32f4xx_hal_dma.c
@@ -152,7 +152,7 @@ typedef struct
* @{
*/
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
+uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
/**
@@ -1188,7 +1188,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
* the configuration information for the specified DMA Stream.
* @retval Stream base address
*/
-static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
+uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
{
uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U;