The wait in mci_WaitForEvent will delay all card transactions.
Fork of EALib by
sdram.cpp
00001 /***************************************************************************** 00002 * 00003 * Copyright(C) 2011, Embedded Artists AB 00004 * All rights reserved. 00005 * 00006 ****************************************************************************** 00007 * Software that is described herein is for illustrative purposes only 00008 * which provides customers with programming information regarding the 00009 * products. This software is supplied "AS IS" without any warranties. 00010 * Embedded Artists AB assumes no responsibility or liability for the 00011 * use of the software, conveys no license or title under any patent, 00012 * copyright, or mask work right to the product. Embedded Artists AB 00013 * reserves the right to make changes in the software without 00014 * notification. Embedded Artists AB also make no representation or 00015 * warranty that such application will be suitable for the specified 00016 * use without further testing or modification. 00017 *****************************************************************************/ 00018 00019 00020 00021 /****************************************************************************** 00022 * Includes 00023 *****************************************************************************/ 00024 00025 #include "mbed.h" 00026 #include "sdram.h" 00027 00028 00029 /****************************************************************************** 00030 * Defines and typedefs 00031 *****************************************************************************/ 00032 00033 00034 /****************************************************************************** 00035 * External global variables 00036 *****************************************************************************/ 00037 00038 /****************************************************************************** 00039 * Local variables 00040 *****************************************************************************/ 00041 00042 static volatile uint32_t ringosccount[2] = {0,0}; 00043 00044 static bool okToUseSdramForHeap = true; 00045 static bool initialized = false; 00046 00047 /****************************************************************************** 00048 * Overridden Global Functions 00049 *****************************************************************************/ 00050 00051 #if defined(TOOLCHAIN_ARM) /* KEIL uVision and mbed online compiler */ 00052 //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0349c/Cihehbce.html 00053 00054 extern "C" unsigned __rt_heap_extend(unsigned size, void **block) { 00055 static uint32_t lastReturnedBlock = 0; 00056 00057 if (okToUseSdramForHeap && !initialized) { 00058 sdram_init(); 00059 } 00060 00061 // Make sure that SDRAM is only returned once (as all of it is returned 00062 // the first time) and only if the user has chosen to do it (via the 00063 // okToUseSdramForHeap variable. 00064 if (okToUseSdramForHeap && lastReturnedBlock==0) { 00065 *block = (void*)SDRAM_BASE; 00066 lastReturnedBlock = SDRAM_BASE; 00067 return SDRAM_SIZE; 00068 } 00069 return 0; 00070 } 00071 #elif defined(TOOLCHAIN_GCC_CR) /* CodeRed's RedSuite or LPCXpresso IDE */ 00072 00073 // NOTE: This way of overriding the implementation of malloc in NEWLIB 00074 // will prevent the internal RAM from being used by malloc as 00075 // it only exposes the SDRAM. 00076 00077 // Dynamic memory allocation related syscall. 00078 extern "C" caddr_t _sbrk(int incr) { 00079 static unsigned char* heap = (unsigned char*)SDRAM_BASE; 00080 unsigned char* prev_heap = heap; 00081 unsigned char* new_heap = heap + incr; 00082 00083 if (okToUseSdramForHeap && !initialized) { 00084 sdram_init(); 00085 } 00086 if (!okToUseSdramForHeap) { 00087 //errno = ENOMEM; 00088 return (caddr_t)-1; 00089 } 00090 if (new_heap >= (unsigned char*)(SDRAM_BASE + SDRAM_SIZE)) { 00091 //errno = ENOMEM; 00092 return (caddr_t)-1; 00093 } 00094 00095 heap = new_heap; 00096 return (caddr_t) prev_heap; 00097 } 00098 #endif 00099 00100 /****************************************************************************** 00101 * Local Functions 00102 *****************************************************************************/ 00103 00104 static void pinConfig(void) 00105 { 00106 LPC_IOCON->P3_0 |= 1; /* D0 @ P3.0 */ 00107 LPC_IOCON->P3_1 |= 1; /* D1 @ P3.1 */ 00108 LPC_IOCON->P3_2 |= 1; /* D2 @ P3.2 */ 00109 LPC_IOCON->P3_3 |= 1; /* D3 @ P3.3 */ 00110 00111 LPC_IOCON->P3_4 |= 1; /* D4 @ P3.4 */ 00112 LPC_IOCON->P3_5 |= 1; /* D5 @ P3.5 */ 00113 LPC_IOCON->P3_6 |= 1; /* D6 @ P3.6 */ 00114 LPC_IOCON->P3_7 |= 1; /* D7 @ P3.7 */ 00115 00116 LPC_IOCON->P3_8 |= 1; /* D8 @ P3.8 */ 00117 LPC_IOCON->P3_9 |= 1; /* D9 @ P3.9 */ 00118 LPC_IOCON->P3_10 |= 1; /* D10 @ P3.10 */ 00119 LPC_IOCON->P3_11 |= 1; /* D11 @ P3.11 */ 00120 00121 LPC_IOCON->P3_12 |= 1; /* D12 @ P3.12 */ 00122 LPC_IOCON->P3_13 |= 1; /* D13 @ P3.13 */ 00123 LPC_IOCON->P3_14 |= 1; /* D14 @ P3.14 */ 00124 LPC_IOCON->P3_15 |= 1; /* D15 @ P3.15 */ 00125 00126 LPC_IOCON->P3_16 |= 1; /* D16 @ P3.16 */ 00127 LPC_IOCON->P3_17 |= 1; /* D17 @ P3.17 */ 00128 LPC_IOCON->P3_18 |= 1; /* D18 @ P3.18 */ 00129 LPC_IOCON->P3_19 |= 1; /* D19 @ P3.19 */ 00130 00131 LPC_IOCON->P3_20 |= 1; /* D20 @ P3.20 */ 00132 LPC_IOCON->P3_21 |= 1; /* D21 @ P3.21 */ 00133 LPC_IOCON->P3_22 |= 1; /* D22 @ P3.22 */ 00134 LPC_IOCON->P3_23 |= 1; /* D23 @ P3.23 */ 00135 00136 LPC_IOCON->P3_24 |= 1; /* D24 @ P3.24 */ 00137 LPC_IOCON->P3_25 |= 1; /* D25 @ P3.25 */ 00138 LPC_IOCON->P3_26 |= 1; /* D26 @ P3.26 */ 00139 LPC_IOCON->P3_27 |= 1; /* D27 @ P3.27 */ 00140 00141 LPC_IOCON->P3_28 |= 1; /* D28 @ P3.28 */ 00142 LPC_IOCON->P3_29 |= 1; /* D29 @ P3.29 */ 00143 LPC_IOCON->P3_30 |= 1; /* D30 @ P3.30 */ 00144 LPC_IOCON->P3_31 |= 1; /* D31 @ P3.31 */ 00145 00146 LPC_IOCON->P4_0 |= 1; /* A0 @ P4.0 */ 00147 LPC_IOCON->P4_1 |= 1; /* A1 @ P4.1 */ 00148 LPC_IOCON->P4_2 |= 1; /* A2 @ P4.2 */ 00149 LPC_IOCON->P4_3 |= 1; /* A3 @ P4.3 */ 00150 00151 LPC_IOCON->P4_4 |= 1; /* A4 @ P4.4 */ 00152 LPC_IOCON->P4_5 |= 1; /* A5 @ P4.5 */ 00153 LPC_IOCON->P4_6 |= 1; /* A6 @ P4.6 */ 00154 LPC_IOCON->P4_7 |= 1; /* A7 @ P4.7 */ 00155 00156 LPC_IOCON->P4_8 |= 1; /* A8 @ P4.8 */ 00157 LPC_IOCON->P4_9 |= 1; /* A9 @ P4.9 */ 00158 LPC_IOCON->P4_10 |= 1; /* A10 @ P4.10 */ 00159 LPC_IOCON->P4_11 |= 1; /* A11 @ P4.11 */ 00160 00161 LPC_IOCON->P4_12 |= 1; /* A12 @ P4.12 */ 00162 LPC_IOCON->P4_13 |= 1; /* A13 @ P4.13 */ 00163 LPC_IOCON->P4_14 |= 1; /* A14 @ P4.14 */ 00164 #if 0 // not used for SDRAM 00165 LPC_IOCON->P4_15 |= 1; /* A15 @ P4.15 */ 00166 00167 LPC_IOCON->P4_16 |= 1; /* A16 @ P4.16 */ 00168 LPC_IOCON->P4_17 |= 1; /* A17 @ P4.17 */ 00169 LPC_IOCON->P4_18 |= 1; /* A18 @ P4.18 */ 00170 LPC_IOCON->P4_19 |= 1; /* A19 @ P4.19 */ 00171 00172 LPC_IOCON->P4_20 |= 1; /* A20 @ P4.20 */ 00173 LPC_IOCON->P4_21 |= 1; /* A21 @ P4.21 */ 00174 LPC_IOCON->P4_22 |= 1; /* A22 @ P4.22 */ 00175 LPC_IOCON->P4_23 |= 1; /* A23 @ P4.23 */ 00176 #endif 00177 00178 LPC_IOCON->P4_24 |= 1; /* OEN @ P4.24 */ 00179 LPC_IOCON->P4_25 |= 1; /* WEN @ P4.25 */ 00180 #if 0 // not used for SDRAM 00181 LPC_IOCON->P4_26 |= 1; /* BLSN[0] @ P4.26 */ 00182 LPC_IOCON->P4_27 |= 1; /* BLSN[1] @ P4.27 */ 00183 00184 00185 LPC_IOCON->P4_28 |= 1; /* BLSN[2] @ P4.28 */ 00186 LPC_IOCON->P4_29 |= 1; /* BLSN[3] @ P4.29 */ 00187 LPC_IOCON->P4_30 |= 1; /* CSN[0] @ P4.30 */ 00188 LPC_IOCON->P4_31 |= 1; /* CSN[1] @ P4.31 */ 00189 #endif 00190 00191 LPC_IOCON->P2_14 |= 1; /* CSN[2] @ P2.14 */ 00192 LPC_IOCON->P2_15 |= 1; /* CSN[3] @ P2.15 */ 00193 00194 LPC_IOCON->P2_16 |= 1; /* CASN @ P2.16 */ 00195 LPC_IOCON->P2_17 |= 1; /* RASN @ P2.17 */ 00196 LPC_IOCON->P2_18 |= 1; /* CLK[0] @ P2.18 */ 00197 #if 0 // not used for SDRAM 00198 LPC_IOCON->P2_19 |= 1; /* CLK[1] @ P2.19 */ 00199 #endif 00200 00201 LPC_IOCON->P2_20 |= 1; /* DYCSN[0] @ P2.20 */ 00202 #if 0 // not used for SDRAM 00203 LPC_IOCON->P2_21 |= 1; /* DYCSN[1] @ P2.21 */ 00204 LPC_IOCON->P2_22 |= 1; /* DYCSN[2] @ P2.22 */ 00205 LPC_IOCON->P2_23 |= 1; /* DYCSN[3] @ P2.23 */ 00206 #endif 00207 00208 LPC_IOCON->P2_24 |= 1; /* CKE[0] @ P2.24 */ 00209 #if 0 // not used for SDRAM 00210 LPC_IOCON->P2_25 |= 1; /* CKE[1] @ P2.25 */ 00211 LPC_IOCON->P2_26 |= 1; /* CKE[2] @ P2.26 */ 00212 LPC_IOCON->P2_27 |= 1; /* CKE[3] @ P2.27 */ 00213 #endif 00214 00215 LPC_IOCON->P2_28 |= 1; /* DQM[0] @ P2.28 */ 00216 LPC_IOCON->P2_29 |= 1; /* DQM[1] @ P2.29 */ 00217 LPC_IOCON->P2_30 |= 1; /* DQM[2] @ P2.30 */ 00218 LPC_IOCON->P2_31 |= 1; /* DQM[3] @ P2.31 */ 00219 } 00220 00221 00222 static uint32_t sdram_test( void ) 00223 { 00224 volatile uint32_t *wr_ptr; 00225 volatile uint16_t *short_wr_ptr; 00226 uint32_t data; 00227 uint32_t i, j; 00228 00229 wr_ptr = (uint32_t *)SDRAM_BASE; 00230 short_wr_ptr = (uint16_t *)wr_ptr; 00231 /* Clear content before 16 bit access test */ 00232 // for (i = 0; i < SDRAM_SIZE/4; i++) 00233 // { 00234 // *wr_ptr++ = 0; 00235 // } 00236 00237 /* 16 bit write */ 00238 for (i = 0; i < SDRAM_SIZE/0x40000; i++) 00239 { 00240 for (j = 0; j < 0x100; j++) 00241 { 00242 *short_wr_ptr++ = (i + j); 00243 *short_wr_ptr++ = (i + j) + 1; 00244 } 00245 } 00246 00247 /* Verifying */ 00248 wr_ptr = (uint32_t *)SDRAM_BASE; 00249 for (i = 0; i < SDRAM_SIZE/0x40000; i++) 00250 { 00251 for (j = 0; j < 0x100; j++) 00252 { 00253 data = *wr_ptr; 00254 if (data != (((((i + j) + 1) & 0xFFFF) << 16) | ((i + j) & 0xFFFF))) 00255 { 00256 return 0x0; 00257 } 00258 wr_ptr++; 00259 } 00260 } 00261 return 0x1; 00262 } 00263 00264 static uint32_t find_cmddly(void) 00265 { 00266 uint32_t cmddly, cmddlystart, cmddlyend, dwtemp; 00267 uint32_t ppass = 0x0, pass = 0x0; 00268 00269 cmddly = 0x0; 00270 cmddlystart = cmddlyend = 0xFF; 00271 00272 while (cmddly < 32) 00273 { 00274 dwtemp = LPC_SC->EMCDLYCTL & ~0x1F; 00275 LPC_SC->EMCDLYCTL = dwtemp | cmddly; 00276 00277 if (sdram_test() == 0x1) 00278 { 00279 /* Test passed */ 00280 if (cmddlystart == 0xFF) 00281 { 00282 cmddlystart = cmddly; 00283 } 00284 ppass = 0x1; 00285 } 00286 else 00287 { 00288 /* Test failed */ 00289 if (ppass == 1) 00290 { 00291 cmddlyend = cmddly; 00292 pass = 0x1; 00293 ppass = 0x0; 00294 } 00295 } 00296 00297 /* Try next value */ 00298 cmddly++; 00299 } 00300 00301 /* If the test passed, the we can use the average of the min and max values to get an optimal DQSIN delay */ 00302 if (pass == 0x1) 00303 { 00304 cmddly = (cmddlystart + cmddlyend) / 2; 00305 } 00306 else if (ppass == 0x1) 00307 { 00308 cmddly = (cmddlystart + 0x1F) / 2; 00309 } 00310 else 00311 { 00312 /* A working value couldn't be found, just pick something safe so the system doesn't become unstable */ 00313 cmddly = 0x10; 00314 } 00315 00316 dwtemp = LPC_SC->EMCDLYCTL & ~0x1F; 00317 LPC_SC->EMCDLYCTL = dwtemp | cmddly; 00318 00319 return (pass | ppass); 00320 } 00321 00322 static uint32_t find_fbclkdly(void) 00323 { 00324 uint32_t fbclkdly, fbclkdlystart, fbclkdlyend, dwtemp; 00325 uint32_t ppass = 0x0, pass = 0x0; 00326 00327 fbclkdly = 0x0; 00328 fbclkdlystart = fbclkdlyend = 0xFF; 00329 00330 while (fbclkdly < 32) 00331 { 00332 dwtemp = LPC_SC->EMCDLYCTL & ~0x1F00; 00333 LPC_SC->EMCDLYCTL = dwtemp | (fbclkdly << 8); 00334 00335 if (sdram_test() == 0x1) 00336 { 00337 /* Test passed */ 00338 if (fbclkdlystart == 0xFF) 00339 { 00340 fbclkdlystart = fbclkdly; 00341 } 00342 ppass = 0x1; 00343 } 00344 else 00345 { 00346 /* Test failed */ 00347 if (ppass == 1) 00348 { 00349 fbclkdlyend = fbclkdly; 00350 pass = 0x1; 00351 ppass = 0x0; 00352 } 00353 } 00354 00355 /* Try next value */ 00356 fbclkdly++; 00357 } 00358 00359 /* If the test passed, the we can use the average of the min and max values to get an optimal DQSIN delay */ 00360 if (pass == 0x1) 00361 { 00362 fbclkdly = (fbclkdlystart + fbclkdlyend) / 2; 00363 } 00364 else if (ppass == 0x1) 00365 { 00366 fbclkdly = (fbclkdlystart + 0x1F) / 2; 00367 } 00368 else 00369 { 00370 /* A working value couldn't be found, just pick something safe so the system doesn't become unstable */ 00371 fbclkdly = 0x10; 00372 } 00373 00374 dwtemp = LPC_SC->EMCDLYCTL & ~0x1F00; 00375 LPC_SC->EMCDLYCTL = dwtemp | (fbclkdly << 8); 00376 00377 return (pass | ppass); 00378 } 00379 00380 static uint32_t calibration( void ) 00381 { 00382 uint32_t dwtemp, i; 00383 uint32_t cnt = 0; 00384 00385 for (i = 0; i < 10; i++) 00386 { 00387 dwtemp = LPC_SC->EMCCAL & ~0x4000; 00388 LPC_SC->EMCCAL = dwtemp | 0x4000; 00389 00390 dwtemp = LPC_SC->EMCCAL; 00391 while ((dwtemp & 0x8000) == 0x0000) 00392 { 00393 dwtemp = LPC_SC->EMCCAL; 00394 } 00395 cnt += (dwtemp & 0xFF); 00396 } 00397 return (cnt / 10); 00398 } 00399 00400 /****************************************************************************** 00401 * Public Functions 00402 *****************************************************************************/ 00403 00404 00405 void adjust_timing( void ) 00406 { 00407 uint32_t dwtemp, cmddly, fbclkdly; 00408 00409 /* Current value */ 00410 ringosccount[1] = calibration(); 00411 00412 dwtemp = LPC_SC->EMCDLYCTL; 00413 cmddly = ((dwtemp & 0x1F) * ringosccount[0] / ringosccount[1]) & 0x1F; 00414 fbclkdly = ((dwtemp & 0x1F00) * ringosccount[0] / ringosccount[1]) & 0x1F00; 00415 LPC_SC->EMCDLYCTL = (dwtemp & ~0x1F1F) | fbclkdly | cmddly; 00416 } 00417 00418 /****************************************************************************** 00419 * 00420 * Description: 00421 * Initialize the SDRAM 00422 * 00423 *****************************************************************************/ 00424 uint32_t sdram_init (void) 00425 { 00426 uint32_t i; 00427 uint32_t dwtemp = 0; 00428 //uint16_t wtemp = 0; 00429 00430 if (initialized) { 00431 return 0; 00432 } 00433 00434 LPC_SC->PCONP |= 0x00000800; 00435 LPC_SC->EMCDLYCTL = 0x00001010; 00436 LPC_EMC->Control = 0x00000001; 00437 LPC_EMC->Config = 0x00000000; 00438 00439 pinConfig(); //Full 32-bit Data bus, 24-bit Address 00440 00441 /* Configure memory layout, but MUST DISABLE BUFFERs during configuration */ 00442 /* 256MB, 8Mx32, 4 banks, row=12, column=9 */ 00443 LPC_EMC->DynamicConfig0 = 0x00004480; 00444 00445 /*Configure timing for ISSI IS4x32800D SDRAM*/ 00446 00447 #if (SDRAM_SPEED==SDRAM_SPEED_48) 00448 //Timing for 48MHz Bus 00449 LPC_EMC->DynamicRasCas0 = 0x00000201; /* 1 RAS, 2 CAS latency */ 00450 LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ 00451 LPC_EMC->DynamicRP = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00452 LPC_EMC->DynamicRAS = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ 00453 LPC_EMC->DynamicSREX = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00454 LPC_EMC->DynamicAPR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00455 LPC_EMC->DynamicDAL = 0x00000002; /* ( n ) -> 2 clock cycles */ 00456 LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00457 LPC_EMC->DynamicRC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00458 LPC_EMC->DynamicRFC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00459 LPC_EMC->DynamicXSR = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00460 LPC_EMC->DynamicRRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00461 LPC_EMC->DynamicMRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00462 #elif (SDRAM_SPEED==SDRAM_SPEED_50) 00463 //Timing for 50MHz Bus (with 100MHz M3 Core) 00464 LPC_EMC->DynamicRasCas0 = 0x00000201; /* 1 RAS, 2 CAS latency */ 00465 LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ 00466 LPC_EMC->DynamicRP = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00467 LPC_EMC->DynamicRAS = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ 00468 LPC_EMC->DynamicSREX = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00469 LPC_EMC->DynamicAPR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00470 LPC_EMC->DynamicDAL = 0x00000002; /* ( n ) -> 2 clock cycles */ 00471 LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00472 LPC_EMC->DynamicRC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00473 LPC_EMC->DynamicRFC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00474 LPC_EMC->DynamicXSR = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00475 LPC_EMC->DynamicRRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00476 LPC_EMC->DynamicMRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ 00477 #elif (SDRAM_SPEED==SDRAM_SPEED_60) 00478 //Timing for 60 MHz Bus (same as 72MHz) 00479 LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ 00480 LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ 00481 LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00482 LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00483 LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00484 LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ 00485 LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ 00486 LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00487 LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00488 LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00489 LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00490 LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00491 LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00492 #elif (SDRAM_SPEED==SDRAM_SPEED_72) 00493 //Timing for 72 MHz Bus 00494 LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ 00495 LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ 00496 LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00497 LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00498 LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00499 LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ 00500 LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ 00501 LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00502 LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00503 LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00504 LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00505 LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00506 LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00507 #elif (SDRAM_SPEED==SDRAM_SPEED_80) 00508 //Timing for 80 MHz Bus (same as 72MHz) 00509 LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ 00510 LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ 00511 LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00512 LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ 00513 LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00514 LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ 00515 LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ 00516 LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00517 LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00518 LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ 00519 LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ 00520 LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00521 LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ 00522 #else 00523 #error UNSUPPORTED SDRAM FREQ 00524 #endif 00525 00526 LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */ 00527 wait(0.2); /* wait 200ms */ 00528 LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */ 00529 LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */ 00530 for(i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */ 00531 00532 00533 #if (SDRAM_SPEED==SDRAM_SPEED_48) 00534 //Timing for 48MHz Bus 00535 LPC_EMC->DynamicRefresh = 0x0000002E; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */ 00536 #elif (SDRAM_SPEED==SDRAM_SPEED_50) 00537 //Timing for 50MHz Bus 00538 LPC_EMC->DynamicRefresh = 0x0000003A; /* ( n * 16 ) -> 768 clock cycles -> 15.360uS at 50MHz <= 15.625uS ( 64ms / 4096 row ) */ 00539 #elif (SDRAM_SPEED==SDRAM_SPEED_60) 00540 //Timing for 60MHz Bus 00541 LPC_EMC->DynamicRefresh = 0x0000003A; /* ( n * 16 ) -> 928 clock cycles -> 15.466uS at 60MHz <= 15.625uS ( 64ms / 4096 row ) */ 00542 #elif (SDRAM_SPEED==SDRAM_SPEED_72) 00543 //Timing for 72MHz Bus 00544 LPC_EMC->DynamicRefresh = 0x00000046; /* ( n * 16 ) -> 1120 clock cycles -> 15.556uS at 72MHz <= 15.625uS ( 64ms / 4096 row ) */ 00545 #elif (SDRAM_SPEED==SDRAM_SPEED_80) 00546 //Timing for 80MHz Bus 00547 LPC_EMC->DynamicRefresh = 0x0000004E; /* ( n * 16 ) -> 1248 clock cycles -> 15.600uS at 80MHz <= 15.625uS ( 64ms / 4096 row ) */ 00548 #else 00549 #error UNSUPPORTED SDRAM FREQ 00550 #endif 00551 00552 LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */ 00553 //Timing for 48/60/72MHZ Bus 00554 dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x22<<(2+2+9)))); /* 4 burst, 2 CAS latency */ 00555 dwtemp = dwtemp; 00556 LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */ 00557 //[re]enable buffers 00558 LPC_EMC->DynamicConfig0 = 0x00084480; /* 256MB, 8Mx32, 4 banks, row=12, column=9 */ 00559 00560 /* Nominal value */ 00561 ringosccount[0] = calibration(); 00562 00563 if (find_cmddly() == 0x0) 00564 { 00565 //while (1); /* fatal error */ 00566 return 1;//FALSE; 00567 } 00568 00569 if (find_fbclkdly() == 0x0) 00570 { 00571 //while (1); /* fatal error */ 00572 return 1;//FALSE; 00573 } 00574 00575 adjust_timing(); 00576 00577 initialized = true; 00578 00579 return 0;//TRUE; 00580 } 00581 00582 void sdram_disableMallocSdram() 00583 { 00584 okToUseSdramForHeap = false; 00585 } 00586 00587
Generated on Tue Jul 12 2022 15:13:41 by 1.7.2