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