cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 to STM32H7 - FMC DMA/MDMA confusion & warning

TGeof.2
Associate II

Hi,

I'm migrating a project from STM32F7 to STM32H7, and I'm hitting some roadblocks wrt DMA and the FMC.

When I was using an F7, I was doing this to initialise the FMC, and it worked perfectly:

/**
  * @brief  Initializes SDRAM MSP.
  * @param  hsdram: SDRAM handle
  * @param  Params  
  * @retval None
  */
__weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
{  
  static DMA_HandleTypeDef dma_handle;
  GPIO_InitTypeDef gpio_init_structure;
  
  /* Enable FMC clock */
  __HAL_RCC_FMC_CLK_ENABLE();
  
  /* Enable chosen DMAx clock */
  __DMAx_CLK_ENABLE();
 
  /* Enable GPIOs clock */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOI_CLK_ENABLE();
  
  /* Common GPIO configuration */
  gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
  gpio_init_structure.Pull      = GPIO_PULLUP;
  gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
  gpio_init_structure.Alternate = GPIO_AF12_FMC;
  
  /* GPIOD configuration */
  gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8| GPIO_PIN_9 | GPIO_PIN_10 |\
                              GPIO_PIN_14 | GPIO_PIN_15;
 
   
  HAL_GPIO_Init(GPIOD, &gpio_init_structure);
 
  /* GPIOE configuration */  
  gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\
                              GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
                              GPIO_PIN_15;
      
  HAL_GPIO_Init(GPIOE, &gpio_init_structure);
  
  /* GPIOF configuration */  
  gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\
                              GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
                              GPIO_PIN_15;
    
  HAL_GPIO_Init(GPIOF, &gpio_init_structure);
  
  /* GPIOG configuration */  
  gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4|\
                              GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOG, &gpio_init_structure);
 
  /* GPIOH configuration */  
  gpio_init_structure.Pin   = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_9 |\
                              GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\
                              GPIO_PIN_15;
  HAL_GPIO_Init(GPIOH, &gpio_init_structure); 
  
  /* GPIOI configuration */  
  gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |\
                              GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_9 | GPIO_PIN_10;
  HAL_GPIO_Init(GPIOI, &gpio_init_structure);  
  
  /* Configure common DMA parameters */
  dma_handle.Init.Channel             = SDRAM_DMAx_CHANNEL;
  dma_handle.Init.Direction           = DMA_MEMORY_TO_MEMORY;
  dma_handle.Init.PeriphInc           = DMA_PINC_ENABLE;
  dma_handle.Init.MemInc              = DMA_MINC_ENABLE;
  dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  dma_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  dma_handle.Init.Mode                = DMA_NORMAL;
  dma_handle.Init.Priority            = DMA_PRIORITY_HIGH;
  dma_handle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;         
  dma_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  dma_handle.Init.MemBurst            = DMA_MBURST_SINGLE;
  dma_handle.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
  
  dma_handle.Instance = SDRAM_DMAx_STREAM;
  
   /* Associate the DMA handle */
  __HAL_LINKDMA(hsdram, hdma, dma_handle);
  
  /* Deinitialize the stream for new transfer */
  HAL_DMA_DeInit(&dma_handle);
  
  /* Configure the DMA stream */
  HAL_DMA_Init(&dma_handle); 
  
  /* NVIC configuration for DMA transfer complete interrupt */
  HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 15, 0);
  HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
}

Now that I'm using H7, while it *seems* to still work, I'm getting this warning:

warning: assignment to 'MDMA_HandleTypeDef *' {aka 'struct __MDMA_HandleTypeDef *'} from incompatible pointer type 'DMA_HandleTypeDef *' {aka 'struct __DMA_HandleTypeDef *'} [-Wincompatible-pointer-types]
   66 |                               (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \
      |                                                               ^
note: in expansion of macro '__HAL_LINKDMA'
  215 |   __HAL_LINKDMA(hsdram, hmdma, dma_handle);

And indeed I can see that the struct SDRAM_Handle_TypeDef has changed between F7 and H7.

In stm32f7xx_hal_sdram.h it is defined as:

#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
typedef struct __SDRAM_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS  */
{
  FMC_SDRAM_TypeDef             *Instance;  /*!< Register base address                 */
  
  FMC_SDRAM_InitTypeDef         Init;       /*!< SDRAM device configuration parameters */
  
  __IO HAL_SDRAM_StateTypeDef   State;      /*!< SDRAM access state                    */
  
  HAL_LockTypeDef               Lock;       /*!< SDRAM locking object                  */ 
 
  DMA_HandleTypeDef             *hdma;      /*!< Pointer DMA handler                   */
 
#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
  void  (* MspInitCallback)        ( struct __SDRAM_HandleTypeDef * hsdram);    /*!< SDRAM Msp Init callback              */
  void  (* MspDeInitCallback)      ( struct __SDRAM_HandleTypeDef * hsdram);    /*!< SDRAM Msp DeInit callback            */
  void  (* RefreshErrorCallback)   ( struct __SDRAM_HandleTypeDef * hsdram);    /*!< SDRAM Refresh Error callback         */
  void  (* DmaXferCpltCallback)    ( DMA_HandleTypeDef * hdma);                 /*!< SDRAM DMA Xfer Complete callback     */
  void  (* DmaXferErrorCallback)   ( DMA_HandleTypeDef * hdma);                 /*!< SDRAM DMA Xfer Error callback        */
#endif
} SDRAM_HandleTypeDef;

Now it's this:

#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
typedef struct __SDRAM_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS  */
{
  FMC_SDRAM_TypeDef             *Instance;  /*!< Register base address                 */
 
  FMC_SDRAM_InitTypeDef         Init;       /*!< SDRAM device configuration parameters */
 
  __IO HAL_SDRAM_StateTypeDef   State;      /*!< SDRAM access state                    */
 
  HAL_LockTypeDef               Lock;       /*!< SDRAM locking object                  */
 
  MDMA_HandleTypeDef             *hmdma;      /*!< Pointer DMA handler                   */
 
#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
  void (* MspInitCallback)(struct __SDRAM_HandleTypeDef *hsdram);               /*!< SDRAM Msp Init callback              */
  void (* MspDeInitCallback)(struct __SDRAM_HandleTypeDef *hsdram);             /*!< SDRAM Msp DeInit callback            */
  void (* RefreshErrorCallback)(struct __SDRAM_HandleTypeDef *hsdram);          /*!< SDRAM Refresh Error callback         */
  void (* DmaXferCpltCallback)(MDMA_HandleTypeDef *hmdma);                        /*!< SDRAM DMA Xfer Complete callback     */
  void (* DmaXferErrorCallback)(MDMA_HandleTypeDef *hmdma);                       /*!< SDRAM DMA Xfer Error callback        */
#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */
} SDRAM_HandleTypeDef;

The DMA handler has gone from being a DMA_HandleTypeDef to being an MDMA_HandleTypeDef.

While it *seems* to work, I'm not 100% confident about how MDMA works, and how it can or cannot be a drop-in replacement of DMA. I haven't seen a single example of FMC being used on an H7.

Any pointers ? (pun intended)

2 REPLIES 2

And how do you use that DMA?

I don't Cube, and can't quite understand why would SDRAM need some dedicated DMA handle.

JW

Amel NASRI
ST Employee

Hi @TGeof.2​ ,

>> I haven't seen a single example of FMC being used on an H7.

There are several FMC_SDRAM examples in STM32CubeH7 package, as:

  • STM32Cube_FW_H7\Projects\STM32H7B3I-DK\Examples\FMC\FMC_SDRAM
  • STM32Cube_FW_H7\Projects\STM32H7B3I-EVAL\Examples\FMC\FMC_SDRAM
  • STM32Cube_FW_H7\Projects\STM32H745I-DISCO\Examples\FMC\FMC_SDRAM_DataMemory
  • STM32Cube_FW_H7\Projects\STM32H750B-DK\Examples\FMC\FMC_SDRAM

MDMA is used only with this example STM32Cube_FW_H7\Projects\STM32H743I-EVAL\Examples\FMC\FMC_SRAM.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.