drv_sdram.c 10 KB

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