1 | //*----------------------------------------------------------------------------
|
2 | // main.c
|
3 | // Testprogramm für das TFT-Display KWH040GM05-F02
|
4 | // 480 x 272 Pixel
|
5 | //
|
6 | // Hardware: LPC2478 @ 72MHz, SDRAM IS42S32400B (ISSI, 4M x 32)
|
7 | //
|
8 | // v1.0, Januar 2010, Erwin Reuss
|
9 | //*----------------------------------------------------------------------------
|
10 | #include "tools.h"
|
11 | //*----------------------------------------------------------------------------
|
12 | #define SDRAM_BASE_ADDR 0xA0000000
|
13 | #define SDRAM_SIZE 0x01000000
|
14 | //*----------------------------------------------------------------------------
|
15 | void EMC_Init(void)
|
16 | {
|
17 | u32 i;
|
18 |
|
19 | EMC_CTRL = 0x00000001; /*Disable Address mirror*/
|
20 | PCONP |= 0x00000800; /* Turn On EMC PCLK */
|
21 |
|
22 | PINSEL5 = 0x55010115;
|
23 | PINSEL6 = 0x55555555;
|
24 | PINSEL7 = 0x55555555;
|
25 | PINSEL8 = 0x15555555;
|
26 | PINSEL9 = (1 << 18);
|
27 |
|
28 | EMC_DYN_RP = 2; /* command period: 3(n+1) clock cycles */
|
29 | EMC_DYN_RAS = 3; /* RAS command period: 4(n+1) clock cycles */
|
30 | EMC_DYN_SREX = 7; /* Self-refresh period: 8(n+1) clock cycles */
|
31 | EMC_DYN_APR = 2; /* Data out to active: 3(n+1) clock cycles */
|
32 | EMC_DYN_DAL = 5; /* Data in to active: 6(n+1) clock cycles */
|
33 | EMC_DYN_WR = 1; /* Write recovery: 2(n+1) clock cycles */
|
34 | EMC_DYN_RC = 5; /* Active to Active cmd: 6(n+1) clock cycles */
|
35 | EMC_DYN_RFC = 5; /* Auto-refresh: 6(n+1) clock cycles */
|
36 | EMC_DYN_XSR = 7; /* Exit self-refresh: 8(n+1) clock cycles */
|
37 | EMC_DYN_RRD = 1; /* Active bank A->B: 2(n+1) clock cycles */
|
38 | EMC_DYN_MRD = 2; /* Load Mode to Active cmd: 3(n+1) clock cycles */
|
39 |
|
40 | EMC_DYN_RD_CFG = 1; /* Command delayed strategy */
|
41 | /* Default setting, RAS latency 3 CCLKs, CAS latenty 3 CCLKs. */
|
42 | EMC_DYN_RASCAS0 = 0x00000303;
|
43 | EMC_DYN_CFG0 = (1 << 14) | (0 << 12) | (2 << 9) | (2 << 7); // 4M x 32 in 4 banks
|
44 |
|
45 | delayMs(0, 100);
|
46 | /* Mem clock enable, CLKOUT runs, send command: NOP */
|
47 | EMC_DYN_CTRL = 0x00000183;
|
48 | delayMs(0, 200);
|
49 | /* Send command: PRECHARGE-ALL, shortest possible refresh period */
|
50 | EMC_DYN_CTRL = 0x00000103;
|
51 | /* set 32 CCLKs between SDRAM refresh cycles */
|
52 | EMC_DYN_RFSH = 0x00000002;
|
53 |
|
54 | for(i = 0; i < 0x40; i++); /* wait 128 AHB clock cycles */
|
55 | /* set 28 x 16CCLKs=448CCLK=7us between SDRAM refresh cycles */
|
56 | EMC_DYN_RFSH = 28;
|
57 | /* Mem clock enable, CLKOUT runs, send command: MODE */
|
58 | EMC_DYN_CTRL = 0x00000083;
|
59 | /* Set mode register in SDRAM */
|
60 | i = *((volatile DWORD *)(SDRAM_BASE_ADDR | (0x032 << 12)));
|
61 | EMC_DYN_CTRL = 0x00000000; /* Send command: NORMAL */
|
62 | EMC_DYN_CFG0 |= 0x00080000; /* Enable buffer */
|
63 | }
|
64 | //*----------------------------------------------------------------------------
|
65 | // LCD INIT
|
66 | //*----------------------------------------------------------------------------
|
67 | #define LCD_CFG (*(volatile unsigned long *)0xE01FC1B8)
|
68 | #define LCD_TIMH (*(volatile unsigned long *)0xFFE10000)
|
69 | #define LCD_TIMV (*(volatile unsigned long *)0xFFE10004)
|
70 | #define LCD_POL (*(volatile unsigned long *)0xFFE10008)
|
71 | #define LCD_UPBASE (*(volatile unsigned long *)0xFFE10010)
|
72 | #define LCD_LPBASE (*(volatile unsigned long *)0xFFE10014)
|
73 | #define LCD_CTRL (*(volatile unsigned long *)0xFFE10018)
|
74 | #define CRSR_CTRL (*(volatile unsigned long *)0xFFE10C00)
|
75 | //*----------------------------------------------------------------------------
|
76 | #define x_size 480
|
77 | #define y_size 272
|
78 | #define FRAMEBUF 0xA0000000
|
79 | //*----------------------------------------------------------------------------
|
80 | void Lcd_Init(void)
|
81 | {
|
82 | PINSEL0 |= 0x00055500;
|
83 | PINSEL3 |= 0x05555500;
|
84 | PINSEL4 |= 0x050FFFFF;
|
85 | PINSEL9 |= 0x0A000000;
|
86 | PINSEL11 |= 0x0000000B;
|
87 |
|
88 | PCONP |= BIT(20);
|
89 | LCD_CTRL = BIT(5) | (6 << 1); // TFT-5:6:5 Bit
|
90 | LCD_CFG = 7; // CCLK/8 = 9 Mhz
|
91 | LCD_POL = (0x01 << 26) // Bypass clock divider
|
92 | | ((x_size - 1) << 16) // Clock per Line
|
93 | | (0x00 << 14) // ENA aktiv low
|
94 | | (0x00 << 13) // DATA falling edge
|
95 | | (0x01 << 12) // HSYNC aktiv low
|
96 | | (0x01 << 11); // VSYNC aktiv low
|
97 | LCD_TIMH = (1 << 24) // Horizontal back porch (2)
|
98 | | (1 << 16) // Horizontal front porch (2)
|
99 | | (40 << 8) // Horizontal pulse width (41)
|
100 | | (((x_size / 16) - 1) << 2); // Pixels per Line
|
101 | LCD_TIMV = (2 << 24) // Vertical back porch (3)
|
102 | | (2 << 16) // Vertical front porch (3)
|
103 | | (9 << 10) // Vertical pulse width (10)
|
104 | | (y_size - 1); // Vertical lines
|
105 | LCD_UPBASE = FRAMEBUF;
|
106 | LCD_LPBASE = 0;
|
107 | LCD_CTRL |= BIT(11) | 0x01;
|
108 | }
|
109 | //*----------------------------------------------------------------------------
|
110 | // 24-Bit Farbtabelle für Farbbalken
|
111 | //*----------------------------------------------------------------------------
|
112 | const u32 coltab[] = { 0x00FFFFFF, 0x0000FFFF, 0x00FFFF00, 0x0000FF00,
|
113 | 0x00FF00FF, 0x000000FF, 0x00FF0000, 0x00000000 };
|
114 | //*----------------------------------------------------------------------------
|
115 | // Programm beginnt hier
|
116 | //*----------------------------------------------------------------------------
|
117 | int main(void)
|
118 | {
|
119 | u32 *ptr = (u32 *)0xA0000000;
|
120 | u32 x, y;
|
121 |
|
122 | EMC_Init();
|
123 | Lcd_Init();
|
124 |
|
125 | while((u32)ptr < 0xA1000000) { // Kompletten Speicher löschen
|
126 | *ptr++ = 0x00000000;
|
127 | }
|
128 |
|
129 | // Farbbalken anzeigen
|
130 | ptr = (u32 *)0xA0000000;
|
131 | for(y = 0; y < y_size; y++) {
|
132 | for(x = 0; x < x_size; x++) {
|
133 | ptr[y * 480 + x] = coltab[x / 60];
|
134 | }
|
135 | }
|
136 |
|
137 |
|
138 | while(true) { // Endlosschleife...
|
139 | }
|
140 | }
|
141 | //*----------------------------------------------------------------------------
|