drv_sdram.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * File : drv_sdram.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2013-05-19 Bernard The first version for LPC40xx
  13. */
  14. #include "drv_sdram.h"
  15. #include <lpc_emc.h>
  16. #include <lpc_timer.h>
  17. #define SDRAM_BASE_ADDR 0xA0000000
  18. #define SDRAM_SIZE 0x2000000
  19. /*******************************************************************************************
  20. * @函数名:sdram_gpio_config()
  21. * @参数 :void
  22. * @返回值:void
  23. * @描述 :SDRAM管脚配置函数,内部调用
  24. *********************************************************************************************/
  25. static void sdram_gpio_config(void)
  26. {
  27. LPC_IOCON->P3_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D0 @ P3.0 */
  28. LPC_IOCON->P3_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D1 @ P3.1 */
  29. LPC_IOCON->P3_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D2 @ P3.2 */
  30. LPC_IOCON->P3_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D3 @ P3.3 */
  31. LPC_IOCON->P3_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D4 @ P3.4 */
  32. LPC_IOCON->P3_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D5 @ P3.5 */
  33. LPC_IOCON->P3_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D6 @ P3.6 */
  34. LPC_IOCON->P3_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D7 @ P3.7 */
  35. LPC_IOCON->P3_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D8 @ P3.8 */
  36. LPC_IOCON->P3_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D9 @ P3.9 */
  37. LPC_IOCON->P3_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D10 @ P3.10 */
  38. LPC_IOCON->P3_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D11 @ P3.11 */
  39. LPC_IOCON->P3_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D12 @ P3.12 */
  40. LPC_IOCON->P3_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D13 @ P3.13 */
  41. LPC_IOCON->P3_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D14 @ P3.14 */
  42. LPC_IOCON->P3_15 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* D15 @ P3.15 */
  43. LPC_IOCON->P4_0 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A0 @ P4.0 */
  44. LPC_IOCON->P4_1 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A1 @ P4.1 */
  45. LPC_IOCON->P4_2 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A2 @ P4.2 */
  46. LPC_IOCON->P4_3 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A3 @ P4.3 */
  47. LPC_IOCON->P4_4 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A4 @ P4.4 */
  48. LPC_IOCON->P4_5 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A5 @ P4.5 */
  49. LPC_IOCON->P4_6 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A6 @ P4.6 */
  50. LPC_IOCON->P4_7 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A7 @ P4.7 */
  51. LPC_IOCON->P4_8 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A8 @ P4.8 */
  52. LPC_IOCON->P4_9 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A9 @ P4.9 */
  53. LPC_IOCON->P4_10 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A10 @ P4.10 */
  54. LPC_IOCON->P4_11 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A11 @ P4.11 */
  55. LPC_IOCON->P4_12 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A12 @ P4.12 */
  56. LPC_IOCON->P4_13 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A13 @ P4.13 */
  57. LPC_IOCON->P4_14 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* A14 @ P4.14 */
  58. LPC_IOCON->P4_25 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* WEN @ P4.25 */
  59. LPC_IOCON->P2_16 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CASN @ P2.16 */
  60. LPC_IOCON->P2_17 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* RASN @ P2.17 */
  61. LPC_IOCON->P2_18 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[0] @ P2.18 */
  62. LPC_IOCON->P2_19 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CLK[1] @ P2.19 */
  63. LPC_IOCON->P2_20 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DYCSN[0] @ P2.20 */
  64. LPC_IOCON->P2_24 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* CKE[0] @ P2.24 */
  65. LPC_IOCON->P2_28 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[0] @ P2.28 */
  66. LPC_IOCON->P2_29 = (1 << 0 | 0 << 3 | 0 << 5 | 1 << 9); /* DQM[1] @ P2.29 */
  67. }
  68. void lpc_sdram_hw_init(void)
  69. {
  70. volatile uint32_t i;
  71. volatile uint32_t dwtemp;
  72. uint16_t wtemp = wtemp;
  73. TIM_TIMERCFG_Type TIM_ConfigStruct;
  74. TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
  75. TIM_ConfigStruct.PrescaleValue = 1;
  76. // Set configuration for Tim_config and Tim_MatchConfig
  77. TIM_Init(LPC_TIM0, TIM_TIMER_MODE, &TIM_ConfigStruct);
  78. LPC_SC->PCONP |= 0x00000800;
  79. LPC_SC->EMCDLYCTL = 0x00001010;
  80. LPC_EMC->Control = 0x00000001;
  81. LPC_EMC->Config = 0x00000000;
  82. sdram_gpio_config();
  83. //LPC_SC->EMCCLKSEL = 1; //跑主频的一般频率,60Mhz
  84. LPC_EMC->DynamicRP = EMC_NS2CLK(20); /* 20ns, */
  85. LPC_EMC->DynamicRAS = /*EMC_NS2CLK(42, nsPerClk);*/ 15; /* 42ns to 100K ns, */
  86. LPC_EMC->DynamicSREX = 1 - 1; /* tSRE, 1clk, */
  87. LPC_EMC->DynamicAPR = 2 - 1; /* Not found!!! Estimated as 2clk, */
  88. LPC_EMC->DynamicDAL = EMC_NS2CLK(20) + 2; /* tDAL = tRP + tDPL = 20ns + 2clk */
  89. LPC_EMC->DynamicWR = 2 - 1; /* 2CLK, */
  90. LPC_EMC->DynamicRC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRC=63ns(min)*/
  91. LPC_EMC->DynamicRFC = EMC_NS2CLK(63); /* H57V2562GTR-75C tRFC=tRC */
  92. LPC_EMC->DynamicXSR = 0x0000000F; /* exit self-refresh to active, 不知道,设为最久 */
  93. LPC_EMC->DynamicRRD = EMC_NS2CLK(63); /* 3clk, tRRD=15ns(min) */
  94. LPC_EMC->DynamicMRD = 2 - 1; /* 2clk, tMRD=2clk(min) */
  95. LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
  96. /* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
  97. LPC_EMC->DynamicRasCas0 = 0x303;
  98. /* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9 */
  99. #ifdef SDRAM_CONFIG_16BIT
  100. LPC_EMC->DynamicConfig0 = 0x680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
  101. #elif defined SDRAM_CONFIG_32BIT
  102. LPC_EMC->DynamicConfig0 = 0x4680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
  103. #endif
  104. TIM_Waitms(100);
  105. LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */
  106. TIM_Waitms(200); /* wait 200ms */
  107. LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */
  108. LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */
  109. for (i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */
  110. LPC_EMC->DynamicRefresh = EMC_SDRAM_REFRESH(64);
  111. LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */
  112. #ifdef SDRAM_CONFIG_16BIT
  113. wtemp = *((volatile uint16_t *)(SDRAM_BASE | (0x33 << 12))); /* 8 burst, 3 CAS latency */
  114. #elif defined SDRAM_CONFIG_32BIT
  115. dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32 << 13))); /* 4 burst, 3 CAS latency */
  116. #endif
  117. LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */
  118. LPC_EMC->DynamicConfig0 |= 0x80000; /* enable buffer */
  119. TIM_Waitms(1);
  120. TIM_DeInit(LPC_TIM0);
  121. }