]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_M4_AMP_STM32H745I_Discovery_IAR/ST_code/BSP/STM32H745I-Discovery/stm32h745i_discovery_sdram.c
Add M7/M4 AMP demo.
[freertos] / FreeRTOS / Demo / CORTEX_M7_M4_AMP_STM32H745I_Discovery_IAR / ST_code / BSP / STM32H745I-Discovery / stm32h745i_discovery_sdram.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32h745i_discovery_sdram.c\r
4   * @author  MCD Application Team\r
5   * @brief   This file includes the SDRAM driver for the MT48LC4M32B2B5-6A memory \r
6   *          device mounted on STM32H745I_DISCOVERY boards.\r
7   ******************************************************************************\r
8   @verbatim\r
9   How To use this driver:\r
10   -----------------------\r
11    - This driver is used to drive the MT48LC4M32B2B5-6A SDRAM external memory mounted\r
12      on STM32H745I_DISCOVERY board.\r
13    - This driver does not need a specific component driver for the SDRAM device\r
14      to be included with.\r
15 \r
16   Driver description:\r
17   ------------------\r
18   + Initialization steps:\r
19      o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This \r
20        function includes the MSP layer hardware resources initialization and the\r
21        FMC controller configuration to interface with the external SDRAM memory.\r
22      o It contains the SDRAM initialization sequence to program the SDRAM external \r
23        device using the function BSP_SDRAM_Initialization_sequence(). Note that this \r
24        sequence is standard for all SDRAM devices, but can include some differences\r
25        from a device to another. If it is the case, the right sequence should be \r
26        implemented separately.\r
27   \r
28   + SDRAM read/write operations\r
29      o SDRAM external memory can be accessed with read/write operations once it is\r
30        initialized.\r
31        Read/write operation can be performed with AHB access using the functions\r
32        BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by MDMA transfer using the functions\r
33        BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA().\r
34      o The AHB access is performed with 32-bit width transaction, the MDMA transfer\r
35        configuration is fixed at single (no burst) word transfer (see the \r
36        SDRAM_MspInit() static function).\r
37      o User can implement his own functions for read/write access with his desired \r
38        configurations.\r
39      o If interrupt mode is used for MDMA transfer, the function BSP_SDRAM_MDMA_IRQHandler()\r
40        is called in IRQ handler file, to serve the generated interrupt once the MDMA \r
41        transfer is complete.\r
42      o You can send a command to the SDRAM device in runtime using the function \r
43        BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between \r
44        the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure. \r
45   @endverbatim\r
46   ******************************************************************************\r
47   * @attention\r
48   *\r
49   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.\r
50   * All rights reserved.</center></h2>\r
51   *\r
52   * This software component is licensed by ST under BSD 3-Clause license,\r
53   * the "License"; You may not use this file except in compliance with the\r
54   * License. You may obtain a copy of the License at:\r
55   *                        opensource.org/licenses/BSD-3-Clause\r
56   *\r
57   ******************************************************************************\r
58   */\r
59 \r
60 /* Includes ------------------------------------------------------------------*/\r
61 #include "stm32h745i_discovery_sdram.h"\r
62 \r
63 /** @addtogroup BSP\r
64   * @{\r
65   */\r
66 \r
67 /** @addtogroup STM32H745I_DISCOVERY\r
68   * @{\r
69   */ \r
70   \r
71 /** @defgroup  STM32H745I_DISCOVERY_SDRAM STM32H745I_DISCOVERY_SDRAM\r
72   * @{\r
73   */ \r
74 \r
75 \r
76 /** @defgroup STM32H745I_DISCOVERY_SDRAM_Private_Variables Private Variables\r
77   * @{\r
78   */       \r
79 SDRAM_HandleTypeDef sdramHandle;\r
80 static FMC_SDRAM_TimingTypeDef Timing;\r
81 static FMC_SDRAM_CommandTypeDef Command;\r
82 /**\r
83   * @}\r
84   */ \r
85 \r
86     \r
87 /** @defgroup STM32H745I_DISCOVERY_SDRAM_Exported_Functions Exported Functions\r
88   * @{\r
89   */ \r
90 \r
91 /**\r
92   * @brief  Initializes the SDRAM device.\r
93   * @retval SDRAM status\r
94   */\r
95 uint8_t BSP_SDRAM_Init(void)\r
96\r
97   static uint8_t sdramstatus = SDRAM_OK;\r
98   /* SDRAM device configuration */\r
99   sdramHandle.Instance = FMC_SDRAM_DEVICE;\r
100     \r
101   /* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */\r
102   Timing.LoadToActiveDelay    = 2;\r
103   Timing.ExitSelfRefreshDelay = 7;\r
104   Timing.SelfRefreshTime      = 4;\r
105   Timing.RowCycleDelay        = 7;\r
106   Timing.WriteRecoveryTime    = 2;\r
107   Timing.RPDelay              = 2;\r
108   Timing.RCDDelay             = 2;\r
109   \r
110   sdramHandle.Init.SDBank             = FMC_SDRAM_BANK2;\r
111   sdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;\r
112   sdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;\r
113   sdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;\r
114   sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;\r
115   sdramHandle.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_3;\r
116   sdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;\r
117   sdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;\r
118   sdramHandle.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;\r
119   sdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0;\r
120   \r
121   /* SDRAM controller initialization */\r
122 \r
123   BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */\r
124 \r
125   if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)\r
126   {\r
127     sdramstatus = SDRAM_ERROR;\r
128   }\r
129   else\r
130   {\r
131     /* SDRAM initialization sequence */\r
132     BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);\r
133   }\r
134 \r
135   return sdramstatus;\r
136 }\r
137 \r
138 /**\r
139   * @brief  DeInitializes the SDRAM device.\r
140   * @retval SDRAM status\r
141   */\r
142 uint8_t BSP_SDRAM_DeInit(void)\r
143\r
144   static uint8_t sdramstatus = SDRAM_OK;\r
145   /* SDRAM device de-initialization */\r
146   sdramHandle.Instance = FMC_SDRAM_DEVICE;\r
147 \r
148   if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK)\r
149   {\r
150     sdramstatus = SDRAM_ERROR;\r
151   }\r
152   else\r
153   {\r
154     /* SDRAM controller de-initialization */\r
155     BSP_SDRAM_MspDeInit(&sdramHandle, NULL);\r
156   }\r
157  \r
158   return sdramstatus;\r
159 }\r
160 \r
161 /**\r
162   * @brief  Programs the SDRAM device.\r
163   * @param  RefreshCount: SDRAM refresh counter value \r
164   * @retval None\r
165   */\r
166 void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)\r
167 {\r
168   __IO uint32_t tmpmrd = 0;\r
169   \r
170   /* Step 1: Configure a clock configuration enable command */\r
171   Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;\r
172   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;\r
173   Command.AutoRefreshNumber      = 1;\r
174   Command.ModeRegisterDefinition = 0;\r
175 \r
176   /* Send the command */\r
177   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
178 \r
179   /* Step 2: Insert 100 us minimum delay */ \r
180   /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */\r
181   HAL_Delay(1);\r
182     \r
183   /* Step 3: Configure a PALL (precharge all) command */ \r
184   Command.CommandMode            = FMC_SDRAM_CMD_PALL;\r
185   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;\r
186   Command.AutoRefreshNumber      = 1;\r
187   Command.ModeRegisterDefinition = 0;\r
188 \r
189   /* Send the command */\r
190   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);  \r
191   \r
192   /* Step 4: Configure an Auto Refresh command */ \r
193   Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;\r
194   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;\r
195   Command.AutoRefreshNumber      = 8;\r
196   Command.ModeRegisterDefinition = 0;\r
197 \r
198   /* Send the command */\r
199   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
200   \r
201   /* Step 5: Program the external memory mode register */\r
202   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |\\r
203                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |\\r
204                      SDRAM_MODEREG_CAS_LATENCY_3           |\\r
205                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |\\r
206                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;\r
207   \r
208   Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;\r
209   Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;\r
210   Command.AutoRefreshNumber      = 1;\r
211   Command.ModeRegisterDefinition = tmpmrd;\r
212 \r
213   /* Send the command */\r
214   HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);\r
215   \r
216   /* Step 6: Set the refresh rate counter */\r
217   /* Set the device refresh rate */\r
218   HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount); \r
219 }\r
220 \r
221 /**\r
222   * @brief  Reads an amount of data from the SDRAM memory in polling mode.\r
223   * @param  uwStartAddress: Read start address\r
224   * @param  pData: Pointer to data to be read  \r
225   * @param  uwDataSize: Size of read data from the memory\r
226   * @retval SDRAM status\r
227   */\r
228 uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)\r
229 {\r
230   if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
231   {\r
232     return SDRAM_ERROR;\r
233   }\r
234   else\r
235   {\r
236     return SDRAM_OK;\r
237   } \r
238 }\r
239 \r
240 /**\r
241   * @brief  Reads an amount of data from the SDRAM memory in DMA mode.\r
242   * @param  uwStartAddress: Read start address\r
243   * @param  pData: Pointer to data to be read  \r
244   * @param  uwDataSize: Size of read data from the memory\r
245   * @retval SDRAM status\r
246   */\r
247 uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)\r
248 {\r
249   if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
250   {\r
251     return SDRAM_ERROR;\r
252   }\r
253   else\r
254   {\r
255     return SDRAM_OK;\r
256   }     \r
257 }\r
258 \r
259 /**\r
260   * @brief  Writes an amount of data to the SDRAM memory in polling mode.\r
261   * @param  uwStartAddress: Write start address\r
262   * @param  pData: Pointer to data to be written  \r
263   * @param  uwDataSize: Size of written data from the memory\r
264   * @retval SDRAM status\r
265   */\r
266 uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) \r
267 {\r
268   if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
269   {\r
270     return SDRAM_ERROR;\r
271   }\r
272   else\r
273   {\r
274     return SDRAM_OK;\r
275   }\r
276 }\r
277 \r
278 /**\r
279   * @brief  Writes an amount of data to the SDRAM memory in DMA mode.\r
280   * @param  uwStartAddress: Write start address\r
281   * @param  pData: Pointer to data to be written  \r
282   * @param  uwDataSize: Size of written data from the memory\r
283   * @retval SDRAM status\r
284   */\r
285 uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) \r
286 {\r
287   if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)\r
288   {\r
289     return SDRAM_ERROR;\r
290   }\r
291   else\r
292   {\r
293     return SDRAM_OK;\r
294   } \r
295 }\r
296 \r
297 /**\r
298   * @brief  Sends command to the SDRAM bank.\r
299   * @param  SdramCmd: Pointer to SDRAM command structure \r
300   * @retval SDRAM status\r
301   */  \r
302 uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)\r
303 {\r
304   if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)\r
305   {\r
306     return SDRAM_ERROR;\r
307   }\r
308   else\r
309   {\r
310     return SDRAM_OK;\r
311   }\r
312 }\r
313 \r
314 /**\r
315   * @brief  Initializes SDRAM MSP.\r
316   * @param  hsdram SDRAM handle\r
317   * @param  Params User parameters\r
318   * @retval None\r
319   */\r
320 __weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)\r
321 {  \r
322   static MDMA_HandleTypeDef mdma_handle;\r
323   GPIO_InitTypeDef gpio_init_structure;\r
324   \r
325   /* Enable FMC clock */\r
326   __HAL_RCC_FMC_CLK_ENABLE();\r
327   \r
328   /* Enable chosen MDMAx clock */\r
329   __MDMAx_CLK_ENABLE();\r
330 \r
331   /* Enable GPIOs clock */\r
332   __HAL_RCC_GPIOD_CLK_ENABLE();\r
333   __HAL_RCC_GPIOE_CLK_ENABLE();\r
334   __HAL_RCC_GPIOF_CLK_ENABLE();\r
335   __HAL_RCC_GPIOG_CLK_ENABLE();\r
336   __HAL_RCC_GPIOH_CLK_ENABLE();\r
337   \r
338   /* Common GPIO configuration */\r
339   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;\r
340   gpio_init_structure.Pull      = GPIO_PULLUP;\r
341   gpio_init_structure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;\r
342   gpio_init_structure.Alternate = GPIO_AF12_FMC;\r
343   \r
344   /* GPIOD configuration */\r
345   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8| GPIO_PIN_9 | GPIO_PIN_10 |\\r
346                               GPIO_PIN_14 | GPIO_PIN_15;\r
347  \r
348    \r
349   HAL_GPIO_Init(GPIOD, &gpio_init_structure);\r
350 \r
351   /* GPIOE configuration */  \r
352   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\\r
353                               GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\\r
354                               GPIO_PIN_15;\r
355       \r
356   HAL_GPIO_Init(GPIOE, &gpio_init_structure);\r
357   \r
358   /* GPIOF configuration */  \r
359   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\\r
360                               GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\\r
361                               GPIO_PIN_15;\r
362     \r
363   HAL_GPIO_Init(GPIOF, &gpio_init_structure);\r
364   \r
365   /* GPIOG configuration */  \r
366   gpio_init_structure.Pin   = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;\r
367   HAL_GPIO_Init(GPIOG, &gpio_init_structure);\r
368 \r
369   /* GPIOH configuration */  \r
370   gpio_init_structure.Pin   = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 ;\r
371   HAL_GPIO_Init(GPIOH, &gpio_init_structure); \r
372   \r
373 \r
374   \r
375   /* Configure common MDMA parameters */\r
376   mdma_handle.Init.Request = MDMA_REQUEST_SW;\r
377   mdma_handle.Init.TransferTriggerMode = MDMA_BLOCK_TRANSFER;\r
378   mdma_handle.Init.Priority = MDMA_PRIORITY_HIGH;\r
379   mdma_handle.Init.Endianness = MDMA_LITTLE_ENDIANNESS_PRESERVE;\r
380   mdma_handle.Init.SourceInc = MDMA_SRC_INC_WORD;\r
381   mdma_handle.Init.DestinationInc = MDMA_DEST_INC_WORD;\r
382   mdma_handle.Init.SourceDataSize = MDMA_SRC_DATASIZE_WORD;\r
383   mdma_handle.Init.DestDataSize = MDMA_DEST_DATASIZE_WORD;\r
384   mdma_handle.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;                            \r
385   mdma_handle.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;\r
386   mdma_handle.Init.DestBurst = MDMA_DEST_BURST_SINGLE;\r
387   mdma_handle.Init.BufferTransferLength = 128;\r
388   mdma_handle.Init.SourceBlockAddressOffset = 0;\r
389   mdma_handle.Init.DestBlockAddressOffset = 0; \r
390    \r
391   \r
392   mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;\r
393   \r
394    /* Associate the DMA handle */\r
395   __HAL_LINKDMA(hsdram, hmdma, mdma_handle);\r
396   \r
397   /* Deinitialize the stream for new transfer */\r
398   HAL_MDMA_DeInit(&mdma_handle);\r
399   \r
400   /* Configure the DMA stream */\r
401   HAL_MDMA_Init(&mdma_handle); \r
402   \r
403   /* NVIC configuration for DMA transfer complete interrupt */\r
404   HAL_NVIC_SetPriority(SDRAM_MDMAx_IRQn, 0x0F, 0);\r
405   HAL_NVIC_EnableIRQ(SDRAM_MDMAx_IRQn);\r
406 }\r
407 \r
408 /**\r
409   * @brief  DeInitializes SDRAM MSP.\r
410   * @param  hsdram SDRAM handle\r
411   * @param  Params User parameters\r
412   * @retval None\r
413   */\r
414 __weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef  *hsdram, void *Params)\r
415 {  \r
416     static MDMA_HandleTypeDef mdma_handle;\r
417   \r
418     /* Disable NVIC configuration for DMA interrupt */\r
419     HAL_NVIC_DisableIRQ(SDRAM_MDMAx_IRQn);\r
420 \r
421     /* Deinitialize the stream for new transfer */\r
422     mdma_handle.Instance = SDRAM_MDMAx_CHANNEL;\r
423     HAL_MDMA_DeInit(&mdma_handle);\r
424 \r
425     /* GPIO pins clock, FMC clock and MDMA clock can be shut down in the applications\r
426        by surcharging this __weak function */ \r
427 }\r
428 \r
429 /**\r
430   * @}\r
431   */  \r
432   \r
433 /**\r
434   * @}\r
435   */ \r
436   \r
437 /**\r
438   * @}\r
439   */ \r
440   \r
441 /**\r
442   * @}\r
443   */ \r
444 \r
445 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r