--- /dev/null
+/**\r
+ ******************************************************************************\r
+ * @file stm32h745i_discovery_sdram.c\r
+ * @author MCD Application Team\r
+ * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-6A memory \r
+ * device mounted on STM32H745I_DISCOVERY boards.\r
+ ******************************************************************************\r
+ @verbatim\r
+ How To use this driver:\r
+ -----------------------\r
+ - This driver is used to drive the MT48LC4M32B2B5-6A SDRAM external memory mounted\r
+ on STM32H745I_DISCOVERY board.\r
+ - This driver does not need a specific component driver for the SDRAM device\r
+ to be included with.\r
+\r
+ Driver description:\r
+ ------------------\r
+ + Initialization steps:\r
+ o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This \r
+ function includes the MSP layer hardware resources initialization and the\r
+ FMC controller configuration to interface with the external SDRAM memory.\r
+ o It contains the SDRAM initialization sequence to program the SDRAM external \r
+ device using the function BSP_SDRAM_Initialization_sequence(). Note that this \r
+ sequence is standard for all SDRAM devices, but can include some differences\r
+ from a device to another. If it is the case, the right sequence should be \r
+ implemented separately.\r
+ \r
+ + SDRAM read/write operations\r
+ o SDRAM external memory can be accessed with read/write operations once it is\r
+ initialized.\r
+ Read/write operation can be performed with AHB access using the functions\r
+ BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by MDMA transfer using the functions\r
+ BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().\r
+ o The AHB access is performed with 32-bit width transaction, the MDMA transfer\r
+ configuration is fixed at single (no burst) word transfer (see the \r
+ SDRAM_MspInit() static function).\r
+ o User can implement his own functions for read/write access with his desired \r
+ configurations.\r
+ o If interrupt mode is used for MDMA transfer, the function BSP_SDRAM_MDMA_IRQHandler()\r
+ is called in IRQ handler file, to serve the generated interrupt once the MDMA \r
+ transfer is complete.\r
+ o You can send a command to the SDRAM device in runtime using the function \r
+ BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between \r
+ the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure. \r
+ @endverbatim\r
+ ******************************************************************************\r
+ * @attention\r
+ *\r
+ * <h2><center>© Copyright (c) 2019 STMicroelectronics.\r
+ * All rights reserved.</center></h2>\r
+ *\r
+ * This software component is licensed by ST under BSD 3-Clause license,\r
+ * the "License"; You may not use this file except in compliance with the\r
+ * License. You may obtain a copy of the License at:\r
+ * opensource.org/licenses/BSD-3-Clause\r
+ *\r
+ ******************************************************************************\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include "stm32h745i_discovery_sdram.h"\r
+\r
+/** @addtogroup BSP\r
+ * @{\r
+ */\r
+\r
+/** @addtogroup STM32H745I_DISCOVERY\r
+ * @{\r
+ */ \r
+ \r
+/** @defgroup STM32H745I_DISCOVERY_SDRAM STM32H745I_DISCOVERY_SDRAM\r
+ * @{\r
+ */ \r
+\r
+\r
+/** @defgroup STM32H745I_DISCOVERY_SDRAM_Private_Variables Private Variables\r
+ * @{\r
+ */ \r
+SDRAM_HandleTypeDef sdramHandle;\r
+static FMC_SDRAM_TimingTypeDef Timing;\r
+static FMC_SDRAM_CommandTypeDef Command;\r
+/**\r
+ * @}\r
+ */ \r
+\r
+ \r
+/** @defgroup STM32H745I_DISCOVERY_SDRAM_Exported_Functions Exported Functions\r
+ * @{\r
+ */ \r
+\r
+/**\r
+ * @brief Initializes the SDRAM device.\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_Init(void)\r
+{ \r
+ static uint8_t sdramstatus = SDRAM_OK;\r
+ /* SDRAM device configuration */\r
+ sdramHandle.Instance = FMC_SDRAM_DEVICE;\r
+ \r
+ /* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */\r
+ Timing.LoadToActiveDelay = 2;\r
+ Timing.ExitSelfRefreshDelay = 7;\r
+ Timing.SelfRefreshTime = 4;\r
+ Timing.RowCycleDelay = 7;\r
+ Timing.WriteRecoveryTime = 2;\r
+ Timing.RPDelay = 2;\r
+ Timing.RCDDelay = 2;\r
+ \r
+ sdramHandle.Init.SDBank = FMC_SDRAM_BANK2;\r
+ sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;\r
+ sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;\r
+ sdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;\r
+ sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;\r
+ sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;\r
+ sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;\r
+ sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD;\r
+ sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;\r
+ sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;\r
+ \r
+ /* SDRAM controller initialization */\r
+\r
+ BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */\r
+\r
+ if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)\r
+ {\r
+ sdramstatus = SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ /* SDRAM initialization sequence */\r
+ BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);\r
+ }\r
+\r
+ return sdramstatus;\r
+}\r
+\r
+/**\r
+ * @brief DeInitializes the SDRAM device.\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_DeInit(void)\r
+{ \r
+ static uint8_t sdramstatus = SDRAM_OK;\r
+ /* SDRAM device de-initialization */\r
+ sdramHandle.Instance = FMC_SDRAM_DEVICE;\r
+\r
+ if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK)\r
+ {\r
+ sdramstatus = SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ /* SDRAM controller de-initialization */\r
+ BSP_SDRAM_MspDeInit(&sdramHandle, NULL);\r
+ }\r
+ \r
+ return sdramstatus;\r
+}\r
+\r
+/**\r
+ * @brief Programs the SDRAM device.\r
+ * @param RefreshCount: SDRAM refresh counter value \r
+ * @retval None\r
+ */\r
+void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)\r
+{\r
+ __IO uint32_t tmpmrd = 0;\r
+ \r
+ /* Step 1: Configure a clock configuration enable command */\r
+ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;\r
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;\r
+ Command.AutoRefreshNumber = 1;\r
+ Command.ModeRegisterDefinition = 0;\r
+\r
+ /* Send the command */\r
+ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
+\r
+ /* Step 2: Insert 100 us minimum delay */ \r
+ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */\r
+ HAL_Delay(1);\r
+ \r
+ /* Step 3: Configure a PALL (precharge all) command */ \r
+ Command.CommandMode = FMC_SDRAM_CMD_PALL;\r
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;\r
+ Command.AutoRefreshNumber = 1;\r
+ Command.ModeRegisterDefinition = 0;\r
+\r
+ /* Send the command */\r
+ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); \r
+ \r
+ /* Step 4: Configure an Auto Refresh command */ \r
+ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;\r
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;\r
+ Command.AutoRefreshNumber = 8;\r
+ Command.ModeRegisterDefinition = 0;\r
+\r
+ /* Send the command */\r
+ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
+ \r
+ /* Step 5: Program the external memory mode register */\r
+ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |\\r
+ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |\\r
+ SDRAM_MODEREG_CAS_LATENCY_3 |\\r
+ SDRAM_MODEREG_OPERATING_MODE_STANDARD |\\r
+ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;\r
+ \r
+ Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;\r
+ Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;\r
+ Command.AutoRefreshNumber = 1;\r
+ Command.ModeRegisterDefinition = tmpmrd;\r
+\r
+ /* Send the command */\r
+ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
+ \r
+ /* Step 6: Set the refresh rate counter */\r
+ /* Set the device refresh rate */\r
+ HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount); \r
+}\r
+\r
+/**\r
+ * @brief Reads an amount of data from the SDRAM memory in polling mode.\r
+ * @param uwStartAddress: Read start address\r
+ * @param pData: Pointer to data to be read \r
+ * @param uwDataSize: Size of read data from the memory\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)\r
+{\r
+ if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
+ {\r
+ return SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ return SDRAM_OK;\r
+ } \r
+}\r
+\r
+/**\r
+ * @brief Reads an amount of data from the SDRAM memory in DMA mode.\r
+ * @param uwStartAddress: Read start address\r
+ * @param pData: Pointer to data to be read \r
+ * @param uwDataSize: Size of read data from the memory\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)\r
+{\r
+ if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
+ {\r
+ return SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ return SDRAM_OK;\r
+ } \r
+}\r
+\r
+/**\r
+ * @brief Writes an amount of data to the SDRAM memory in polling mode.\r
+ * @param uwStartAddress: Write start address\r
+ * @param pData: Pointer to data to be written \r
+ * @param uwDataSize: Size of written data from the memory\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) \r
+{\r
+ if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
+ {\r
+ return SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ return SDRAM_OK;\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Writes an amount of data to the SDRAM memory in DMA mode.\r
+ * @param uwStartAddress: Write start address\r
+ * @param pData: Pointer to data to be written \r
+ * @param uwDataSize: Size of written data from the memory\r
+ * @retval SDRAM status\r
+ */\r
+uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) \r
+{\r
+ if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
+ {\r
+ return SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ return SDRAM_OK;\r
+ } \r
+}\r
+\r
+/**\r
+ * @brief Sends command to the SDRAM bank.\r
+ * @param SdramCmd: Pointer to SDRAM command structure \r
+ * @retval SDRAM status\r
+ */ \r
+uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)\r
+{\r
+ if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)\r
+ {\r
+ return SDRAM_ERROR;\r
+ }\r
+ else\r
+ {\r
+ return SDRAM_OK;\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Initializes SDRAM MSP.\r
+ * @param hsdram SDRAM handle\r
+ * @param Params User parameters\r
+ * @retval None\r
+ */\r
+__weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params)\r
+{ \r
+ static MDMA_HandleTypeDef mdma_handle;\r
+ GPIO_InitTypeDef gpio_init_structure;\r
+ \r
+ /* Enable FMC clock */\r
+ __HAL_RCC_FMC_CLK_ENABLE();\r
+ \r
+ /* Enable chosen MDMAx clock */\r
+ __MDMAx_CLK_ENABLE();\r
+\r
+ /* Enable GPIOs clock */\r
+ __HAL_RCC_GPIOD_CLK_ENABLE();\r
+ __HAL_RCC_GPIOE_CLK_ENABLE();\r
+ __HAL_RCC_GPIOF_CLK_ENABLE();\r
+ __HAL_RCC_GPIOG_CLK_ENABLE();\r
+ __HAL_RCC_GPIOH_CLK_ENABLE();\r
+ \r
+ /* Common GPIO configuration */\r
+ gpio_init_structure.Mode = GPIO_MODE_AF_PP;\r
+ gpio_init_structure.Pull = GPIO_PULLUP;\r
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;\r
+ gpio_init_structure.Alternate = GPIO_AF12_FMC;\r
+ \r
+ /* GPIOD configuration */\r
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8| GPIO_PIN_9 | GPIO_PIN_10 |\\r
+ GPIO_PIN_14 | GPIO_PIN_15;\r
+ \r
+ \r
+ HAL_GPIO_Init(GPIOD, &gpio_init_structure);\r
+\r
+ /* GPIOE configuration */ \r
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\\r
+ GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\\r
+ GPIO_PIN_15;\r
+ \r
+ HAL_GPIO_Init(GPIOE, &gpio_init_structure);\r
+ \r
+ /* GPIOF configuration */ \r
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\\r
+ GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\\r
+ GPIO_PIN_15;\r
+ \r
+ HAL_GPIO_Init(GPIOF, &gpio_init_structure);\r
+ \r
+ /* GPIOG configuration */ \r
+ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;\r
+ HAL_GPIO_Init(GPIOG, &gpio_init_structure);\r
+\r
+ /* GPIOH configuration */ \r
+ gpio_init_structure.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 ;\r
+ HAL_GPIO_Init(GPIOH, &gpio_init_structure); \r
+ \r
+\r
+ \r
+ /* Configure common MDMA parameters */\r
+ mdma_handle.Init.Request = MDMA_REQUEST_SW;\r
+ mdma_handle.Init.TransferTriggerMode = MDMA_BLOCK_TRANSFER;\r
+ mdma_handle.Init.Priority = MDMA_PRIORITY_HIGH;\r
+ mdma_handle.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;\r
+ mdma_handle.Init.SourceInc = MDMA_SRC_INC_WORD;\r
+ mdma_handle.Init.DestinationInc = MDMA_DEST_INC_WORD;\r
+ mdma_handle.Init.SourceDataSize = MDMA_SRC_DATASIZE_WORD;\r
+ mdma_handle.Init.DestDataSize = MDMA_DEST_DATASIZE_WORD;\r
+ mdma_handle.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE; \r
+ mdma_handle.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;\r
+ mdma_handle.Init.DestBurst = MDMA_DEST_BURST_SINGLE;\r
+ mdma_handle.Init.BufferTransferLength = 128;\r
+ mdma_handle.Init.SourceBlockAddressOffset = 0;\r
+ mdma_handle.Init.DestBlockAddressOffset = 0; \r
+ \r
+ \r
+ mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;\r
+ \r
+ /* Associate the DMA handle */\r
+ __HAL_LINKDMA(hsdram, hmdma, mdma_handle);\r
+ \r
+ /* Deinitialize the stream for new transfer */\r
+ HAL_MDMA_DeInit(&mdma_handle);\r
+ \r
+ /* Configure the DMA stream */\r
+ HAL_MDMA_Init(&mdma_handle); \r
+ \r
+ /* NVIC configuration for DMA transfer complete interrupt */\r
+ HAL_NVIC_SetPriority(SDRAM_MDMAx_IRQn, 0x0F, 0);\r
+ HAL_NVIC_EnableIRQ(SDRAM_MDMAx_IRQn);\r
+}\r
+\r
+/**\r
+ * @brief DeInitializes SDRAM MSP.\r
+ * @param hsdram SDRAM handle\r
+ * @param Params User parameters\r
+ * @retval None\r
+ */\r
+__weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params)\r
+{ \r
+ static MDMA_HandleTypeDef mdma_handle;\r
+ \r
+ /* Disable NVIC configuration for DMA interrupt */\r
+ HAL_NVIC_DisableIRQ(SDRAM_MDMAx_IRQn);\r
+\r
+ /* Deinitialize the stream for new transfer */\r
+ mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;\r
+ HAL_MDMA_DeInit(&mdma_handle);\r
+\r
+ /* GPIO pins clock, FMC clock and MDMA clock can be shut down in the applications\r
+ by surcharging this __weak function */ \r
+}\r
+\r
+/**\r
+ * @}\r
+ */ \r
+ \r
+/**\r
+ * @}\r
+ */ \r
+ \r
+/**\r
+ * @}\r
+ */ \r
+ \r
+/**\r
+ * @}\r
+ */ \r
+\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r