1
0

drv_sdram.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-05-16 shelton first version
  9. */
  10. #include "drv_common.h"
  11. #ifdef BSP_USING_SDRAM
  12. #include "drv_sdram.h"
  13. #define DRV_DEBUG
  14. #define LOG_TAG "drv.sdram"
  15. #include <drv_log.h>
  16. #ifdef RT_USING_MEMHEAP_AS_HEAP
  17. static struct rt_memheap system_heap;
  18. #endif
  19. static void sdram_init_sequence(xmc_cmd_bank1_2_type cmd_bank)
  20. {
  21. xmc_sdram_cmd_type sdram_cmd_struct;
  22. uint32_t timeout = 0xffff, delay = 0;
  23. sdram_cmd_struct.cmd = XMC_CMD_CLK;
  24. sdram_cmd_struct.auto_refresh = 1;
  25. sdram_cmd_struct.cmd_banks = cmd_bank;
  26. sdram_cmd_struct.data = 0;
  27. xmc_sdram_cmd(&sdram_cmd_struct);
  28. while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
  29. {
  30. timeout --;
  31. }
  32. /* insert 100 ms delay */
  33. for (delay = 0; delay < 0xffff; delay ++)
  34. ;
  35. sdram_cmd_struct.cmd = XMC_CMD_PRECHARG_ALL;
  36. sdram_cmd_struct.auto_refresh = 1;
  37. sdram_cmd_struct.cmd_banks = cmd_bank;
  38. sdram_cmd_struct.data = 0;
  39. xmc_sdram_cmd(&sdram_cmd_struct);
  40. timeout = 0xffff;
  41. while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
  42. {
  43. timeout --;
  44. }
  45. /* set refresh rate */
  46. xmc_sdram_refresh_counter_set(SDRAM_REFRESH_COUNT);
  47. sdram_cmd_struct.cmd = XMC_CMD_AUTO_REFRESH;
  48. sdram_cmd_struct.auto_refresh = 8;
  49. sdram_cmd_struct.cmd_banks = cmd_bank;
  50. sdram_cmd_struct.data = 0;
  51. xmc_sdram_cmd(&sdram_cmd_struct);
  52. timeout = 0xffff;
  53. while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
  54. {
  55. timeout --;
  56. }
  57. sdram_cmd_struct.cmd = XMC_CMD_LOAD_MODE;
  58. sdram_cmd_struct.auto_refresh = 1;
  59. sdram_cmd_struct.cmd_banks = cmd_bank;
  60. #if SDRAM_DATA_WIDTH == 8
  61. sdram_cmd_struct.data = (uint32_t)SDRAM_BURST_LEN_1 |
  62. #elif SDRAM_DATA_WIDTH == 16
  63. sdram_cmd_struct.data = (uint32_t)SDRAM_BURST_LEN_2 |
  64. #endif
  65. SDRAM_BURST_SEQUENTIAL |
  66. #if SDRAM_CAS_LATENCY == 3
  67. SDRAM_CAS_LATENCY_3 |
  68. #else
  69. SDRAM_CAS_LATENCY_2 |
  70. #endif
  71. SDRAM_OPERATING_MODE_STANDARD |
  72. SDRAM_WR_BURST_SINGLE;
  73. xmc_sdram_cmd(&sdram_cmd_struct);
  74. timeout = 0xffff;
  75. while((xmc_flag_status_get(XMC_BANK5_6_SDRAM, XMC_BUSY_FLAG) != RESET) && (timeout > 0))
  76. {
  77. timeout --;
  78. }
  79. }
  80. static int sdram_init(void)
  81. {
  82. int result = RT_EOK;
  83. xmc_cmd_bank1_2_type target_bank = XMC_CMD_BANK1;
  84. xmc_sdram_init_type sdram_init_struct;
  85. xmc_sdram_timing_type sdram_timing_struct;
  86. at32_msp_sdram_init(NULL);
  87. /* xmc configuration */
  88. xmc_sdram_default_para_init(&sdram_init_struct, &sdram_timing_struct);
  89. #if SDRAM_TARGET_BANK == 1
  90. sdram_init_struct.sdram_bank = XMC_SDRAM_BANK1;
  91. #else
  92. sdram_init_struct.sdram_bank = XMC_SDRAM_BANK2;
  93. #endif
  94. #if SDRAM_COLUMN_BITS == 8
  95. sdram_init_struct.column_address = XMC_COLUMN_8;
  96. #elif SDRAM_COLUMN_BITS == 9
  97. sdram_init_struct.column_address = XMC_COLUMN_9;
  98. #elif SDRAM_COLUMN_BITS == 10
  99. sdram_init_struct.column_address = XMC_COLUMN_10;
  100. #else
  101. sdram_init_struct.column_address = XMC_COLUMN_11;
  102. #endif
  103. #if SDRAM_ROW_BITS == 11
  104. sdram_init_struct.row_address = XMC_ROW_11;
  105. #elif SDRAM_ROW_BITS == 12
  106. sdram_init_struct.row_address = XMC_ROW_12;
  107. #else
  108. sdram_init_struct.row_address = XMC_ROW_13;
  109. #endif
  110. #if SDRAM_DATA_WIDTH == 8
  111. sdram_init_struct.width = XMC_MEM_WIDTH_8;
  112. #elif SDRAM_DATA_WIDTH == 16
  113. sdram_init_struct.width = XMC_MEM_WIDTH_16;
  114. #endif
  115. sdram_init_struct.internel_banks = XMC_INBK_4;
  116. #if SDRAM_CAS_LATENCY == 1
  117. sdram_init_struct.cas = XMC_CAS_1;
  118. #elif SDRAM_CAS_LATENCY == 2
  119. sdram_init_struct.cas = XMC_CAS_2;
  120. #else
  121. sdram_init_struct.cas = XMC_CAS_3;
  122. #endif
  123. #if SDRAM_RPIPE_DELAY == 0
  124. sdram_init_struct.read_delay = XMC_READ_DELAY_0;
  125. #elif SDRAM_RPIPE_DELAY == 1
  126. sdram_init_struct.read_delay = XMC_READ_DELAY_1;
  127. #else
  128. sdram_init_struct.read_delay = XMC_READ_DELAY_2;
  129. #endif
  130. #if SDCLOCK_PERIOD == 2
  131. sdram_init_struct.clkdiv = XMC_CLKDIV_2;
  132. #else
  133. sdram_init_struct.clkdiv = XMC_CLKDIV_3;
  134. #endif
  135. sdram_init_struct.write_protection = FALSE;
  136. sdram_init_struct.burst_read = TRUE;
  137. sdram_timing_struct.tmrd = LOADTOACTIVEDELAY;
  138. sdram_timing_struct.txsr = EXITSELFREFRESHDELAY;
  139. sdram_timing_struct.tras = SELFREFRESHTIME;
  140. sdram_timing_struct.trc = ROWCYCLEDELAY;
  141. sdram_timing_struct.twr = WRITERECOVERYTIME;
  142. sdram_timing_struct.trp = RPDELAY;
  143. sdram_timing_struct.trcd = RCDDELAY;
  144. xmc_sdram_init(&sdram_init_struct, &sdram_timing_struct);
  145. #if SDRAM_TARGET_BANK == 1
  146. target_bank = XMC_CMD_BANK1;
  147. #else
  148. target_bank = XMC_CMD_BANK2;
  149. #endif
  150. sdram_init_sequence(target_bank);
  151. #ifdef RT_USING_MEMHEAP_AS_HEAP
  152. /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
  153. rt_memheap_init(&system_heap, "sdram", (void *)SDRAM_BANK_ADDR, SDRAM_SIZE);
  154. #endif
  155. return result;
  156. }
  157. INIT_BOARD_EXPORT(sdram_init);
  158. #ifdef DRV_DEBUG
  159. #ifdef FINSH_USING_MSH
  160. int sdram_sample(void)
  161. {
  162. int i = 0;
  163. uint32_t start_time = 0, time_cast = 0;
  164. #if SDRAM_DATA_WIDTH == 8
  165. char data_width = 1;
  166. uint8_t data = 0;
  167. #elif SDRAM_DATA_WIDTH == 16
  168. char data_width = 2;
  169. uint16_t data = 0;
  170. #else
  171. char data_width = 4;
  172. uint32_t data = 0;
  173. #endif
  174. /* write data */
  175. LOG_D("writing the %ld bytes data, waiting....", SDRAM_SIZE);
  176. start_time = rt_tick_get();
  177. for (i = 0; i < SDRAM_SIZE / data_width; i++)
  178. {
  179. #if SDRAM_DATA_WIDTH == 8
  180. *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint8_t)(i % 100);
  181. #elif SDRAM_DATA_WIDTH == 16
  182. *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)(i % 1000);
  183. #endif
  184. }
  185. time_cast = rt_tick_get() - start_time;
  186. LOG_D("write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
  187. time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
  188. /* read data */
  189. LOG_D("start reading and verifying data, waiting....");
  190. for (i = 0; i < SDRAM_SIZE / data_width; i++)
  191. {
  192. #if SDRAM_DATA_WIDTH == 8
  193. data = *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width);
  194. if (data != i % 100)
  195. {
  196. LOG_E("sdram test failed!");
  197. break;
  198. }
  199. #elif SDRAM_DATA_WIDTH == 16
  200. data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
  201. if (data != (uint16_t)(i % 1000))
  202. {
  203. LOG_E("sdram test failed, i = %d!", i);
  204. break;
  205. }
  206. #endif
  207. }
  208. if (i >= SDRAM_SIZE / data_width)
  209. {
  210. LOG_D("sdram test success!");
  211. }
  212. return RT_EOK;
  213. }
  214. MSH_CMD_EXPORT(sdram_sample, sdram sample test)
  215. #endif /* FINSH_USING_MSH */
  216. #endif /* DRV_DEBUG */
  217. #endif /* BSP_USING_SDRAM */