2021-04-21 03: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 07: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 03: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.