drv_sdram.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2016-08-20 xuzhuoyi The first version for STM32F42x
  9. */
  10. /* Includes ------------------------------------------------------------------*/
  11. #include "drv_sdram.h"
  12. #include "stm32f4xx_ll_fmc.h"
  13. #include <rtdevice.h>
  14. #include "board.h"
  15. SDRAM_HandleTypeDef hsdram1;
  16. FMC_SDRAM_CommandTypeDef command;
  17. /**
  18. * @brief SDRAM MSP Initialization
  19. * This function configures the hardware resources used in this example:
  20. * - Peripheral's clock enable
  21. * - Peripheral's GPIO Configuration
  22. * @param hsdram: SDRAM handle pointer
  23. * @retval None
  24. */
  25. void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram)
  26. {
  27. GPIO_InitTypeDef GPIO_Init_Structure;
  28. /*##-1- Enable peripherals and GPIO Clocks #################################*/
  29. /* Enable GPIO clocks */
  30. __HAL_RCC_GPIOB_CLK_ENABLE();
  31. __HAL_RCC_GPIOC_CLK_ENABLE();
  32. __HAL_RCC_GPIOD_CLK_ENABLE();
  33. __HAL_RCC_GPIOE_CLK_ENABLE();
  34. __HAL_RCC_GPIOF_CLK_ENABLE();
  35. __HAL_RCC_GPIOG_CLK_ENABLE();
  36. /* Enable FMC clock */
  37. __HAL_RCC_FMC_CLK_ENABLE();
  38. /*##-2- Configure peripheral GPIO ##########################################*/
  39. /*-- GPIOs Configuration -----------------------------------------------------*/
  40. /*
  41. +-------------------+--------------------+--------------------+--------------------+
  42. + SDRAM pins assignment +
  43. +-------------------+--------------------+--------------------+--------------------+
  44. | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 |
  45. | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 |
  46. | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG8 <-> FMC_SDCLK |
  47. | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS |
  48. | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 |--------------------+
  49. | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 |
  50. | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS |
  51. +-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 |
  52. | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 |
  53. | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 |
  54. | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 |
  55. +-------------------+--------------------+--------------------+
  56. | PB5 <-> FMC_SDCKE1|
  57. | PB6 <-> FMC_SDNE1 |
  58. | PC0 <-> FMC_SDNWE |
  59. +-------------------+
  60. */
  61. /* Common GPIO configuration */
  62. GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
  63. GPIO_Init_Structure.Speed = GPIO_SPEED_FAST;
  64. GPIO_Init_Structure.Pull = GPIO_NOPULL;
  65. GPIO_Init_Structure.Alternate = GPIO_AF12_FMC;
  66. /* GPIOB configuration */
  67. GPIO_Init_Structure.Pin = GPIO_PIN_5 | GPIO_PIN_6;
  68. HAL_GPIO_Init(GPIOB, &GPIO_Init_Structure);
  69. /* GPIOC configuration */
  70. GPIO_Init_Structure.Pin = GPIO_PIN_0;
  71. HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);
  72. /* GPIOD configuration */
  73. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 |
  74. GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
  75. GPIO_PIN_15;
  76. HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
  77. /* GPIOE configuration */
  78. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 |
  79. GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |
  80. GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
  81. GPIO_PIN_14 | GPIO_PIN_15;
  82. HAL_GPIO_Init(GPIOE, &GPIO_Init_Structure);
  83. /* GPIOF configuration */
  84. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
  85. GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
  86. GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
  87. GPIO_PIN_14 | GPIO_PIN_15;
  88. HAL_GPIO_Init(GPIOF, &GPIO_Init_Structure);
  89. /* GPIOG configuration */
  90. GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |
  91. GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
  92. HAL_GPIO_Init(GPIOG, &GPIO_Init_Structure);
  93. }
  94. /**
  95. * @brief SDRAM MSP De-Initialization
  96. * This function frees the hardware resources used in this example:
  97. * - Disable the Peripheral's clock
  98. * - Revert GPIO configuration to their default state
  99. * @param hsdram: SDRAM handle pointer
  100. * @retval None
  101. */
  102. void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram)
  103. {
  104. /*## Disable peripherals and GPIO Clocks ###################################*/
  105. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5 | GPIO_PIN_6);
  106. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
  107. HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 |\
  108. GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |\
  109. GPIO_PIN_15);
  110. HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 |\
  111. GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |\
  112. GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |\
  113. GPIO_PIN_14 | GPIO_PIN_15);
  114. HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |\
  115. GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |\
  116. GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |\
  117. GPIO_PIN_14 | GPIO_PIN_15);
  118. HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |\
  119. GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15);
  120. }
  121. /**
  122. * @brief Perform the SDRAM exernal memory inialization sequence
  123. * @param hsdram: SDRAM handle
  124. * @param Command: Pointer to SDRAM command structure
  125. * @retval None
  126. */
  127. static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
  128. {
  129. __IO uint32_t tmpmrd =0;
  130. /* Step 3: Configure a clock configuration enable command */
  131. Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  132. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  133. Command->AutoRefreshNumber = 1;
  134. Command->ModeRegisterDefinition = 0;
  135. /* Send the command */
  136. HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
  137. /* Step 4: Insert 100 ms delay */
  138. /* interrupt is not enable, just to delay some time. */
  139. for (tmpmrd = 0; tmpmrd < 0xfffff; tmpmrd ++)
  140. ;
  141. /* Step 5: Configure a PALL (precharge all) command */
  142. Command->CommandMode = FMC_SDRAM_CMD_PALL;
  143. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  144. Command->AutoRefreshNumber = 1;
  145. Command->ModeRegisterDefinition = 0;
  146. /* Send the command */
  147. HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
  148. /* Step 6 : Configure a Auto-Refresh command */
  149. Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  150. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  151. Command->AutoRefreshNumber = 4;
  152. Command->ModeRegisterDefinition = 0;
  153. /* Send the command */
  154. HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
  155. /* Step 7: Program the external memory mode register */
  156. tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
  157. SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
  158. SDRAM_MODEREG_CAS_LATENCY_3 |
  159. SDRAM_MODEREG_OPERATING_MODE_STANDARD |
  160. SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  161. Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  162. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  163. Command->AutoRefreshNumber = 1;
  164. Command->ModeRegisterDefinition = tmpmrd;
  165. /* Send the command */
  166. HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
  167. /* Step 8: Set the refresh rate counter */
  168. /* (15.62 us x Freq) - 20 */
  169. /* Set the device refresh counter */
  170. HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
  171. }
  172. /**
  173. * @brief Configures the FMC and GPIOs to interface with the SDRAM memory.
  174. * This function must be called before any read/write operation
  175. * on the SDRAM.
  176. * @param None
  177. * @retval None
  178. */
  179. void SDRAM_Init(void)
  180. {
  181. FMC_SDRAM_TimingTypeDef SDRAM_Timing;
  182. /*##-1- Configure the SDRAM device #########################################*/
  183. /* SDRAM device configuration */
  184. hsdram1.Instance = FMC_SDRAM_DEVICE;
  185. /* Timing configuration for 90 MHz of SD clock frequency (180MHz/2) */
  186. /* TMRD: 2 Clock cycles */
  187. SDRAM_Timing.LoadToActiveDelay = 2;
  188. /* TXSR: min=70ns (6x11.90ns) */
  189. SDRAM_Timing.ExitSelfRefreshDelay = 7;
  190. /* TRAS: min=42ns (4x11.90ns) max=120k (ns) */
  191. SDRAM_Timing.SelfRefreshTime = 4;
  192. /* TRC: min=63 (6x11.90ns) */
  193. SDRAM_Timing.RowCycleDelay = 7;
  194. /* TWR: 2 Clock cycles */
  195. SDRAM_Timing.WriteRecoveryTime = 2;
  196. /* TRP: 15ns => 2x11.90ns */
  197. SDRAM_Timing.RPDelay = 2;
  198. /* TRCD: 15ns => 2x11.90ns */
  199. SDRAM_Timing.RCDDelay = 2;
  200. hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
  201. hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  202. hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  203. hsdram1.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
  204. hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  205. hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  206. hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  207. hsdram1.Init.SDClockPeriod = SDCLOCK_PERIOD;
  208. hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
  209. hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
  210. /* Initialize the SDRAM controller */
  211. if(HAL_SDRAM_Init(&hsdram1, &SDRAM_Timing) != HAL_OK)
  212. {
  213. /* Initialization Error */
  214. Error_Handler();
  215. }
  216. /* Program the SDRAM external device */
  217. SDRAM_Initialization_Sequence(&hsdram1, &command);
  218. }
  219. rt_err_t sdram_hw_init(void)
  220. {
  221. SDRAM_Init();
  222. return RT_EOK;
  223. }
  224. static int rt_sdram_hw_init(void)
  225. {
  226. return (int)sdram_hw_init();
  227. }
  228. INIT_BOARD_EXPORT(rt_sdram_hw_init);