STM32H743 CubeH7 package DMA IFCR HAL Bug ?
Hi,
I have been breaking my head, looking at the following code:
STM32Cube_FW_H7_V1.7.0\Driver\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c
Specifically at the following:
typedef struct
{
__IO uint32_t ISR; /*!< DMA interrupt status register */
__IO uint32_t Reserved0;
__IO uint32_t IFCR; /*!< DMA interrupt flag clear register */
} DMA_Base_Registers;
typedef struct
{
__IO uint32_t ISR; /*!< BDMA interrupt status register */
__IO uint32_t IFCR; /*!< BDMA interrupt flag clear register */
} BDMA_Base_Registers;
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
/* calculate DMA base and stream number */
DMA_Base_Registers *regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
{
/* Clear the DMAMUX synchro overrun flag */
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
if(hdma->DMAmuxRequestGen != 0U)
{
/* Clear the DMAMUX request generator overrun flag */
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
}
}
if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
{
/* Clear all interrupt flags at correct offset within the register */
regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
/* Clear DBM bit */
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
/* Configure DMA Stream data length */
((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
/* Peripheral to Memory */
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
{
/* Configure DMA Stream destination address */
((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
/* Configure DMA Stream source address */
((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
}
/* Memory to Peripheral */
else
{
/* Configure DMA Stream source address */
((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
/* Configure DMA Stream destination address */
((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
}
}
else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
{
/* Clear all flags */
regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
/* Configure DMA Channel data length */
((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
/* Peripheral to Memory */
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
{
/* Configure DMA Channel destination address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
/* Configure DMA Channel source address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
}
/* Memory to Peripheral */
else
{
/* Configure DMA Channel source address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
/* Configure DMA Channel destination address */
((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
}
}
else
{
/* Nothing To Do */
}
}In the Datasheet, while the BDMA module has 32 bit wide registers
BDMA_ISR,
BDMA_IFCR
which looks alright but
the DMA module has 32 bit wide registers
DMA_LISR,
DMA_HISR,
DMA_LIFCR,
DMA_HIFCR
The register definition for the DMA ISR/LIFCR in stm32h7xx_hal_dma.c
shows ISR/LIFCR 32 bits wide.
The LISR/LIFCR applies only to Streams 0 -3
while the HISR/HIFCR applies to Streams 4 - 7
But DMA_SetConfig() appears to assume that DMA_ISR/LIFCR as one contiguous 32 bit wide register, thereby rendering Streams 4 - 7 inoperable.
This appears to be a bug.
Am I looking at this correctly ?
Can someone clarify, please ?
Thanks,
Manu
