drv_sdram.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * File : drv_sdram.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2018-05-17 ZYH first implementation
  23. */
  24. #include "drv_sdram.h"
  25. #include <rtthread.h>
  26. #ifdef BSP_USING_SDRAM
  27. SDRAM_HandleTypeDef hsdram;
  28. static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command);
  29. /* FMC initialization function */
  30. void MX_FMC_Init(void)
  31. {
  32. FMC_SDRAM_TimingTypeDef SdramTiming;
  33. FMC_SDRAM_CommandTypeDef command;
  34. /** Perform the SDRAM1 memory initialization sequence
  35. */
  36. hsdram.Instance = FMC_SDRAM_DEVICE;
  37. /* hsdram.Init */
  38. hsdram.Init.SDBank = FMC_SDRAM_BANK1;
  39. hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  40. hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  41. hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
  42. hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  43. hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
  44. hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  45. hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  46. hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  47. hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  48. /* SdramTiming */
  49. SdramTiming.LoadToActiveDelay = 2;
  50. SdramTiming.ExitSelfRefreshDelay = 6;
  51. SdramTiming.SelfRefreshTime = 4;
  52. SdramTiming.RowCycleDelay = 6;
  53. SdramTiming.WriteRecoveryTime = 2;
  54. SdramTiming.RPDelay = 2;
  55. SdramTiming.RCDDelay = 2;
  56. HAL_SDRAM_Init(&hsdram, &SdramTiming);
  57. BSP_SDRAM_Initialization_Sequence(&hsdram, &command);
  58. }
  59. static uint32_t FMC_Initialized = 0;
  60. static void HAL_FMC_MspInit(void)
  61. {
  62. GPIO_InitTypeDef GPIO_InitStruct;
  63. if (FMC_Initialized)
  64. {
  65. return;
  66. }
  67. FMC_Initialized = 1;
  68. /* Peripheral clock enable */
  69. __HAL_RCC_FMC_CLK_ENABLE();
  70. __HAL_RCC_GPIOD_CLK_ENABLE();
  71. __HAL_RCC_GPIOE_CLK_ENABLE();
  72. __HAL_RCC_GPIOF_CLK_ENABLE();
  73. __HAL_RCC_GPIOG_CLK_ENABLE();
  74. __HAL_RCC_GPIOH_CLK_ENABLE();
  75. __HAL_RCC_GPIOI_CLK_ENABLE();
  76. /** FMC GPIO Configuration
  77. PE1 ------> FMC_NBL1
  78. PE0 ------> FMC_NBL0
  79. PG15 ------> FMC_SDNCAS
  80. PD0 ------> FMC_D2
  81. PI4 ------> FMC_NBL2
  82. PD1 ------> FMC_D3
  83. PI3 ------> FMC_D27
  84. PI2 ------> FMC_D26
  85. PF0 ------> FMC_A0
  86. PI5 ------> FMC_NBL3
  87. PI7 ------> FMC_D29
  88. PI10 ------> FMC_D31
  89. PI6 ------> FMC_D28
  90. PH15 ------> FMC_D23
  91. PI1 ------> FMC_D25
  92. PF1 ------> FMC_A1
  93. PI9 ------> FMC_D30
  94. PH13 ------> FMC_D21
  95. PH14 ------> FMC_D22
  96. PI0 ------> FMC_D24
  97. PF2 ------> FMC_A2
  98. PF3 ------> FMC_A3
  99. PG8 ------> FMC_SDCLK
  100. PF4 ------> FMC_A4
  101. PH5 ------> FMC_SDNWE
  102. PH3 ------> FMC_SDNE0
  103. PF5 ------> FMC_A5
  104. PH2 ------> FMC_SDCKE0
  105. PD15 ------> FMC_D1
  106. PD10 ------> FMC_D15
  107. PD14 ------> FMC_D0
  108. PD9 ------> FMC_D14
  109. PD8 ------> FMC_D13
  110. PF12 ------> FMC_A6
  111. PG1 ------> FMC_A11
  112. PF15 ------> FMC_A9
  113. PH12 ------> FMC_D20
  114. PF13 ------> FMC_A7
  115. PG0 ------> FMC_A10
  116. PE8 ------> FMC_D5
  117. PG5 ------> FMC_BA1
  118. PG4 ------> FMC_BA0
  119. PH9 ------> FMC_D17
  120. PH11 ------> FMC_D19
  121. PF14 ------> FMC_A8
  122. PF11 ------> FMC_SDNRAS
  123. PE9 ------> FMC_D6
  124. PE11 ------> FMC_D8
  125. PE14 ------> FMC_D11
  126. PH8 ------> FMC_D16
  127. PH10 ------> FMC_D18
  128. PE7 ------> FMC_D4
  129. PE10 ------> FMC_D7
  130. PE12 ------> FMC_D9
  131. PE15 ------> FMC_D12
  132. PE13 ------> FMC_D10
  133. */
  134. /* GPIO_InitStruct */
  135. GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_0 | GPIO_PIN_8 | GPIO_PIN_9
  136. | GPIO_PIN_11 | GPIO_PIN_14 | GPIO_PIN_7 | GPIO_PIN_10
  137. | GPIO_PIN_12 | GPIO_PIN_15 | GPIO_PIN_13;
  138. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  139. GPIO_InitStruct.Pull = GPIO_NOPULL;
  140. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  141. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  142. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  143. /* GPIO_InitStruct */
  144. GPIO_InitStruct.Pin = GPIO_PIN_15 | GPIO_PIN_8 | GPIO_PIN_1 | GPIO_PIN_0
  145. | GPIO_PIN_5 | GPIO_PIN_4;
  146. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  147. GPIO_InitStruct.Pull = GPIO_NOPULL;
  148. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  149. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  150. HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
  151. /* GPIO_InitStruct */
  152. GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_15 | GPIO_PIN_10
  153. | GPIO_PIN_14 | GPIO_PIN_9 | GPIO_PIN_8;
  154. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  155. GPIO_InitStruct.Pull = GPIO_NOPULL;
  156. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  157. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  158. HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  159. /* GPIO_InitStruct */
  160. GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_5
  161. | GPIO_PIN_7 | GPIO_PIN_10 | GPIO_PIN_6 | GPIO_PIN_1
  162. | GPIO_PIN_9 | GPIO_PIN_0;
  163. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  164. GPIO_InitStruct.Pull = GPIO_NOPULL;
  165. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  166. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  167. HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  168. /* GPIO_InitStruct */
  169. GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3
  170. | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_12 | GPIO_PIN_15
  171. | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_11;
  172. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  173. GPIO_InitStruct.Pull = GPIO_NOPULL;
  174. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  175. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  176. HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
  177. /* GPIO_InitStruct */
  178. GPIO_InitStruct.Pin = GPIO_PIN_15 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_5
  179. | GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_12 | GPIO_PIN_9
  180. | GPIO_PIN_11 | GPIO_PIN_8 | GPIO_PIN_10;
  181. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  182. GPIO_InitStruct.Pull = GPIO_NOPULL;
  183. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  184. GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  185. HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  186. }
  187. void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *sdramHandle)
  188. {
  189. HAL_FMC_MspInit();
  190. }
  191. static uint32_t FMC_DeInitialized = 0;
  192. static void HAL_FMC_MspDeInit(void)
  193. {
  194. if (FMC_DeInitialized)
  195. {
  196. return;
  197. }
  198. FMC_DeInitialized = 1;
  199. /* Peripheral clock enable */
  200. __HAL_RCC_FMC_CLK_DISABLE();
  201. /** FMC GPIO Configuration
  202. PE1 ------> FMC_NBL1
  203. PE0 ------> FMC_NBL0
  204. PG15 ------> FMC_SDNCAS
  205. PD0 ------> FMC_D2
  206. PI4 ------> FMC_NBL2
  207. PD1 ------> FMC_D3
  208. PI3 ------> FMC_D27
  209. PI2 ------> FMC_D26
  210. PF0 ------> FMC_A0
  211. PI5 ------> FMC_NBL3
  212. PI7 ------> FMC_D29
  213. PI10 ------> FMC_D31
  214. PI6 ------> FMC_D28
  215. PH15 ------> FMC_D23
  216. PI1 ------> FMC_D25
  217. PF1 ------> FMC_A1
  218. PI9 ------> FMC_D30
  219. PH13 ------> FMC_D21
  220. PH14 ------> FMC_D22
  221. PI0 ------> FMC_D24
  222. PF2 ------> FMC_A2
  223. PF3 ------> FMC_A3
  224. PG8 ------> FMC_SDCLK
  225. PF4 ------> FMC_A4
  226. PH5 ------> FMC_SDNWE
  227. PH3 ------> FMC_SDNE0
  228. PF5 ------> FMC_A5
  229. PH2 ------> FMC_SDCKE0
  230. PD15 ------> FMC_D1
  231. PD10 ------> FMC_D15
  232. PD14 ------> FMC_D0
  233. PD9 ------> FMC_D14
  234. PD8 ------> FMC_D13
  235. PF12 ------> FMC_A6
  236. PG1 ------> FMC_A11
  237. PF15 ------> FMC_A9
  238. PH12 ------> FMC_D20
  239. PF13 ------> FMC_A7
  240. PG0 ------> FMC_A10
  241. PE8 ------> FMC_D5
  242. PG5 ------> FMC_BA1
  243. PG4 ------> FMC_BA0
  244. PH9 ------> FMC_D17
  245. PH11 ------> FMC_D19
  246. PF14 ------> FMC_A8
  247. PF11 ------> FMC_SDNRAS
  248. PE9 ------> FMC_D6
  249. PE11 ------> FMC_D8
  250. PE14 ------> FMC_D11
  251. PH8 ------> FMC_D16
  252. PH10 ------> FMC_D18
  253. PE7 ------> FMC_D4
  254. PE10 ------> FMC_D7
  255. PE12 ------> FMC_D9
  256. PE15 ------> FMC_D12
  257. PE13 ------> FMC_D10
  258. */
  259. HAL_GPIO_DeInit(GPIOE, GPIO_PIN_1 | GPIO_PIN_0 | GPIO_PIN_8 | GPIO_PIN_9
  260. | GPIO_PIN_11 | GPIO_PIN_14 | GPIO_PIN_7 | GPIO_PIN_10
  261. | GPIO_PIN_12 | GPIO_PIN_15 | GPIO_PIN_13);
  262. HAL_GPIO_DeInit(GPIOG, GPIO_PIN_15 | GPIO_PIN_8 | GPIO_PIN_1 | GPIO_PIN_0
  263. | GPIO_PIN_5 | GPIO_PIN_4);
  264. HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_15 | GPIO_PIN_10
  265. | GPIO_PIN_14 | GPIO_PIN_9 | GPIO_PIN_8);
  266. HAL_GPIO_DeInit(GPIOI, GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_5
  267. | GPIO_PIN_7 | GPIO_PIN_10 | GPIO_PIN_6 | GPIO_PIN_1
  268. | GPIO_PIN_9 | GPIO_PIN_0);
  269. HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3
  270. | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_12 | GPIO_PIN_15
  271. | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_11);
  272. HAL_GPIO_DeInit(GPIOH, GPIO_PIN_15 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_5
  273. | GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_12 | GPIO_PIN_9
  274. | GPIO_PIN_11 | GPIO_PIN_8 | GPIO_PIN_10);
  275. }
  276. void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *sdramHandle)
  277. {
  278. HAL_FMC_MspDeInit();
  279. }
  280. static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
  281. {
  282. __IO uint32_t tmpmrd = 0;
  283. int delay = 216000/3;
  284. /* Step 3: Configure a clock configuration enable command */
  285. Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  286. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  287. Command->AutoRefreshNumber = 1;
  288. Command->ModeRegisterDefinition = 0;
  289. /* Send the command */
  290. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  291. /* Step 4: Insert 100 us minimum delay */
  292. /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  293. while(delay)
  294. {
  295. delay--;
  296. }
  297. /* Step 5: Configure a PALL (precharge all) command */
  298. Command->CommandMode = FMC_SDRAM_CMD_PALL;
  299. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  300. Command->AutoRefreshNumber = 1;
  301. Command->ModeRegisterDefinition = 0;
  302. /* Send the command */
  303. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  304. /* Step 6 : Configure a Auto-Refresh command */
  305. Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  306. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  307. Command->AutoRefreshNumber = 8;
  308. Command->ModeRegisterDefinition = 0;
  309. /* Send the command */
  310. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  311. /* Step 7: Program the external memory mode register */
  312. tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
  313. SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
  314. SDRAM_MODEREG_CAS_LATENCY_2 |
  315. SDRAM_MODEREG_OPERATING_MODE_STANDARD |
  316. SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  317. Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  318. Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  319. Command->AutoRefreshNumber = 1;
  320. Command->ModeRegisterDefinition = tmpmrd;
  321. /* Send the command */
  322. HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
  323. /* Step 8: Set the refresh rate counter */
  324. /* (15.62 us x Freq) - 20 */
  325. /* Set the device refresh counter */
  326. hsdram->Instance->SDRTR |= ((uint32_t)((1292) << 1));
  327. }
  328. int bsp_sdram_hw_init(void)
  329. {
  330. MX_FMC_Init();
  331. return 0;
  332. }
  333. #endif