sdram.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include <rtthread.h>
  2. #include <system_LPC177x_8x.h>
  3. #include "LPC177x_8x.h"
  4. #include "sdram.h"
  5. //LPC_EMC_TypeDef * const g_pEMC = ((LPC_EMC_TypeDef*) LPC_EMC_BASE);
  6. //LPC_IOCON_TypeDef * const LPC_IOCON = ((LPC_IOCON_TypeDef*) LPC_IOCON_BASE);
  7. #define SDRAM_BASE 0xA0000000 /* CS0 */
  8. #define EMC_NS2CLK(ns, nsPerClk) ((ns + nsPerClk - 1) / nsPerClk)
  9. static void delayMs(int a,int b)
  10. {
  11. volatile unsigned int i;
  12. for(i=0;i<10000;i++);
  13. }
  14. /*****************************************************************************
  15. ** Function name: delayMs
  16. **
  17. ** Descriptions: Start the timer delay in milo seconds
  18. ** until elapsed
  19. **
  20. ** parameters: timer number, Delay value in milo second
  21. **
  22. ** Returned value: None
  23. **
  24. *****************************************************************************/
  25. //void delayMs(uint8_t timer_num, uint32_t delayInMs)
  26. //{
  27. // if ( timer_num == 0 )
  28. // {
  29. // LPC_TIM0->TCR = 0x02; /* reset timer */
  30. // LPC_TIM0->PR = 0x00; /* set prescaler to zero */
  31. // LPC_TIM0->MR0 = delayInMs * (PeripheralClock / 1000 - 1);
  32. // LPC_TIM0->IR = 0xff; /* reset all interrrupts */
  33. // LPC_TIM0->MCR = 0x04; /* stop timer on match */
  34. // LPC_TIM0->TCR = 0x01; /* start timer */
  35. //
  36. // /* wait until delay time has elapsed */
  37. // while (LPC_TIM0->TCR & 0x01);
  38. // }
  39. // else if ( timer_num == 1 )
  40. // {
  41. // LPC_TIM1->TCR = 0x02; /* reset timer */
  42. // LPC_TIM1->PR = 0x00; /* set prescaler to zero */
  43. // LPC_TIM1->MR0 = delayInMs * (PeripheralClock / 1000 - 1);
  44. // LPC_TIM1->IR = 0xff; /* reset all interrrupts */
  45. // LPC_TIM1->MCR = 0x04; /* stop timer on match */
  46. // LPC_TIM1->TCR = 0x01; /* start timer */
  47. //
  48. // /* wait until delay time has elapsed */
  49. // while (LPC_TIM1->TCR & 0x01);
  50. // }
  51. // else if ( timer_num == 2 )
  52. // {
  53. // LPC_TIM2->TCR = 0x02; /* reset timer */
  54. // LPC_TIM2->PR = 0x00; /* set prescaler to zero */
  55. // LPC_TIM2->MR0 = delayInMs * (PeripheralClock / 1000 - 1);
  56. // LPC_TIM2->IR = 0xff; /* reset all interrrupts */
  57. // LPC_TIM2->MCR = 0x04; /* stop timer on match */
  58. // LPC_TIM2->TCR = 0x01; /* start timer */
  59. //
  60. // /* wait until delay time has elapsed */
  61. // while (LPC_TIM2->TCR & 0x01);
  62. // }
  63. // else if ( timer_num == 3 )
  64. // {
  65. // LPC_TIM3->TCR = 0x02; /* reset timer */
  66. // LPC_TIM3->PR = 0x00; /* set prescaler to zero */
  67. // LPC_TIM3->MR0 = delayInMs * (PeripheralClock / 1000 - 1);
  68. // LPC_TIM3->IR = 0xff; /* reset all interrrupts */
  69. // LPC_TIM3->MCR = 0x04; /* stop timer on match */
  70. // LPC_TIM3->TCR = 0x01; /* start timer */
  71. //
  72. // /* wait until delay time has elapsed */
  73. // while (LPC_TIM3->TCR & 0x01);
  74. // }
  75. // return;
  76. //}
  77. static void EMC_GPIO_Init (void)
  78. {
  79. LPC_IOCON->P3_0 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D0 @ P3.0 */
  80. LPC_IOCON->P3_1 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D1 @ P3.1 */
  81. LPC_IOCON->P3_2 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D2 @ P3.2 */
  82. LPC_IOCON->P3_3 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D3 @ P3.3 */
  83. LPC_IOCON->P3_4 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D4 @ P3.4 */
  84. LPC_IOCON->P3_5 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D5 @ P3.5 */
  85. LPC_IOCON->P3_6 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D6 @ P3.6 */
  86. LPC_IOCON->P3_7 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D7 @ P3.7 */
  87. LPC_IOCON->P3_8 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D8 @ P3.8 */
  88. LPC_IOCON->P3_9 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D9 @ P3.9 */
  89. LPC_IOCON->P3_10 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D10 @ P3.10 */
  90. LPC_IOCON->P3_11 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D11 @ P3.11 */
  91. LPC_IOCON->P3_12 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D12 @ P3.12 */
  92. LPC_IOCON->P3_13 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D13 @ P3.13 */
  93. LPC_IOCON->P3_14 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D14 @ P3.14 */
  94. LPC_IOCON->P3_15 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D15 @ P3.15 */
  95. LPC_IOCON->P3_16 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D16 @ P3.16 */
  96. LPC_IOCON->P3_17 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D17 @ P3.17 */
  97. LPC_IOCON->P3_18 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D18 @ P3.18 */
  98. LPC_IOCON->P3_19 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D19 @ P3.19 */
  99. LPC_IOCON->P3_20 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D20 @ P3.20 */
  100. LPC_IOCON->P3_21 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D21 @ P3.21 */
  101. LPC_IOCON->P3_22 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D22 @ P3.22 */
  102. LPC_IOCON->P3_23 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D23 @ P3.23 */
  103. LPC_IOCON->P3_24 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D24 @ P3.24 */
  104. LPC_IOCON->P3_25 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D25 @ P3.25 */
  105. LPC_IOCON->P3_26 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D26 @ P3.26 */
  106. LPC_IOCON->P3_27 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D27 @ P3.27 */
  107. LPC_IOCON->P3_28 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D28 @ P3.28 */
  108. LPC_IOCON->P3_29 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D29 @ P3.29 */
  109. LPC_IOCON->P3_30 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D30 @ P3.30 */
  110. LPC_IOCON->P3_31 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* D31 @ P3.31 */
  111. LPC_IOCON->P4_0 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A0 @ P4.0 */
  112. LPC_IOCON->P4_1 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A1 @ P4.1 */
  113. LPC_IOCON->P4_2 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A2 @ P4.2 */
  114. LPC_IOCON->P4_3 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A3 @ P4.3 */
  115. LPC_IOCON->P4_4 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A4 @ P4.4 */
  116. LPC_IOCON->P4_5 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A5 @ P4.5 */
  117. LPC_IOCON->P4_6 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A6 @ P4.6 */
  118. LPC_IOCON->P4_7 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A7 @ P4.7 */
  119. LPC_IOCON->P4_8 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A8 @ P4.8 */
  120. LPC_IOCON->P4_9 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A9 @ P4.9 */
  121. LPC_IOCON->P4_10 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A10 @ P4.10 */
  122. LPC_IOCON->P4_11 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A11 @ P4.11 */
  123. LPC_IOCON->P4_12 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A12 @ P4.12 */
  124. LPC_IOCON->P4_13 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A13 @ P4.13 */
  125. LPC_IOCON->P4_14 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A14 @ P4.14 */
  126. LPC_IOCON->P4_15 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A15 @ P4.15 */
  127. LPC_IOCON->P4_16 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A16 @ P4.16 */
  128. LPC_IOCON->P4_17 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A17 @ P4.17 */
  129. LPC_IOCON->P4_18 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A18 @ P4.18 */
  130. LPC_IOCON->P4_19 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A19 @ P4.19 */
  131. LPC_IOCON->P4_20 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A20 @ P4.20 */
  132. LPC_IOCON->P4_21 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A21 @ P4.21 */
  133. LPC_IOCON->P4_22 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A22 @ P4.22 */
  134. LPC_IOCON->P4_23 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* A23 @ P4.23 */
  135. LPC_IOCON->P4_25 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* WEN @ P4.25 */
  136. #if 1
  137. LPC_IOCON->P4_24 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* OEN @ P4.24 */
  138. LPC_IOCON->P4_26 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* BLSN[0] @ P4.26 */
  139. LPC_IOCON->P4_27 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* BLSN[1] @ P4.27 */
  140. LPC_IOCON->P4_28 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* BLSN[2] @ P4.28 */
  141. LPC_IOCON->P4_29 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* BLSN[3] @ P4.29 */
  142. LPC_IOCON->P4_30 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CSN[0] @ P4.30 */
  143. LPC_IOCON->P4_31 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CSN[1] @ P4.31 */
  144. LPC_IOCON->P2_14 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CSN[2] @ P2.14 */
  145. LPC_IOCON->P2_15 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CSN[3] @ P2.15 */
  146. #endif
  147. #if 1
  148. LPC_IOCON->P2_16 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CASN @ P2.16 */
  149. LPC_IOCON->P2_17 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* RASN @ P2.17 */
  150. LPC_IOCON->P2_18 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CLK[0] @ P2.18 */
  151. LPC_IOCON->P2_19 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CLK[1] @ P2.19 */
  152. LPC_IOCON->P2_20 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DYCSN[0] @ P2.20 */
  153. LPC_IOCON->P2_21 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DYCSN[1] @ P2.21 */
  154. LPC_IOCON->P2_22 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DYCSN[2] @ P2.22 */
  155. LPC_IOCON->P2_23 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DYCSN[3] @ P2.23 */
  156. LPC_IOCON->P2_24 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CKE[0] @ P2.24 */
  157. // LPC_IOCON->P2_25 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CKE[1] @ P2.25 */
  158. LPC_IOCON->P2_26 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CKE[2] @ P2.26 */
  159. LPC_IOCON->P2_27 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* CKE[3] @ P2.27 */
  160. LPC_IOCON->P2_28 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DQM[0] @ P2.28 */
  161. LPC_IOCON->P2_29 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DQM[1] @ P2.29 */
  162. LPC_IOCON->P2_30 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DQM[2] @ P2.30 */
  163. LPC_IOCON->P2_31 = (1<<0 | 0<<3 | 0<<5 | 1<<9); /* DQM[3] @ P2.31 */
  164. #endif
  165. }
  166. void SDRAM_Init (void)
  167. {
  168. uint32_t i, dwtemp = dwtemp;
  169. uint16_t wtemp = wtemp;
  170. uint32_t mhz, nsPerClk;
  171. /* Enable External Memory Controller power/clock */
  172. LPC_SC->PCONP |= 0x00000800;
  173. LPC_SC->EMCDLYCTL = 0x00001010;
  174. LPC_EMC->Control = 0x00000001;
  175. LPC_EMC->Config = 0x00000000;
  176. EMC_GPIO_Init();
  177. mhz = SystemCoreClock / 1000000;
  178. if (LPC_SC->EMCCLKSEL)
  179. mhz >>= 1;
  180. nsPerClk = 1000 / mhz;
  181. LPC_EMC->DynamicRP = EMC_NS2CLK(20, nsPerClk); /* 20ns, */
  182. LPC_EMC->DynamicRAS = /*EMC_NS2CLK(42, nsPerClk);*/ 15; /* 42ns to 100K ns, */
  183. LPC_EMC->DynamicSREX = 1 - 1; /* tSRE, 1clk, */
  184. LPC_EMC->DynamicAPR = 2 - 1; /* Not found!!! Estimated as 2clk, */
  185. LPC_EMC->DynamicDAL = EMC_NS2CLK(20, nsPerClk) + 2; /* tDAL = tRP + tDPL = 20ns + 2clk */
  186. LPC_EMC->DynamicWR = 2 - 1; /* 2CLK, */
  187. LPC_EMC->DynamicRC = EMC_NS2CLK(63, nsPerClk); /* H57V2562GTR-75C tRC=63ns(min)*/
  188. LPC_EMC->DynamicRFC = EMC_NS2CLK(63, nsPerClk); /* H57V2562GTR-75C tRFC=tRC */
  189. LPC_EMC->DynamicXSR = 0x0000000F; /* exit self-refresh to active, ²»ÖªµÀ£¬ÉèΪ×î¾Ã */
  190. LPC_EMC->DynamicRRD = EMC_NS2CLK(63, nsPerClk); /* 3clk, tRRD=15ns(min) */
  191. LPC_EMC->DynamicMRD = 2 - 1; /* 2clk, tMRD=2clk(min) */
  192. // LPC_EMC->DynamicRP = 0x00000002; /* 3clk=24ns, */
  193. // LPC_EMC->DynamicRAS = 0x00000005; /* 6clk=48ns, */
  194. // LPC_EMC->DynamicSREX = 0x00000001; /* 2clk, */
  195. // LPC_EMC->DynamicAPR = 0x00000001; /* 2clk, */
  196. // LPC_EMC->DynamicDAL = 0x00000005; /* 6clk, */
  197. // LPC_EMC->DynamicWR = 0x00000001; /* 2CLK, */
  198. // LPC_EMC->DynamicRC = 0x00000008; /* 9clk, H57V2562GTR-75C tRC=63ns(min)*/
  199. // LPC_EMC->DynamicRFC = 0x00000008; /* 9clk, H57V2562GTR-75C tRFC=63ns(min) */
  200. // LPC_EMC->DynamicXSR = 0x00000007; /* 8clk, */
  201. // LPC_EMC->DynamicRRD = 0x00000002; /* 3clk, tRRD=15ns(min) */
  202. // LPC_EMC->DynamicMRD = 0x00000001; /* 2clk, tMRD=2clk(min) */
  203. LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
  204. /* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
  205. LPC_EMC->DynamicRasCas0 = 0x00000303; /* 3 RAS, 3 CAS latency */
  206. /* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9 */
  207. #ifdef SDRAM_CONFIG_16BIT
  208. LPC_EMC->DynamicConfig0 = 0x680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
  209. #elif defined SDRAM_CONFIG_32BIT
  210. LPC_EMC->DynamicConfig0 = 0x4680; /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */
  211. #endif
  212. delayMs(0, 100);
  213. LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */
  214. delayMs(0, 200); /* wait 200ms */
  215. LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */
  216. LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */
  217. for(i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */
  218. /* 64ms/8192=7.8125us, nx16x8.33ns<7.8125us, n<58.6*/
  219. wtemp = 64000000 / (1 << 13);
  220. wtemp -= 16;
  221. wtemp >>= 4;
  222. wtemp = wtemp * mhz / 1000;
  223. LPC_EMC->DynamicRefresh = wtemp;
  224. LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */
  225. #ifdef SDRAM_CONFIG_16BIT
  226. wtemp = *((volatile uint16_t *)(SDRAM_BASE | (0x33<<12))); /* 8 burst, 3 CAS latency */
  227. #elif defined SDRAM_CONFIG_32BIT
  228. dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x32<<13))); /* 4 burst, 3 CAS latency */
  229. #endif
  230. LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */
  231. LPC_EMC->DynamicConfig0 |= 0x80000; /* enable buffer */
  232. delayMs(0, 1);
  233. }