]> git.sur5r.net Git - freertos/blob
88dadbf2ebdf68fd3396e9c354045167a8fb41dd
[freertos] /
1 /**********************************************************************
2 * $Id: lpc18xx_emc.c 8765 2011-12-08 00:51:21Z nxp21346 $               lpc18xx_emc.c           2011-12-07
3 *//**
4 * @file         lpc18xx_emc.c
5 * @brief        Contains all functions support for Clock Generation and Control
6 *                       firmware library on lpc18xx
7 * @version      1.0
8 * @date         07. December. 2011
9 * @author       NXP MCU SW Application Team
10 *
11 * Copyright(C) 2011, NXP Semiconductor
12 * All rights reserved.
13 *
14 ***********************************************************************
15 * Software that is described herein is for illustrative purposes only
16 * which provides customers with programming information regarding the
17 * products. This software is supplied "AS IS" without any warranties.
18 * NXP Semiconductors assumes no responsibility or liability for the
19 * use of the software, conveys no license or title under any patent,
20 * copyright, or mask work right to the product. NXP Semiconductors
21 * reserves the right to make changes in the software without
22 * notification. NXP Semiconductors also make no representation or
23 * warranty that such application will be suitable for the specified
24 * use without further testing or modification.
25 **********************************************************************/
26
27 #include "LPC18xx.h"
28 #include "lpc18xx_emc.h"
29 #include "lpc18xx_scu.h"
30
31 #define M32(x)  *((uint32_t *)x)
32 #define DELAYCYCLES(ns) (ns / ((1.0 / __EMCHZ) * 1E9))
33
34 void emc_WaitUS(volatile uint32_t us)
35 {
36         us *= (SystemCoreClock / 1000000) / 3;
37         while(us--);
38 }
39
40 void emc_WaitMS(uint32_t ms)
41 {
42         emc_WaitUS(ms * 1000);
43 }
44
45 void MemoryPinInit(void)
46 {
47   /* select correct functions on the GPIOs */
48
49 #if 1
50   /* DATA LINES 0..31 > D0..D31 */
51         /* P1_7 - EXTBUS_D0 \97 External memory data line 0 */
52     scu_pinmux(0x1,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_7: D0 (function 0) errata */
53     scu_pinmux(0x1,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_8: D1 (function 0) errata */
54     scu_pinmux(0x1,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_9: D2 (function 0) errata */
55     scu_pinmux(0x1,  10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_10: D3 (function 0) errata */
56     scu_pinmux(0x1,  11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_11: D4 (function 0) errata */
57     scu_pinmux(0x1,  12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_12: D5 (function 0) errata */
58     scu_pinmux(0x1,  13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_13: D6 (function 0) errata */
59     scu_pinmux(0x1,  14, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_14: D7 (function 0) errata */
60     scu_pinmux(0x5,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_4: D8 (function 0) errata */
61     scu_pinmux(0x5,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_5: D9 (function 0) errata */
62     scu_pinmux(0x5,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_6: D10 (function 0) errata */
63     scu_pinmux(0x5,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_7: D11 (function 0) errata */
64     scu_pinmux(0x5,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_0: D12 (function 0) errata */
65     scu_pinmux(0x5,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_1: D13 (function 0) errata */
66     scu_pinmux(0x5,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_2: D14 (function 0) errata */
67     scu_pinmux(0x5,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_3: D15 (function 0) errata */
68 #if 0
69     scu_pinmux(0xD,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_2: D16 (function 0) errata */
70     scu_pinmux(0xD,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_3: D17 (function 0) errata */
71     scu_pinmux(0xD,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_4: D18 (function 0) errata */
72     scu_pinmux(0xD,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_5: D19 (function 0) errata */
73     scu_pinmux(0xD,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_6: D20 (function 0) errata */
74     scu_pinmux(0xD,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_7: D21 (function 0) errata */
75     scu_pinmux(0xD,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_8: D22 (function 0) errata */
76     scu_pinmux(0xD,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_9: D23 (function 0) errata */
77     scu_pinmux(0xE,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_5: D24 (function 0) errata */
78     scu_pinmux(0xE,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_6: D25 (function 0) errata */
79     scu_pinmux(0xE,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_7: D26 (function 0) errata */
80     scu_pinmux(0xE,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_8: D27 (function 0) errata */
81     scu_pinmux(0xE,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_9: D28 (function 0) errata */
82     scu_pinmux(0xE, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_10: D29 (function 0) errata */
83     scu_pinmux(0xE, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_11: D30 (function 0) errata */
84     scu_pinmux(0xE, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_12: D31 (function 0) errata */
85 #endif
86   
87   /* ADDRESS LINES A0..A11 > A0..A11 */
88         scu_pinmux(0x2,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_9 - EXTBUS_A0 \97 External memory address line 0 */
89         scu_pinmux(0x2, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_10 - EXTBUS_A1 \97 External memory address line 1 */        
90         scu_pinmux(0x2, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_11 - EXTBUS_A2 \97 External memory address line 2 */        
91         scu_pinmux(0x2, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_12 - EXTBUS_A3 \97 External memory address line 3 */
92         scu_pinmux(0x2, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_13 - EXTBUS_A4 \97 External memory address line 4 */        
93         scu_pinmux(0x1,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P1_0 - EXTBUS_A5 \97 External memory address line 5 */
94         scu_pinmux(0x1,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P1_1 - EXTBUS_A6 \97 External memory address line 6 */ 
95         scu_pinmux(0x1,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P1_2 - EXTBUS_A7 \97 External memory address line 7 */ 
96         scu_pinmux(0x2,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_8 - EXTBUS_A8 \97 External memory address line 8 */
97         scu_pinmux(0x2,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P2_7 - EXTBUS_A9 \97 External memory address line 9 */ 
98         scu_pinmux(0x2,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P2_6 - EXTBUS_A10 \97 External memory address line 10 */
99         scu_pinmux(0x2,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P2_2 - EXTBUS_A11 \97 External memory address line 11 */
100         scu_pinmux(0x2,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P2_1 - EXTBUS_A12 \97 External memory address line 12 */
101         scu_pinmux(0x2,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* P2_0 - EXTBUS_A13 \97 External memory address line 13 */       
102         scu_pinmux(0x6,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);        /* P6_8 - EXTBUS_A14 \97 External memory address line 14 */
103         scu_pinmux(0x6,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);        /* P6_7 - EXTBUS_A15 \97 External memory address line 15 */       
104         scu_pinmux(0xD, 16,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* PD_16 - EXTBUS_A16 \97 External memory address line 16 */
105         scu_pinmux(0xD, 15,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* PD_15 - EXTBUS_A17 \97 External memory address line 17 */      
106         scu_pinmux(0xE,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PE_0 - EXTBUS_A18 \97 External memory address line 18 */
107         scu_pinmux(0xE,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PE_1 - EXTBUS_A19 \97 External memory address line 19 */
108         scu_pinmux(0xE,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PE_2 - EXTBUS_A20 \97 External memory address line 20 */
109         scu_pinmux(0xE,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PE_3 - EXTBUS_A21 \97 External memory address line 21 */
110         scu_pinmux(0xE,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PE_4 - EXTBUS_A22 \97 External memory address line 22 */       
111         scu_pinmux(0xA,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* PA_4 - EXTBUS_A23 \97 External memory address line 23 */
112
113   /* BYTE ENABLES */
114         scu_pinmux(0x1,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);        /* P1_4 - EXTBUS_BLS0 \97 LOW active Byte Lane select signal 0 */
115         scu_pinmux(0x6,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);        /* P6_6 - EXTBUS_BLS1 \97 LOW active Byte Lane select signal 1 */ 
116         scu_pinmux(0xD, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* PD_13 - EXTBUS_BLS2 \97 LOW active Byte Lane select signal 2 */
117         scu_pinmux(0xD, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);        /* PD_10 - EXTBUS_BLS3 \97 LOW active Byte Lane select signal 3 */                
118     
119     scu_pinmux(0x6,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_9: EXTBUS_DYCS0  (function 0) > CS# errata */
120     scu_pinmux(0x1,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_6: WE (function 0) errata */
121     scu_pinmux(0x6,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_4: CAS  (function 0) > CAS# errata */
122     scu_pinmux(0x6,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_5: RAS  (function 0) > RAS# errata */
123
124         LPC_SCU_CLK(0) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK0: EXTBUS_CLK0  (function 0, from datasheet) > CLK ds */
125     LPC_SCU_CLK(1) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK1: EXTBUS_CLK1  (function 2, from datasheet) */
126     LPC_SCU_CLK(2) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK2: EXTBUS_CLK2  (function 2, from datasheet) */
127     LPC_SCU_CLK(3) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK3: EXTBUS_CLK3  (function 2, from datasheet) */
128
129     scu_pinmux(0x6, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_11: CKEOUT0  (function 0) > CKE errata */
130     scu_pinmux(0x6, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_12: DQMOUT0  (function 0) > DQM0 errata */
131     scu_pinmux(0x6, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_10: DQMOUT1  (function 0) > DQM1 errata */
132     scu_pinmux(0xD,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_0: DQMOUT2  (function 2, from datasheet) > DQM2 errata */
133     scu_pinmux(0xE, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_13: DQMOUT3  (function 3, from datasheet) > DQM3 errata */
134
135         scu_pinmux(     1       ,       3       ,       MD_PLN_FAST     ,       3       );      //OE
136         scu_pinmux(     1       ,       4       ,       MD_PLN_FAST     ,       3       );      //BLS0
137         scu_pinmux(     1       ,       5       ,       MD_PLN_FAST     ,       3       );      //CS0
138         scu_pinmux(     1       ,       6       ,       MD_PLN_FAST     ,       3       );      //WE
139
140 #endif
141 }
142
143 void EMCFlashInit(void)
144 {
145         // Hitex board SST39VF3201B Flash
146         // Read Cycle Time 70 nS minimum
147         // Chip Enable Access Time 70 ns maximum
148         // Address Access Time 70 ns max
149         // Toe 35 ns max
150         // CE/OE high to inactive output 16 ns
151
152         /* Set up EMC Controller */
153         LPC_EMC->STATICWAITRD0 = DELAYCYCLES(70)+1;
154
155         LPC_EMC->STATICWAITPAG0 = DELAYCYCLES(70)+1;
156
157
158         LPC_EMC->CONTROL = 0x01;
159         LPC_EMC->STATICCONFIG0 = (1UL<<7) | (1UL);
160         LPC_EMC->STATICWAITOEN0 = DELAYCYCLES(35)+1;
161
162     /*Enable Buffer for External Flash*/
163     LPC_EMC->STATICCONFIG0 |= 1<<19;
164 }
165
166 /* SDRAM refresh time to 16 clock num */
167 #define EMC_SDRAM_REFRESH(freq,time)  \
168   (((uint64_t)((uint64_t)time * freq)/16000000000ull)+1)
169
170 void vEMC_InitSRDRAM(uint32_t u32BaseAddr, uint32_t u32Width, uint32_t u32Size, uint32_t u32DataBus, uint32_t u32ColAddrBits)
171 {
172    // adjust the CCU delaye for EMI (default to zero)
173     //LPC_SCU->EMCCLKDELAY = (CLK0_DELAY | (CLKE0_DELAY << 16));
174         // Move all clock delays together
175         LPC_SCU->EMCDELAYCLK = ((CLK0_DELAY) 
176                                                  |  (CLK0_DELAY << 4)
177                                                  |  (CLK0_DELAY << 8)
178                                                  |  (CLK0_DELAY << 12));
179
180    /* Initialize EMC to interface with SDRAM */
181         LPC_EMC->CONTROL                        = 0x00000001;   /* Enable the external memory controller */     
182         LPC_EMC->CONFIG                         = 0;
183
184         LPC_EMC->DYNAMICCONFIG0         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14));
185         LPC_EMC->DYNAMICCONFIG2         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14));
186
187     LPC_EMC->DYNAMICRASCAS0     = (3 << 0) | (3 << 8);      // aem
188     LPC_EMC->DYNAMICRASCAS2     = (3 << 0) | (3 << 8);  // aem
189         
190         LPC_EMC->DYNAMICREADCONFIG      = EMC_COMMAND_DELAYED_STRATEGY;
191         
192         LPC_EMC->DYNAMICRP                      = 1;    // calculated from xls sheet
193         LPC_EMC->DYNAMICRAS             = 3;
194         LPC_EMC->DYNAMICSREX            = 5;   
195         LPC_EMC->DYNAMICAPR             = 0;
196         LPC_EMC->DYNAMICDAL             = 4;
197         LPC_EMC->DYNAMICWR                      = 1;
198         LPC_EMC->DYNAMICRC                      = 5;   
199         LPC_EMC->DYNAMICRFC             = 5;   
200         LPC_EMC->DYNAMICXSR             = 5;   
201         LPC_EMC->DYNAMICRRD             = 1;
202         LPC_EMC->DYNAMICMRD             = 1;
203         
204         LPC_EMC->DYNAMICCONTROL         = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_NOP);
205         emc_WaitUS(100);
206         
207         LPC_EMC->DYNAMICCONTROL         = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_PRECHARGE_ALL);
208
209         LPC_EMC->DYNAMICREFRESH         = 2;
210         emc_WaitUS(100);
211         
212     LPC_EMC->DYNAMICREFRESH     = 50;
213         
214         LPC_EMC->DYNAMICCONTROL         = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_MODE);
215
216         if(u32DataBus == 0) 
217         {
218                 /* burst size 8 */
219         *((volatile uint32_t *)(u32BaseAddr | ((3 | (3 << 4)) << (u32ColAddrBits + 1))));
220         }
221         else 
222         {
223                 /* burst size 4 */
224                 *((volatile uint32_t *)(u32BaseAddr | ((2UL | (2UL << 4)) << (u32ColAddrBits + 2))));
225         }
226
227         LPC_EMC->DYNAMICCONTROL         = 0; // EMC_CE_ENABLE | EMC_CS_ENABLE;
228         LPC_EMC->DYNAMICCONFIG0         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
229         LPC_EMC->DYNAMICCONFIG1         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
230         LPC_EMC->DYNAMICCONFIG2         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
231         LPC_EMC->DYNAMICCONFIG3         = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
232 }
233