MP3 Player. You can change fwd/rev speed and skip. see: http://mbed.org/users/okini3939/notebook/lpc4088_madplayer/
Dependencies: I2SSlave SDFileSystem TLV320 mbed
EALib/sdram.cpp@0:8ba6230eefbd, 2014-02-18 (annotated)
- Committer:
- okini3939
- Date:
- Tue Feb 18 00:22:50 2014 +0000
- Revision:
- 0:8ba6230eefbd
1st build
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 0:8ba6230eefbd | 1 | /* |
okini3939 | 0:8ba6230eefbd | 2 | * Copyright 2013 Embedded Artists AB |
okini3939 | 0:8ba6230eefbd | 3 | * |
okini3939 | 0:8ba6230eefbd | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
okini3939 | 0:8ba6230eefbd | 5 | * you may not use this file except in compliance with the License. |
okini3939 | 0:8ba6230eefbd | 6 | * You may obtain a copy of the License at |
okini3939 | 0:8ba6230eefbd | 7 | * |
okini3939 | 0:8ba6230eefbd | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
okini3939 | 0:8ba6230eefbd | 9 | * |
okini3939 | 0:8ba6230eefbd | 10 | * Unless required by applicable law or agreed to in writing, software |
okini3939 | 0:8ba6230eefbd | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
okini3939 | 0:8ba6230eefbd | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
okini3939 | 0:8ba6230eefbd | 13 | * See the License for the specific language governing permissions and |
okini3939 | 0:8ba6230eefbd | 14 | * limitations under the License. |
okini3939 | 0:8ba6230eefbd | 15 | */ |
okini3939 | 0:8ba6230eefbd | 16 | |
okini3939 | 0:8ba6230eefbd | 17 | |
okini3939 | 0:8ba6230eefbd | 18 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 19 | * Includes |
okini3939 | 0:8ba6230eefbd | 20 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 21 | |
okini3939 | 0:8ba6230eefbd | 22 | #include "mbed.h" |
okini3939 | 0:8ba6230eefbd | 23 | #include "sdram.h" |
okini3939 | 0:8ba6230eefbd | 24 | |
okini3939 | 0:8ba6230eefbd | 25 | #if defined(TOOLCHAIN_ARM) /* KEIL uVision and mbed online compiler */ |
okini3939 | 0:8ba6230eefbd | 26 | #include "sys_helper.h" |
okini3939 | 0:8ba6230eefbd | 27 | #endif |
okini3939 | 0:8ba6230eefbd | 28 | |
okini3939 | 0:8ba6230eefbd | 29 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 30 | * Defines and typedefs |
okini3939 | 0:8ba6230eefbd | 31 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 32 | |
okini3939 | 0:8ba6230eefbd | 33 | |
okini3939 | 0:8ba6230eefbd | 34 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 35 | * External global variables |
okini3939 | 0:8ba6230eefbd | 36 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 37 | |
okini3939 | 0:8ba6230eefbd | 38 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 39 | * Local variables |
okini3939 | 0:8ba6230eefbd | 40 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 41 | |
okini3939 | 0:8ba6230eefbd | 42 | static volatile uint32_t ringosccount[2] = {0,0}; |
okini3939 | 0:8ba6230eefbd | 43 | |
okini3939 | 0:8ba6230eefbd | 44 | static bool okToUseSdramForHeap = true; |
okini3939 | 0:8ba6230eefbd | 45 | static bool initialized = false; |
okini3939 | 0:8ba6230eefbd | 46 | |
okini3939 | 0:8ba6230eefbd | 47 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 48 | * Overridden Global Functions |
okini3939 | 0:8ba6230eefbd | 49 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 50 | |
okini3939 | 0:8ba6230eefbd | 51 | #if defined(TOOLCHAIN_ARM) /* KEIL uVision and mbed online compiler */ |
okini3939 | 0:8ba6230eefbd | 52 | //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0349c/Cihehbce.html |
okini3939 | 0:8ba6230eefbd | 53 | |
okini3939 | 0:8ba6230eefbd | 54 | extern "C" unsigned __rt_heap_extend(unsigned size, void **block) { |
okini3939 | 0:8ba6230eefbd | 55 | static uint32_t lastReturnedBlock = 0; |
okini3939 | 0:8ba6230eefbd | 56 | |
okini3939 | 0:8ba6230eefbd | 57 | if (okToUseSdramForHeap && !initialized) { |
okini3939 | 0:8ba6230eefbd | 58 | sdram_init(); |
okini3939 | 0:8ba6230eefbd | 59 | } |
okini3939 | 0:8ba6230eefbd | 60 | |
okini3939 | 0:8ba6230eefbd | 61 | // Make sure that SDRAM is only returned once (as all of it is returned |
okini3939 | 0:8ba6230eefbd | 62 | // the first time) and only if the user has chosen to do it (via the |
okini3939 | 0:8ba6230eefbd | 63 | // okToUseSdramForHeap variable. |
okini3939 | 0:8ba6230eefbd | 64 | if (okToUseSdramForHeap && lastReturnedBlock==0) { |
okini3939 | 0:8ba6230eefbd | 65 | *block = (void*)SDRAM_BASE; |
okini3939 | 0:8ba6230eefbd | 66 | lastReturnedBlock = SDRAM_BASE; |
okini3939 | 0:8ba6230eefbd | 67 | return SDRAM_SIZE; |
okini3939 | 0:8ba6230eefbd | 68 | } |
okini3939 | 0:8ba6230eefbd | 69 | return 0; |
okini3939 | 0:8ba6230eefbd | 70 | } |
okini3939 | 0:8ba6230eefbd | 71 | |
okini3939 | 0:8ba6230eefbd | 72 | // Overrides the WEAK function in sys_helper.cpp to allow reserving a specific |
okini3939 | 0:8ba6230eefbd | 73 | // amount of memory for the stack. Without this function it is possible to allocate |
okini3939 | 0:8ba6230eefbd | 74 | // so much of the internal RAM that there is no free memory for the stack which |
okini3939 | 0:8ba6230eefbd | 75 | // in turn causes the program to crash. |
okini3939 | 0:8ba6230eefbd | 76 | uint32_t __reserved_stack_size() { |
okini3939 | 0:8ba6230eefbd | 77 | return 0x3000; // Reserve 0x3000 bytes of the IRAM for the stack |
okini3939 | 0:8ba6230eefbd | 78 | } |
okini3939 | 0:8ba6230eefbd | 79 | |
okini3939 | 0:8ba6230eefbd | 80 | #elif defined(TOOLCHAIN_GCC_CR) /* CodeRed's RedSuite or LPCXpresso IDE */ |
okini3939 | 0:8ba6230eefbd | 81 | |
okini3939 | 0:8ba6230eefbd | 82 | // NOTE: This way of overriding the implementation of malloc in NEWLIB |
okini3939 | 0:8ba6230eefbd | 83 | // will prevent the internal RAM from being used by malloc as |
okini3939 | 0:8ba6230eefbd | 84 | // it only exposes the SDRAM. |
okini3939 | 0:8ba6230eefbd | 85 | |
okini3939 | 0:8ba6230eefbd | 86 | // Dynamic memory allocation related syscall. |
okini3939 | 0:8ba6230eefbd | 87 | extern "C" caddr_t _sbrk(int incr) { |
okini3939 | 0:8ba6230eefbd | 88 | static unsigned char* heap = (unsigned char*)SDRAM_BASE; |
okini3939 | 0:8ba6230eefbd | 89 | unsigned char* prev_heap = heap; |
okini3939 | 0:8ba6230eefbd | 90 | unsigned char* new_heap = heap + incr; |
okini3939 | 0:8ba6230eefbd | 91 | |
okini3939 | 0:8ba6230eefbd | 92 | if (okToUseSdramForHeap && !initialized) { |
okini3939 | 0:8ba6230eefbd | 93 | sdram_init(); |
okini3939 | 0:8ba6230eefbd | 94 | } |
okini3939 | 0:8ba6230eefbd | 95 | if (!okToUseSdramForHeap) { |
okini3939 | 0:8ba6230eefbd | 96 | //errno = ENOMEM; |
okini3939 | 0:8ba6230eefbd | 97 | return (caddr_t)-1; |
okini3939 | 0:8ba6230eefbd | 98 | } |
okini3939 | 0:8ba6230eefbd | 99 | if (new_heap >= (unsigned char*)(SDRAM_BASE + SDRAM_SIZE)) { |
okini3939 | 0:8ba6230eefbd | 100 | //errno = ENOMEM; |
okini3939 | 0:8ba6230eefbd | 101 | return (caddr_t)-1; |
okini3939 | 0:8ba6230eefbd | 102 | } |
okini3939 | 0:8ba6230eefbd | 103 | |
okini3939 | 0:8ba6230eefbd | 104 | heap = new_heap; |
okini3939 | 0:8ba6230eefbd | 105 | return (caddr_t) prev_heap; |
okini3939 | 0:8ba6230eefbd | 106 | } |
okini3939 | 0:8ba6230eefbd | 107 | #endif |
okini3939 | 0:8ba6230eefbd | 108 | |
okini3939 | 0:8ba6230eefbd | 109 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 110 | * Local Functions |
okini3939 | 0:8ba6230eefbd | 111 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 112 | |
okini3939 | 0:8ba6230eefbd | 113 | static void pinConfig(void) |
okini3939 | 0:8ba6230eefbd | 114 | { |
okini3939 | 0:8ba6230eefbd | 115 | LPC_IOCON->P3_0 |= 1; /* D0 @ P3.0 */ |
okini3939 | 0:8ba6230eefbd | 116 | LPC_IOCON->P3_1 |= 1; /* D1 @ P3.1 */ |
okini3939 | 0:8ba6230eefbd | 117 | LPC_IOCON->P3_2 |= 1; /* D2 @ P3.2 */ |
okini3939 | 0:8ba6230eefbd | 118 | LPC_IOCON->P3_3 |= 1; /* D3 @ P3.3 */ |
okini3939 | 0:8ba6230eefbd | 119 | |
okini3939 | 0:8ba6230eefbd | 120 | LPC_IOCON->P3_4 |= 1; /* D4 @ P3.4 */ |
okini3939 | 0:8ba6230eefbd | 121 | LPC_IOCON->P3_5 |= 1; /* D5 @ P3.5 */ |
okini3939 | 0:8ba6230eefbd | 122 | LPC_IOCON->P3_6 |= 1; /* D6 @ P3.6 */ |
okini3939 | 0:8ba6230eefbd | 123 | LPC_IOCON->P3_7 |= 1; /* D7 @ P3.7 */ |
okini3939 | 0:8ba6230eefbd | 124 | |
okini3939 | 0:8ba6230eefbd | 125 | LPC_IOCON->P3_8 |= 1; /* D8 @ P3.8 */ |
okini3939 | 0:8ba6230eefbd | 126 | LPC_IOCON->P3_9 |= 1; /* D9 @ P3.9 */ |
okini3939 | 0:8ba6230eefbd | 127 | LPC_IOCON->P3_10 |= 1; /* D10 @ P3.10 */ |
okini3939 | 0:8ba6230eefbd | 128 | LPC_IOCON->P3_11 |= 1; /* D11 @ P3.11 */ |
okini3939 | 0:8ba6230eefbd | 129 | |
okini3939 | 0:8ba6230eefbd | 130 | LPC_IOCON->P3_12 |= 1; /* D12 @ P3.12 */ |
okini3939 | 0:8ba6230eefbd | 131 | LPC_IOCON->P3_13 |= 1; /* D13 @ P3.13 */ |
okini3939 | 0:8ba6230eefbd | 132 | LPC_IOCON->P3_14 |= 1; /* D14 @ P3.14 */ |
okini3939 | 0:8ba6230eefbd | 133 | LPC_IOCON->P3_15 |= 1; /* D15 @ P3.15 */ |
okini3939 | 0:8ba6230eefbd | 134 | |
okini3939 | 0:8ba6230eefbd | 135 | LPC_IOCON->P3_16 |= 1; /* D16 @ P3.16 */ |
okini3939 | 0:8ba6230eefbd | 136 | LPC_IOCON->P3_17 |= 1; /* D17 @ P3.17 */ |
okini3939 | 0:8ba6230eefbd | 137 | LPC_IOCON->P3_18 |= 1; /* D18 @ P3.18 */ |
okini3939 | 0:8ba6230eefbd | 138 | LPC_IOCON->P3_19 |= 1; /* D19 @ P3.19 */ |
okini3939 | 0:8ba6230eefbd | 139 | |
okini3939 | 0:8ba6230eefbd | 140 | LPC_IOCON->P3_20 |= 1; /* D20 @ P3.20 */ |
okini3939 | 0:8ba6230eefbd | 141 | LPC_IOCON->P3_21 |= 1; /* D21 @ P3.21 */ |
okini3939 | 0:8ba6230eefbd | 142 | LPC_IOCON->P3_22 |= 1; /* D22 @ P3.22 */ |
okini3939 | 0:8ba6230eefbd | 143 | LPC_IOCON->P3_23 |= 1; /* D23 @ P3.23 */ |
okini3939 | 0:8ba6230eefbd | 144 | |
okini3939 | 0:8ba6230eefbd | 145 | LPC_IOCON->P3_24 |= 1; /* D24 @ P3.24 */ |
okini3939 | 0:8ba6230eefbd | 146 | LPC_IOCON->P3_25 |= 1; /* D25 @ P3.25 */ |
okini3939 | 0:8ba6230eefbd | 147 | LPC_IOCON->P3_26 |= 1; /* D26 @ P3.26 */ |
okini3939 | 0:8ba6230eefbd | 148 | LPC_IOCON->P3_27 |= 1; /* D27 @ P3.27 */ |
okini3939 | 0:8ba6230eefbd | 149 | |
okini3939 | 0:8ba6230eefbd | 150 | LPC_IOCON->P3_28 |= 1; /* D28 @ P3.28 */ |
okini3939 | 0:8ba6230eefbd | 151 | LPC_IOCON->P3_29 |= 1; /* D29 @ P3.29 */ |
okini3939 | 0:8ba6230eefbd | 152 | LPC_IOCON->P3_30 |= 1; /* D30 @ P3.30 */ |
okini3939 | 0:8ba6230eefbd | 153 | LPC_IOCON->P3_31 |= 1; /* D31 @ P3.31 */ |
okini3939 | 0:8ba6230eefbd | 154 | |
okini3939 | 0:8ba6230eefbd | 155 | LPC_IOCON->P4_0 |= 1; /* A0 @ P4.0 */ |
okini3939 | 0:8ba6230eefbd | 156 | LPC_IOCON->P4_1 |= 1; /* A1 @ P4.1 */ |
okini3939 | 0:8ba6230eefbd | 157 | LPC_IOCON->P4_2 |= 1; /* A2 @ P4.2 */ |
okini3939 | 0:8ba6230eefbd | 158 | LPC_IOCON->P4_3 |= 1; /* A3 @ P4.3 */ |
okini3939 | 0:8ba6230eefbd | 159 | |
okini3939 | 0:8ba6230eefbd | 160 | LPC_IOCON->P4_4 |= 1; /* A4 @ P4.4 */ |
okini3939 | 0:8ba6230eefbd | 161 | LPC_IOCON->P4_5 |= 1; /* A5 @ P4.5 */ |
okini3939 | 0:8ba6230eefbd | 162 | LPC_IOCON->P4_6 |= 1; /* A6 @ P4.6 */ |
okini3939 | 0:8ba6230eefbd | 163 | LPC_IOCON->P4_7 |= 1; /* A7 @ P4.7 */ |
okini3939 | 0:8ba6230eefbd | 164 | |
okini3939 | 0:8ba6230eefbd | 165 | LPC_IOCON->P4_8 |= 1; /* A8 @ P4.8 */ |
okini3939 | 0:8ba6230eefbd | 166 | LPC_IOCON->P4_9 |= 1; /* A9 @ P4.9 */ |
okini3939 | 0:8ba6230eefbd | 167 | LPC_IOCON->P4_10 |= 1; /* A10 @ P4.10 */ |
okini3939 | 0:8ba6230eefbd | 168 | LPC_IOCON->P4_11 |= 1; /* A11 @ P4.11 */ |
okini3939 | 0:8ba6230eefbd | 169 | |
okini3939 | 0:8ba6230eefbd | 170 | LPC_IOCON->P4_12 |= 1; /* A12 @ P4.12 */ |
okini3939 | 0:8ba6230eefbd | 171 | LPC_IOCON->P4_13 |= 1; /* A13 @ P4.13 */ |
okini3939 | 0:8ba6230eefbd | 172 | LPC_IOCON->P4_14 |= 1; /* A14 @ P4.14 */ |
okini3939 | 0:8ba6230eefbd | 173 | #if 0 // not used for SDRAM |
okini3939 | 0:8ba6230eefbd | 174 | LPC_IOCON->P4_15 |= 1; /* A15 @ P4.15 */ |
okini3939 | 0:8ba6230eefbd | 175 | |
okini3939 | 0:8ba6230eefbd | 176 | LPC_IOCON->P4_16 |= 1; /* A16 @ P4.16 */ |
okini3939 | 0:8ba6230eefbd | 177 | LPC_IOCON->P4_17 |= 1; /* A17 @ P4.17 */ |
okini3939 | 0:8ba6230eefbd | 178 | LPC_IOCON->P4_18 |= 1; /* A18 @ P4.18 */ |
okini3939 | 0:8ba6230eefbd | 179 | LPC_IOCON->P4_19 |= 1; /* A19 @ P4.19 */ |
okini3939 | 0:8ba6230eefbd | 180 | |
okini3939 | 0:8ba6230eefbd | 181 | LPC_IOCON->P4_20 |= 1; /* A20 @ P4.20 */ |
okini3939 | 0:8ba6230eefbd | 182 | LPC_IOCON->P4_21 |= 1; /* A21 @ P4.21 */ |
okini3939 | 0:8ba6230eefbd | 183 | LPC_IOCON->P4_22 |= 1; /* A22 @ P4.22 */ |
okini3939 | 0:8ba6230eefbd | 184 | LPC_IOCON->P4_23 |= 1; /* A23 @ P4.23 */ |
okini3939 | 0:8ba6230eefbd | 185 | #endif |
okini3939 | 0:8ba6230eefbd | 186 | |
okini3939 | 0:8ba6230eefbd | 187 | LPC_IOCON->P4_24 |= 1; /* OEN @ P4.24 */ |
okini3939 | 0:8ba6230eefbd | 188 | LPC_IOCON->P4_25 |= 1; /* WEN @ P4.25 */ |
okini3939 | 0:8ba6230eefbd | 189 | #if 0 // not used for SDRAM |
okini3939 | 0:8ba6230eefbd | 190 | LPC_IOCON->P4_26 |= 1; /* BLSN[0] @ P4.26 */ |
okini3939 | 0:8ba6230eefbd | 191 | LPC_IOCON->P4_27 |= 1; /* BLSN[1] @ P4.27 */ |
okini3939 | 0:8ba6230eefbd | 192 | |
okini3939 | 0:8ba6230eefbd | 193 | |
okini3939 | 0:8ba6230eefbd | 194 | LPC_IOCON->P4_28 |= 1; /* BLSN[2] @ P4.28 */ |
okini3939 | 0:8ba6230eefbd | 195 | LPC_IOCON->P4_29 |= 1; /* BLSN[3] @ P4.29 */ |
okini3939 | 0:8ba6230eefbd | 196 | LPC_IOCON->P4_30 |= 1; /* CSN[0] @ P4.30 */ |
okini3939 | 0:8ba6230eefbd | 197 | LPC_IOCON->P4_31 |= 1; /* CSN[1] @ P4.31 */ |
okini3939 | 0:8ba6230eefbd | 198 | #endif |
okini3939 | 0:8ba6230eefbd | 199 | |
okini3939 | 0:8ba6230eefbd | 200 | LPC_IOCON->P2_14 |= 1; /* CSN[2] @ P2.14 */ |
okini3939 | 0:8ba6230eefbd | 201 | LPC_IOCON->P2_15 |= 1; /* CSN[3] @ P2.15 */ |
okini3939 | 0:8ba6230eefbd | 202 | |
okini3939 | 0:8ba6230eefbd | 203 | LPC_IOCON->P2_16 |= 1; /* CASN @ P2.16 */ |
okini3939 | 0:8ba6230eefbd | 204 | LPC_IOCON->P2_17 |= 1; /* RASN @ P2.17 */ |
okini3939 | 0:8ba6230eefbd | 205 | LPC_IOCON->P2_18 |= 1; /* CLK[0] @ P2.18 */ |
okini3939 | 0:8ba6230eefbd | 206 | #if 0 // not used for SDRAM |
okini3939 | 0:8ba6230eefbd | 207 | LPC_IOCON->P2_19 |= 1; /* CLK[1] @ P2.19 */ |
okini3939 | 0:8ba6230eefbd | 208 | #endif |
okini3939 | 0:8ba6230eefbd | 209 | |
okini3939 | 0:8ba6230eefbd | 210 | LPC_IOCON->P2_20 |= 1; /* DYCSN[0] @ P2.20 */ |
okini3939 | 0:8ba6230eefbd | 211 | #if 0 // not used for SDRAM |
okini3939 | 0:8ba6230eefbd | 212 | LPC_IOCON->P2_21 |= 1; /* DYCSN[1] @ P2.21 */ |
okini3939 | 0:8ba6230eefbd | 213 | LPC_IOCON->P2_22 |= 1; /* DYCSN[2] @ P2.22 */ |
okini3939 | 0:8ba6230eefbd | 214 | LPC_IOCON->P2_23 |= 1; /* DYCSN[3] @ P2.23 */ |
okini3939 | 0:8ba6230eefbd | 215 | #endif |
okini3939 | 0:8ba6230eefbd | 216 | |
okini3939 | 0:8ba6230eefbd | 217 | LPC_IOCON->P2_24 |= 1; /* CKE[0] @ P2.24 */ |
okini3939 | 0:8ba6230eefbd | 218 | #if 0 // not used for SDRAM |
okini3939 | 0:8ba6230eefbd | 219 | LPC_IOCON->P2_25 |= 1; /* CKE[1] @ P2.25 */ |
okini3939 | 0:8ba6230eefbd | 220 | LPC_IOCON->P2_26 |= 1; /* CKE[2] @ P2.26 */ |
okini3939 | 0:8ba6230eefbd | 221 | LPC_IOCON->P2_27 |= 1; /* CKE[3] @ P2.27 */ |
okini3939 | 0:8ba6230eefbd | 222 | #endif |
okini3939 | 0:8ba6230eefbd | 223 | |
okini3939 | 0:8ba6230eefbd | 224 | LPC_IOCON->P2_28 |= 1; /* DQM[0] @ P2.28 */ |
okini3939 | 0:8ba6230eefbd | 225 | LPC_IOCON->P2_29 |= 1; /* DQM[1] @ P2.29 */ |
okini3939 | 0:8ba6230eefbd | 226 | LPC_IOCON->P2_30 |= 1; /* DQM[2] @ P2.30 */ |
okini3939 | 0:8ba6230eefbd | 227 | LPC_IOCON->P2_31 |= 1; /* DQM[3] @ P2.31 */ |
okini3939 | 0:8ba6230eefbd | 228 | } |
okini3939 | 0:8ba6230eefbd | 229 | |
okini3939 | 0:8ba6230eefbd | 230 | |
okini3939 | 0:8ba6230eefbd | 231 | static uint32_t sdram_test( void ) |
okini3939 | 0:8ba6230eefbd | 232 | { |
okini3939 | 0:8ba6230eefbd | 233 | volatile uint32_t *wr_ptr; |
okini3939 | 0:8ba6230eefbd | 234 | volatile uint16_t *short_wr_ptr; |
okini3939 | 0:8ba6230eefbd | 235 | uint32_t data; |
okini3939 | 0:8ba6230eefbd | 236 | uint32_t i, j; |
okini3939 | 0:8ba6230eefbd | 237 | |
okini3939 | 0:8ba6230eefbd | 238 | wr_ptr = (uint32_t *)SDRAM_BASE; |
okini3939 | 0:8ba6230eefbd | 239 | short_wr_ptr = (uint16_t *)wr_ptr; |
okini3939 | 0:8ba6230eefbd | 240 | /* Clear content before 16 bit access test */ |
okini3939 | 0:8ba6230eefbd | 241 | // for (i = 0; i < SDRAM_SIZE/4; i++) |
okini3939 | 0:8ba6230eefbd | 242 | // { |
okini3939 | 0:8ba6230eefbd | 243 | // *wr_ptr++ = 0; |
okini3939 | 0:8ba6230eefbd | 244 | // } |
okini3939 | 0:8ba6230eefbd | 245 | |
okini3939 | 0:8ba6230eefbd | 246 | /* 16 bit write */ |
okini3939 | 0:8ba6230eefbd | 247 | for (i = 0; i < SDRAM_SIZE/0x40000; i++) |
okini3939 | 0:8ba6230eefbd | 248 | { |
okini3939 | 0:8ba6230eefbd | 249 | for (j = 0; j < 0x100; j++) |
okini3939 | 0:8ba6230eefbd | 250 | { |
okini3939 | 0:8ba6230eefbd | 251 | *short_wr_ptr++ = (i + j); |
okini3939 | 0:8ba6230eefbd | 252 | *short_wr_ptr++ = (i + j) + 1; |
okini3939 | 0:8ba6230eefbd | 253 | } |
okini3939 | 0:8ba6230eefbd | 254 | } |
okini3939 | 0:8ba6230eefbd | 255 | |
okini3939 | 0:8ba6230eefbd | 256 | /* Verifying */ |
okini3939 | 0:8ba6230eefbd | 257 | wr_ptr = (uint32_t *)SDRAM_BASE; |
okini3939 | 0:8ba6230eefbd | 258 | for (i = 0; i < SDRAM_SIZE/0x40000; i++) |
okini3939 | 0:8ba6230eefbd | 259 | { |
okini3939 | 0:8ba6230eefbd | 260 | for (j = 0; j < 0x100; j++) |
okini3939 | 0:8ba6230eefbd | 261 | { |
okini3939 | 0:8ba6230eefbd | 262 | data = *wr_ptr; |
okini3939 | 0:8ba6230eefbd | 263 | if (data != (((((i + j) + 1) & 0xFFFF) << 16) | ((i + j) & 0xFFFF))) |
okini3939 | 0:8ba6230eefbd | 264 | { |
okini3939 | 0:8ba6230eefbd | 265 | return 0x0; |
okini3939 | 0:8ba6230eefbd | 266 | } |
okini3939 | 0:8ba6230eefbd | 267 | wr_ptr++; |
okini3939 | 0:8ba6230eefbd | 268 | } |
okini3939 | 0:8ba6230eefbd | 269 | } |
okini3939 | 0:8ba6230eefbd | 270 | return 0x1; |
okini3939 | 0:8ba6230eefbd | 271 | } |
okini3939 | 0:8ba6230eefbd | 272 | |
okini3939 | 0:8ba6230eefbd | 273 | static uint32_t find_cmddly(void) |
okini3939 | 0:8ba6230eefbd | 274 | { |
okini3939 | 0:8ba6230eefbd | 275 | uint32_t cmddly, cmddlystart, cmddlyend, dwtemp; |
okini3939 | 0:8ba6230eefbd | 276 | uint32_t ppass = 0x0, pass = 0x0; |
okini3939 | 0:8ba6230eefbd | 277 | |
okini3939 | 0:8ba6230eefbd | 278 | cmddly = 0x0; |
okini3939 | 0:8ba6230eefbd | 279 | cmddlystart = cmddlyend = 0xFF; |
okini3939 | 0:8ba6230eefbd | 280 | |
okini3939 | 0:8ba6230eefbd | 281 | while (cmddly < 32) |
okini3939 | 0:8ba6230eefbd | 282 | { |
okini3939 | 0:8ba6230eefbd | 283 | dwtemp = LPC_SC->EMCDLYCTL & ~0x1F; |
okini3939 | 0:8ba6230eefbd | 284 | LPC_SC->EMCDLYCTL = dwtemp | cmddly; |
okini3939 | 0:8ba6230eefbd | 285 | |
okini3939 | 0:8ba6230eefbd | 286 | if (sdram_test() == 0x1) |
okini3939 | 0:8ba6230eefbd | 287 | { |
okini3939 | 0:8ba6230eefbd | 288 | /* Test passed */ |
okini3939 | 0:8ba6230eefbd | 289 | if (cmddlystart == 0xFF) |
okini3939 | 0:8ba6230eefbd | 290 | { |
okini3939 | 0:8ba6230eefbd | 291 | cmddlystart = cmddly; |
okini3939 | 0:8ba6230eefbd | 292 | } |
okini3939 | 0:8ba6230eefbd | 293 | ppass = 0x1; |
okini3939 | 0:8ba6230eefbd | 294 | } |
okini3939 | 0:8ba6230eefbd | 295 | else |
okini3939 | 0:8ba6230eefbd | 296 | { |
okini3939 | 0:8ba6230eefbd | 297 | /* Test failed */ |
okini3939 | 0:8ba6230eefbd | 298 | if (ppass == 1) |
okini3939 | 0:8ba6230eefbd | 299 | { |
okini3939 | 0:8ba6230eefbd | 300 | cmddlyend = cmddly; |
okini3939 | 0:8ba6230eefbd | 301 | pass = 0x1; |
okini3939 | 0:8ba6230eefbd | 302 | ppass = 0x0; |
okini3939 | 0:8ba6230eefbd | 303 | } |
okini3939 | 0:8ba6230eefbd | 304 | } |
okini3939 | 0:8ba6230eefbd | 305 | |
okini3939 | 0:8ba6230eefbd | 306 | /* Try next value */ |
okini3939 | 0:8ba6230eefbd | 307 | cmddly++; |
okini3939 | 0:8ba6230eefbd | 308 | } |
okini3939 | 0:8ba6230eefbd | 309 | |
okini3939 | 0:8ba6230eefbd | 310 | /* If the test passed, the we can use the average of the min and max values to get an optimal DQSIN delay */ |
okini3939 | 0:8ba6230eefbd | 311 | if (pass == 0x1) |
okini3939 | 0:8ba6230eefbd | 312 | { |
okini3939 | 0:8ba6230eefbd | 313 | cmddly = (cmddlystart + cmddlyend) / 2; |
okini3939 | 0:8ba6230eefbd | 314 | } |
okini3939 | 0:8ba6230eefbd | 315 | else if (ppass == 0x1) |
okini3939 | 0:8ba6230eefbd | 316 | { |
okini3939 | 0:8ba6230eefbd | 317 | cmddly = (cmddlystart + 0x1F) / 2; |
okini3939 | 0:8ba6230eefbd | 318 | } |
okini3939 | 0:8ba6230eefbd | 319 | else |
okini3939 | 0:8ba6230eefbd | 320 | { |
okini3939 | 0:8ba6230eefbd | 321 | /* A working value couldn't be found, just pick something safe so the system doesn't become unstable */ |
okini3939 | 0:8ba6230eefbd | 322 | cmddly = 0x10; |
okini3939 | 0:8ba6230eefbd | 323 | } |
okini3939 | 0:8ba6230eefbd | 324 | |
okini3939 | 0:8ba6230eefbd | 325 | dwtemp = LPC_SC->EMCDLYCTL & ~0x1F; |
okini3939 | 0:8ba6230eefbd | 326 | LPC_SC->EMCDLYCTL = dwtemp | cmddly; |
okini3939 | 0:8ba6230eefbd | 327 | |
okini3939 | 0:8ba6230eefbd | 328 | return (pass | ppass); |
okini3939 | 0:8ba6230eefbd | 329 | } |
okini3939 | 0:8ba6230eefbd | 330 | |
okini3939 | 0:8ba6230eefbd | 331 | static uint32_t find_fbclkdly(void) |
okini3939 | 0:8ba6230eefbd | 332 | { |
okini3939 | 0:8ba6230eefbd | 333 | uint32_t fbclkdly, fbclkdlystart, fbclkdlyend, dwtemp; |
okini3939 | 0:8ba6230eefbd | 334 | uint32_t ppass = 0x0, pass = 0x0; |
okini3939 | 0:8ba6230eefbd | 335 | |
okini3939 | 0:8ba6230eefbd | 336 | fbclkdly = 0x0; |
okini3939 | 0:8ba6230eefbd | 337 | fbclkdlystart = fbclkdlyend = 0xFF; |
okini3939 | 0:8ba6230eefbd | 338 | |
okini3939 | 0:8ba6230eefbd | 339 | while (fbclkdly < 32) |
okini3939 | 0:8ba6230eefbd | 340 | { |
okini3939 | 0:8ba6230eefbd | 341 | dwtemp = LPC_SC->EMCDLYCTL & ~0x1F00; |
okini3939 | 0:8ba6230eefbd | 342 | LPC_SC->EMCDLYCTL = dwtemp | (fbclkdly << 8); |
okini3939 | 0:8ba6230eefbd | 343 | |
okini3939 | 0:8ba6230eefbd | 344 | if (sdram_test() == 0x1) |
okini3939 | 0:8ba6230eefbd | 345 | { |
okini3939 | 0:8ba6230eefbd | 346 | /* Test passed */ |
okini3939 | 0:8ba6230eefbd | 347 | if (fbclkdlystart == 0xFF) |
okini3939 | 0:8ba6230eefbd | 348 | { |
okini3939 | 0:8ba6230eefbd | 349 | fbclkdlystart = fbclkdly; |
okini3939 | 0:8ba6230eefbd | 350 | } |
okini3939 | 0:8ba6230eefbd | 351 | ppass = 0x1; |
okini3939 | 0:8ba6230eefbd | 352 | } |
okini3939 | 0:8ba6230eefbd | 353 | else |
okini3939 | 0:8ba6230eefbd | 354 | { |
okini3939 | 0:8ba6230eefbd | 355 | /* Test failed */ |
okini3939 | 0:8ba6230eefbd | 356 | if (ppass == 1) |
okini3939 | 0:8ba6230eefbd | 357 | { |
okini3939 | 0:8ba6230eefbd | 358 | fbclkdlyend = fbclkdly; |
okini3939 | 0:8ba6230eefbd | 359 | pass = 0x1; |
okini3939 | 0:8ba6230eefbd | 360 | ppass = 0x0; |
okini3939 | 0:8ba6230eefbd | 361 | } |
okini3939 | 0:8ba6230eefbd | 362 | } |
okini3939 | 0:8ba6230eefbd | 363 | |
okini3939 | 0:8ba6230eefbd | 364 | /* Try next value */ |
okini3939 | 0:8ba6230eefbd | 365 | fbclkdly++; |
okini3939 | 0:8ba6230eefbd | 366 | } |
okini3939 | 0:8ba6230eefbd | 367 | |
okini3939 | 0:8ba6230eefbd | 368 | /* If the test passed, the we can use the average of the min and max values to get an optimal DQSIN delay */ |
okini3939 | 0:8ba6230eefbd | 369 | if (pass == 0x1) |
okini3939 | 0:8ba6230eefbd | 370 | { |
okini3939 | 0:8ba6230eefbd | 371 | fbclkdly = (fbclkdlystart + fbclkdlyend) / 2; |
okini3939 | 0:8ba6230eefbd | 372 | } |
okini3939 | 0:8ba6230eefbd | 373 | else if (ppass == 0x1) |
okini3939 | 0:8ba6230eefbd | 374 | { |
okini3939 | 0:8ba6230eefbd | 375 | fbclkdly = (fbclkdlystart + 0x1F) / 2; |
okini3939 | 0:8ba6230eefbd | 376 | } |
okini3939 | 0:8ba6230eefbd | 377 | else |
okini3939 | 0:8ba6230eefbd | 378 | { |
okini3939 | 0:8ba6230eefbd | 379 | /* A working value couldn't be found, just pick something safe so the system doesn't become unstable */ |
okini3939 | 0:8ba6230eefbd | 380 | fbclkdly = 0x10; |
okini3939 | 0:8ba6230eefbd | 381 | } |
okini3939 | 0:8ba6230eefbd | 382 | |
okini3939 | 0:8ba6230eefbd | 383 | dwtemp = LPC_SC->EMCDLYCTL & ~0x1F00; |
okini3939 | 0:8ba6230eefbd | 384 | LPC_SC->EMCDLYCTL = dwtemp | (fbclkdly << 8); |
okini3939 | 0:8ba6230eefbd | 385 | |
okini3939 | 0:8ba6230eefbd | 386 | return (pass | ppass); |
okini3939 | 0:8ba6230eefbd | 387 | } |
okini3939 | 0:8ba6230eefbd | 388 | |
okini3939 | 0:8ba6230eefbd | 389 | static uint32_t calibration( void ) |
okini3939 | 0:8ba6230eefbd | 390 | { |
okini3939 | 0:8ba6230eefbd | 391 | uint32_t dwtemp, i; |
okini3939 | 0:8ba6230eefbd | 392 | uint32_t cnt = 0; |
okini3939 | 0:8ba6230eefbd | 393 | |
okini3939 | 0:8ba6230eefbd | 394 | for (i = 0; i < 10; i++) |
okini3939 | 0:8ba6230eefbd | 395 | { |
okini3939 | 0:8ba6230eefbd | 396 | dwtemp = LPC_SC->EMCCAL & ~0x4000; |
okini3939 | 0:8ba6230eefbd | 397 | LPC_SC->EMCCAL = dwtemp | 0x4000; |
okini3939 | 0:8ba6230eefbd | 398 | |
okini3939 | 0:8ba6230eefbd | 399 | dwtemp = LPC_SC->EMCCAL; |
okini3939 | 0:8ba6230eefbd | 400 | while ((dwtemp & 0x8000) == 0x0000) |
okini3939 | 0:8ba6230eefbd | 401 | { |
okini3939 | 0:8ba6230eefbd | 402 | dwtemp = LPC_SC->EMCCAL; |
okini3939 | 0:8ba6230eefbd | 403 | } |
okini3939 | 0:8ba6230eefbd | 404 | cnt += (dwtemp & 0xFF); |
okini3939 | 0:8ba6230eefbd | 405 | } |
okini3939 | 0:8ba6230eefbd | 406 | return (cnt / 10); |
okini3939 | 0:8ba6230eefbd | 407 | } |
okini3939 | 0:8ba6230eefbd | 408 | |
okini3939 | 0:8ba6230eefbd | 409 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 410 | * Public Functions |
okini3939 | 0:8ba6230eefbd | 411 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 412 | |
okini3939 | 0:8ba6230eefbd | 413 | |
okini3939 | 0:8ba6230eefbd | 414 | void adjust_timing( void ) |
okini3939 | 0:8ba6230eefbd | 415 | { |
okini3939 | 0:8ba6230eefbd | 416 | uint32_t dwtemp, cmddly, fbclkdly; |
okini3939 | 0:8ba6230eefbd | 417 | |
okini3939 | 0:8ba6230eefbd | 418 | /* Current value */ |
okini3939 | 0:8ba6230eefbd | 419 | ringosccount[1] = calibration(); |
okini3939 | 0:8ba6230eefbd | 420 | |
okini3939 | 0:8ba6230eefbd | 421 | dwtemp = LPC_SC->EMCDLYCTL; |
okini3939 | 0:8ba6230eefbd | 422 | cmddly = ((dwtemp & 0x1F) * ringosccount[0] / ringosccount[1]) & 0x1F; |
okini3939 | 0:8ba6230eefbd | 423 | fbclkdly = ((dwtemp & 0x1F00) * ringosccount[0] / ringosccount[1]) & 0x1F00; |
okini3939 | 0:8ba6230eefbd | 424 | LPC_SC->EMCDLYCTL = (dwtemp & ~0x1F1F) | fbclkdly | cmddly; |
okini3939 | 0:8ba6230eefbd | 425 | } |
okini3939 | 0:8ba6230eefbd | 426 | |
okini3939 | 0:8ba6230eefbd | 427 | /****************************************************************************** |
okini3939 | 0:8ba6230eefbd | 428 | * |
okini3939 | 0:8ba6230eefbd | 429 | * Description: |
okini3939 | 0:8ba6230eefbd | 430 | * Initialize the SDRAM |
okini3939 | 0:8ba6230eefbd | 431 | * |
okini3939 | 0:8ba6230eefbd | 432 | *****************************************************************************/ |
okini3939 | 0:8ba6230eefbd | 433 | uint32_t sdram_init (void) |
okini3939 | 0:8ba6230eefbd | 434 | { |
okini3939 | 0:8ba6230eefbd | 435 | uint32_t i; |
okini3939 | 0:8ba6230eefbd | 436 | uint32_t dwtemp = 0; |
okini3939 | 0:8ba6230eefbd | 437 | //uint16_t wtemp = 0; |
okini3939 | 0:8ba6230eefbd | 438 | |
okini3939 | 0:8ba6230eefbd | 439 | if (initialized) { |
okini3939 | 0:8ba6230eefbd | 440 | return 0; |
okini3939 | 0:8ba6230eefbd | 441 | } |
okini3939 | 0:8ba6230eefbd | 442 | |
okini3939 | 0:8ba6230eefbd | 443 | LPC_SC->PCONP |= 0x00000800; |
okini3939 | 0:8ba6230eefbd | 444 | LPC_SC->EMCDLYCTL = 0x00001010; |
okini3939 | 0:8ba6230eefbd | 445 | LPC_EMC->Control = 0x00000001; |
okini3939 | 0:8ba6230eefbd | 446 | LPC_EMC->Config = 0x00000000; |
okini3939 | 0:8ba6230eefbd | 447 | |
okini3939 | 0:8ba6230eefbd | 448 | pinConfig(); //Full 32-bit Data bus, 24-bit Address |
okini3939 | 0:8ba6230eefbd | 449 | |
okini3939 | 0:8ba6230eefbd | 450 | /* Configure memory layout, but MUST DISABLE BUFFERs during configuration */ |
okini3939 | 0:8ba6230eefbd | 451 | /* 256MB, 8Mx32, 4 banks, row=12, column=9 */ |
okini3939 | 0:8ba6230eefbd | 452 | LPC_EMC->DynamicConfig0 = 0x00004480; |
okini3939 | 0:8ba6230eefbd | 453 | |
okini3939 | 0:8ba6230eefbd | 454 | /*Configure timing for ISSI IS4x32800D SDRAM*/ |
okini3939 | 0:8ba6230eefbd | 455 | |
okini3939 | 0:8ba6230eefbd | 456 | #if (SDRAM_SPEED==SDRAM_SPEED_48) |
okini3939 | 0:8ba6230eefbd | 457 | //Timing for 48MHz Bus |
okini3939 | 0:8ba6230eefbd | 458 | LPC_EMC->DynamicRasCas0 = 0x00000201; /* 1 RAS, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 459 | LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ |
okini3939 | 0:8ba6230eefbd | 460 | LPC_EMC->DynamicRP = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 461 | LPC_EMC->DynamicRAS = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 462 | LPC_EMC->DynamicSREX = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 463 | LPC_EMC->DynamicAPR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 464 | LPC_EMC->DynamicDAL = 0x00000002; /* ( n ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 465 | LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 466 | LPC_EMC->DynamicRC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 467 | LPC_EMC->DynamicRFC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 468 | LPC_EMC->DynamicXSR = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 469 | LPC_EMC->DynamicRRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 470 | LPC_EMC->DynamicMRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 471 | #elif (SDRAM_SPEED==SDRAM_SPEED_50) |
okini3939 | 0:8ba6230eefbd | 472 | //Timing for 50MHz Bus (with 100MHz M3 Core) |
okini3939 | 0:8ba6230eefbd | 473 | LPC_EMC->DynamicRasCas0 = 0x00000201; /* 1 RAS, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 474 | LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ |
okini3939 | 0:8ba6230eefbd | 475 | LPC_EMC->DynamicRP = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 476 | LPC_EMC->DynamicRAS = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 477 | LPC_EMC->DynamicSREX = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 478 | LPC_EMC->DynamicAPR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 479 | LPC_EMC->DynamicDAL = 0x00000002; /* ( n ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 480 | LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 481 | LPC_EMC->DynamicRC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 482 | LPC_EMC->DynamicRFC = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 483 | LPC_EMC->DynamicXSR = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 484 | LPC_EMC->DynamicRRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 485 | LPC_EMC->DynamicMRD = 0x00000000; /* ( n + 1 ) -> 1 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 486 | #elif (SDRAM_SPEED==SDRAM_SPEED_60) |
okini3939 | 0:8ba6230eefbd | 487 | //Timing for 60 MHz Bus (same as 72MHz) |
okini3939 | 0:8ba6230eefbd | 488 | LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 489 | LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ |
okini3939 | 0:8ba6230eefbd | 490 | LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 491 | LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 492 | LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 493 | LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 494 | LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 495 | LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 496 | LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 497 | LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 498 | LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 499 | LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 500 | LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 501 | #elif (SDRAM_SPEED==SDRAM_SPEED_72) |
okini3939 | 0:8ba6230eefbd | 502 | //Timing for 72 MHz Bus |
okini3939 | 0:8ba6230eefbd | 503 | LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 504 | LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ |
okini3939 | 0:8ba6230eefbd | 505 | LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 506 | LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 507 | LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 508 | LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 509 | LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 510 | LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 511 | LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 512 | LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 513 | LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 514 | LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 515 | LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 516 | #elif (SDRAM_SPEED==SDRAM_SPEED_80) |
okini3939 | 0:8ba6230eefbd | 517 | //Timing for 80 MHz Bus (same as 72MHz) |
okini3939 | 0:8ba6230eefbd | 518 | LPC_EMC->DynamicRasCas0 = 0x00000202; /* 2 RAS, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 519 | LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */ |
okini3939 | 0:8ba6230eefbd | 520 | LPC_EMC->DynamicRP = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 521 | LPC_EMC->DynamicRAS = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 522 | LPC_EMC->DynamicSREX = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 523 | LPC_EMC->DynamicAPR = 0x00000002; /* ( n + 1 ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 524 | LPC_EMC->DynamicDAL = 0x00000003; /* ( n ) -> 3 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 525 | LPC_EMC->DynamicWR = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 526 | LPC_EMC->DynamicRC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 527 | LPC_EMC->DynamicRFC = 0x00000004; /* ( n + 1 ) -> 5 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 528 | LPC_EMC->DynamicXSR = 0x00000005; /* ( n + 1 ) -> 6 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 529 | LPC_EMC->DynamicRRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 530 | LPC_EMC->DynamicMRD = 0x00000001; /* ( n + 1 ) -> 2 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 531 | #else |
okini3939 | 0:8ba6230eefbd | 532 | #error UNSUPPORTED SDRAM FREQ |
okini3939 | 0:8ba6230eefbd | 533 | #endif |
okini3939 | 0:8ba6230eefbd | 534 | |
okini3939 | 0:8ba6230eefbd | 535 | LPC_EMC->DynamicControl = 0x00000183; /* Issue NOP command */ |
okini3939 | 0:8ba6230eefbd | 536 | wait(0.2); /* wait 200ms */ |
okini3939 | 0:8ba6230eefbd | 537 | LPC_EMC->DynamicControl = 0x00000103; /* Issue PALL command */ |
okini3939 | 0:8ba6230eefbd | 538 | LPC_EMC->DynamicRefresh = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */ |
okini3939 | 0:8ba6230eefbd | 539 | for(i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */ |
okini3939 | 0:8ba6230eefbd | 540 | |
okini3939 | 0:8ba6230eefbd | 541 | |
okini3939 | 0:8ba6230eefbd | 542 | #if (SDRAM_SPEED==SDRAM_SPEED_48) |
okini3939 | 0:8ba6230eefbd | 543 | //Timing for 48MHz Bus |
okini3939 | 0:8ba6230eefbd | 544 | LPC_EMC->DynamicRefresh = 0x0000002E; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */ |
okini3939 | 0:8ba6230eefbd | 545 | #elif (SDRAM_SPEED==SDRAM_SPEED_50) |
okini3939 | 0:8ba6230eefbd | 546 | //Timing for 50MHz Bus |
okini3939 | 0:8ba6230eefbd | 547 | LPC_EMC->DynamicRefresh = 0x0000003A; /* ( n * 16 ) -> 768 clock cycles -> 15.360uS at 50MHz <= 15.625uS ( 64ms / 4096 row ) */ |
okini3939 | 0:8ba6230eefbd | 548 | #elif (SDRAM_SPEED==SDRAM_SPEED_60) |
okini3939 | 0:8ba6230eefbd | 549 | //Timing for 60MHz Bus |
okini3939 | 0:8ba6230eefbd | 550 | LPC_EMC->DynamicRefresh = 0x0000003A; /* ( n * 16 ) -> 928 clock cycles -> 15.466uS at 60MHz <= 15.625uS ( 64ms / 4096 row ) */ |
okini3939 | 0:8ba6230eefbd | 551 | #elif (SDRAM_SPEED==SDRAM_SPEED_72) |
okini3939 | 0:8ba6230eefbd | 552 | //Timing for 72MHz Bus |
okini3939 | 0:8ba6230eefbd | 553 | LPC_EMC->DynamicRefresh = 0x00000046; /* ( n * 16 ) -> 1120 clock cycles -> 15.556uS at 72MHz <= 15.625uS ( 64ms / 4096 row ) */ |
okini3939 | 0:8ba6230eefbd | 554 | #elif (SDRAM_SPEED==SDRAM_SPEED_80) |
okini3939 | 0:8ba6230eefbd | 555 | //Timing for 80MHz Bus |
okini3939 | 0:8ba6230eefbd | 556 | LPC_EMC->DynamicRefresh = 0x0000004E; /* ( n * 16 ) -> 1248 clock cycles -> 15.600uS at 80MHz <= 15.625uS ( 64ms / 4096 row ) */ |
okini3939 | 0:8ba6230eefbd | 557 | #else |
okini3939 | 0:8ba6230eefbd | 558 | #error UNSUPPORTED SDRAM FREQ |
okini3939 | 0:8ba6230eefbd | 559 | #endif |
okini3939 | 0:8ba6230eefbd | 560 | |
okini3939 | 0:8ba6230eefbd | 561 | LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */ |
okini3939 | 0:8ba6230eefbd | 562 | //Timing for 48/60/72MHZ Bus |
okini3939 | 0:8ba6230eefbd | 563 | dwtemp = *((volatile uint32_t *)(SDRAM_BASE | (0x22<<(2+2+9)))); /* 4 burst, 2 CAS latency */ |
okini3939 | 0:8ba6230eefbd | 564 | dwtemp = dwtemp; |
okini3939 | 0:8ba6230eefbd | 565 | LPC_EMC->DynamicControl = 0x00000000; /* Issue NORMAL command */ |
okini3939 | 0:8ba6230eefbd | 566 | //[re]enable buffers |
okini3939 | 0:8ba6230eefbd | 567 | LPC_EMC->DynamicConfig0 = 0x00084480; /* 256MB, 8Mx32, 4 banks, row=12, column=9 */ |
okini3939 | 0:8ba6230eefbd | 568 | |
okini3939 | 0:8ba6230eefbd | 569 | /* Nominal value */ |
okini3939 | 0:8ba6230eefbd | 570 | ringosccount[0] = calibration(); |
okini3939 | 0:8ba6230eefbd | 571 | |
okini3939 | 0:8ba6230eefbd | 572 | if (find_cmddly() == 0x0) |
okini3939 | 0:8ba6230eefbd | 573 | { |
okini3939 | 0:8ba6230eefbd | 574 | //while (1); /* fatal error */ |
okini3939 | 0:8ba6230eefbd | 575 | return 1;//FALSE; |
okini3939 | 0:8ba6230eefbd | 576 | } |
okini3939 | 0:8ba6230eefbd | 577 | |
okini3939 | 0:8ba6230eefbd | 578 | if (find_fbclkdly() == 0x0) |
okini3939 | 0:8ba6230eefbd | 579 | { |
okini3939 | 0:8ba6230eefbd | 580 | //while (1); /* fatal error */ |
okini3939 | 0:8ba6230eefbd | 581 | return 1;//FALSE; |
okini3939 | 0:8ba6230eefbd | 582 | } |
okini3939 | 0:8ba6230eefbd | 583 | |
okini3939 | 0:8ba6230eefbd | 584 | adjust_timing(); |
okini3939 | 0:8ba6230eefbd | 585 | |
okini3939 | 0:8ba6230eefbd | 586 | initialized = true; |
okini3939 | 0:8ba6230eefbd | 587 | |
okini3939 | 0:8ba6230eefbd | 588 | return 0;//TRUE; |
okini3939 | 0:8ba6230eefbd | 589 | } |
okini3939 | 0:8ba6230eefbd | 590 | |
okini3939 | 0:8ba6230eefbd | 591 | void sdram_disableMallocSdram() |
okini3939 | 0:8ba6230eefbd | 592 | { |
okini3939 | 0:8ba6230eefbd | 593 | okToUseSdramForHeap = false; |
okini3939 | 0:8ba6230eefbd | 594 | } |
okini3939 | 0:8ba6230eefbd | 595 | |
okini3939 | 0:8ba6230eefbd | 596 |