2021-04-21 3:43 AM
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)
2021-04-21 7:57 AM
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
2021-04-23 3:40 AM
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:
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.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.