drv_sdram.c 10 KB

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