The wait in mci_WaitForEvent will delay all card transactions.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sdram.cpp Source File

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