Skip to content

Commit 8f13d99

Browse files
committed
LCD turns on and draws.
Some basic progress on the LCD, such that the interface can turn-on and draw. The implementation uses a slow sequential-write method to update the display; the vestiges of an auto-copy system are also in place but not yet debugged. The system seems to support two methods for issuing commands and data to the LCD. One is a simple write-to-commit method. The other is a more sophisticated command list that's set up, and then dispatched. The write-to-commit kind of works now, although it's left to be seen if we aren't running too far ahead of commands or missing some wait states. To get the demo to work, run the following commands in fernly: bl 5 (turns on backlight) lcd su (sets up GPIOs and timing) lcd init (initializes the LCD-side controller) lcd tp1 (blasts a small test pattern to the top of display) You'll note that the VCOM setting looks to be off (alternate light/dark lines). Next steps include: 1) verify that commands are being issued correctly to the LCD (no missing commands due to writes happening faster than the interface can keep up) 2) cross-check with LCD datasheet for the initialization of the controller -- there are some undocumented commands I left out in this implementation, maybe they need to go in there; I also left out the gamma table. 3) get the autocopy method to work. I think, from what I can tell, the autocopy will take a region of interest from memory, composite it with up to four other regions with alpha blending, and then auto-copy this to the LCD. You can insert commands into the auto-copy stream as necessary, but I believe this, combined with the TE (tearing effect) sync bit, will allow you to just write to a region of memory as a frame buffer and have it show up on the display without any CPU intervention. Could be wrong tho....
1 parent 0893cc4 commit 8f13d99

File tree

3 files changed

+299
-22
lines changed

3 files changed

+299
-22
lines changed

cmd-lcd.c

+243-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "printf.h"
55
#include "serial.h"
66
#include "fernvale-lcd.h"
7+
#include "fernvale-gpio.h"
8+
#include "fernvale-clockgate.h"
79

810
// local implementation of strncmp() because we don't have it as a lib in fernly
911
static int my_strncmp(const char* s1, const char* s2, size_t n)
@@ -17,10 +19,115 @@ static int my_strncmp(const char* s1, const char* s2, size_t n)
1719
return 0;
1820
}
1921

22+
static void usleep(uint32_t usecs) {
23+
uint32_t i, j;
24+
for (i = 0; i < usecs; i++) {
25+
for (j = 0; j < 73; j++) {
26+
asm("nop");
27+
}
28+
}
29+
}
30+
31+
static void msleep(uint32_t msecs) {
32+
uint32_t i, j;
33+
for (i = 0; i < msecs; i++) {
34+
for (j = 0; j < 73000; j++) {
35+
asm("nop");
36+
}
37+
}
38+
}
39+
40+
#define USE_DMA 0
41+
#if USE_DMA // needs debuggin'
42+
void flush_dma( uint8_t q ) {
43+
while(*((volatile uint16_t *) LCD_STATUS_REG) & LCD_STATUS_BUSY_BIT)
44+
;
45+
46+
*((volatile uint16_t *) LCD_INT_ENA_REG) &= ~LCD_INT_ENA_TRIG_BIT;
47+
*((volatile uint32_t *) LCD_MEMMAP_CTRL_REG) &= 0x0FFFFFFF; // disable all layers
48+
*((volatile uint32_t *) LCD_MEMMAP_CTRL_REG) &= 0xFFFFE0FF; // clear command count
49+
*((volatile uint32_t *) LCD_MEMMAP_CTRL_REG) |= (q << 8); // enter command count
50+
*((volatile uint32_t *) LCD_MEMMAP_CTRL_REG) |= 0x8000; // enable commands to be sent first
51+
*((volatile uint32_t *)LCD_MEMMAP_SIZE_REG) = 0x0;
52+
*((volatile uint16_t *)LCD_RUN_REG) = 0;
53+
*((volatile uint16_t *)LCD_RUN_REG) = LCD_RUN_BIT;
54+
usleep(1);
55+
56+
while(*((volatile uint16_t *) LCD_STATUS_REG) & LCD_STATUS_BUSY_BIT)
57+
;
58+
59+
*((volatile uint32_t *)LCD_MEMMAP_SIZE_REG) = 0x014000F0;
60+
}
61+
62+
void lcd_cmd( uint16_t cmd ) {
63+
*((volatile uint32_t *)LCD_CMD_LIST_ADDR) = 0x800000 | cmd;
64+
flush_dma(1);
65+
}
66+
67+
void lcd_dat( uint16_t dat ) {
68+
*((volatile uint32_t *)LCD_CMD_LIST_ADDR) = dat;
69+
flush_dma(1);
70+
}
71+
72+
// note these don't flush the DMA, you have to do this yourself explicitly later on
73+
void lcd_cmd_slot( uint16_t cmd, uint8_t slot ) { // slot is the order to execute
74+
*((volatile uint32_t *) (LCD_CMD_LIST_ADDR + (slot << 2))) = 0x800000 | cmd;
75+
}
76+
void lcd_dat_slot( uint16_t dat, uint8_t slot ) { // slot is the order to execute
77+
*((volatile uint32_t *) (LCD_CMD_LIST_ADDR + (slot << 2))) = dat;
78+
}
79+
#else
80+
81+
#define lcd_cmd(_cmd_) *((volatile uint16_t *)LCD_PAR0_CMD_PORT_REG) = (uint16_t) _cmd_
82+
#define lcd_dat(_dat_) *((volatile uint16_t *)LCD_PAR0_DAT_PORT_REG) = (uint16_t) _dat_
83+
84+
#endif
85+
86+
87+
void setup_lcd_gpio() {
88+
// LPCE0, LPTE0, LPRSTB
89+
*((volatile uint32_t *) GPIO_CTRL_MODE5) &= ~( GPIO_CTRL_MODE5_IO40_MASK |
90+
GPIO_CTRL_MODE5_IO46_MASK |
91+
GPIO_CTRL_MODE5_IO45_MASK );
92+
*((volatile uint32_t *) GPIO_CTRL_MODE5) |= ( GPIO_CTRL_MODE5_IO40_LPCE0B |
93+
GPIO_CTRL_MODE5_IO45_LPTE0 |
94+
GPIO_CTRL_MODE5_IO46_LPRSTB );
95+
96+
// NLD0-4, LWRB, LRDB, LPA0
97+
*((volatile uint32_t *) GPIO_CTRL_MODE4) &= ~( GPIO_CTRL_MODE4_IO32_MASK |
98+
GPIO_CTRL_MODE4_IO33_MASK |
99+
GPIO_CTRL_MODE4_IO34_MASK |
100+
GPIO_CTRL_MODE4_IO35_MASK |
101+
GPIO_CTRL_MODE4_IO36_MASK |
102+
GPIO_CTRL_MODE4_IO37_MASK |
103+
GPIO_CTRL_MODE4_IO38_MASK |
104+
GPIO_CTRL_MODE4_IO39_MASK );
105+
*((volatile uint32_t *) GPIO_CTRL_MODE4) |= ( GPIO_CTRL_MODE4_IO32_NLD4 |
106+
GPIO_CTRL_MODE4_IO33_NLD3 |
107+
GPIO_CTRL_MODE4_IO34_NLD2 |
108+
GPIO_CTRL_MODE4_IO35_NLD1 |
109+
GPIO_CTRL_MODE4_IO36_NLD0 |
110+
GPIO_CTRL_MODE4_IO37_LWRB |
111+
GPIO_CTRL_MODE4_IO38_LRDB |
112+
GPIO_CTRL_MODE4_IO39_LPA0 );
113+
114+
// NLD5-8
115+
*((volatile uint32_t *) GPIO_CTRL_MODE3) &= ~( GPIO_CTRL_MODE3_IO28_MASK |
116+
GPIO_CTRL_MODE3_IO29_MASK |
117+
GPIO_CTRL_MODE3_IO30_MASK |
118+
GPIO_CTRL_MODE3_IO31_MASK );
119+
*((volatile uint32_t *) GPIO_CTRL_MODE3) |= ( GPIO_CTRL_MODE3_IO28_NLD8 |
120+
GPIO_CTRL_MODE3_IO29_NLD7 |
121+
GPIO_CTRL_MODE3_IO30_NLD6 |
122+
GPIO_CTRL_MODE3_IO31_NLD5 );
123+
124+
}
125+
20126
int cmd_lcd(int argc, char **argv)
21127
{
22128
uint32_t genarg = 0;
23129
char *subcmd;
130+
int i;
24131

25132
if (argc < 1) {
26133
printf("Usage: lcd [subcmd] [arg0]\n");
@@ -35,25 +142,150 @@ int cmd_lcd(int argc, char **argv)
35142

36143
printf( "command got: %s\n", subcmd );
37144
if( my_strncmp( subcmd, "su", 8 ) == 0 ) {
145+
setup_lcd_gpio();
146+
147+
*((volatile uint32_t *) CLKGATE_SYS_CTL0_CLR) = CLKGATE_CTL0_LCD; // power up the LCD block
148+
msleep(1);
149+
38150
// execute setup command
39-
printf( "nothing for now.\n" );
151+
// we're on CS0
152+
// our internal bus period is 166 MHz, or 6.25ns
153+
// write cycle = 66ns = 11 cycles - 1 = 10
154+
// write c22write su (tcs) = 15ns = 3 cycles
155+
// write ce2write hold (tdht) = 10ns = 2 cycles - 1 = 1
156+
// read latency = 450 ns = 72 cycles, crop at 63 cycles
157+
// read ce2read su (trdl - trcs) = 45-45 = 0 ns = 0 cycles
158+
// read th = 90ns = 15 cycles (not quite clear, but best guess)
159+
*((volatile uint32_t *)LCD_PAR0_CFG_REG) =
160+
(10 << LCD_PAR_CFG_WR_WAIT_CYC_BIT) |
161+
(3 << LCD_PAR_CFG_WR_TSU_BIT) |
162+
(1 << LCD_PAR_CFG_WR_TH_BIT) |
163+
(63 << LCD_PAR_CFG_RD_LATENCY_CYC_BIT ) | // this might need to be shorter??
164+
(0 << LCD_PAR_CFG_RD_TSU_BIT) |
165+
(15 << LCD_PAR_CFG_RD_TH_BIT);
166+
167+
// 9 bit width, tchw is 0 for this chipset (back2back writes allowed)
168+
*((volatile uint32_t *)LCD_PAR_DATA_WIDTH_REG) =
169+
(0 << LCD_PAR_W2W_WAIT0_BIT) |
170+
(LCD_PAR_BUS_WIDTH_9BIT << LCD_PAR_BUS_WIDTH0_BIT);
171+
172+
*((volatile uint32_t *)LCD_AUTOCOPY_CTRL_REG) = 0; // AUTOCOPY off initially
173+
174+
} else if( my_strncmp( subcmd, "auto", 8 ) == 0 ) {
175+
*((volatile uint32_t *)LCD_LAYER0_CTRL_REG) = 0;
176+
*((volatile uint32_t *)LCD_LAYER0_OFFSET_REG) = 0;
177+
*((volatile uint32_t *)LCD_LAYER0_BUFF_ADDR_REG) = 0;
178+
*((volatile uint32_t *)LCD_LAYER0_SIZE_REG) = 0x014000f0;
179+
*((volatile uint32_t *)LCD_LAYER0_MEM_OFFSET_REG) = 0x0;
180+
*((volatile uint32_t *)LCD_LAYER0_MEM_PITCH_REG) = 0x1e0;
181+
182+
*((volatile uint32_t *)LCD_AUTOCOPY_OFFSET_REG) = 0;
183+
*((volatile uint16_t *)LCD_AUTOCOPY_CMD_ADDR_REG) = 0x4000;
184+
*((volatile uint16_t *)LCD_AUTOCOPY_DATA_ADDR_REG) = 0x4100;
185+
*((volatile uint32_t *)LCD_AUTOCOPY_SIZE_REG) = 0x014000F0;
186+
*((volatile uint32_t *)LCD_AUTOCOPY_BG_COLOR_REG) = 0x80008000;
187+
188+
*((volatile uint32_t *)LCD_AUTOCOPY_CTRL_REG) = 0x85020094;
189+
40190
} else if( my_strncmp( subcmd, "dump", 8 ) == 0 ) {
41191
// dump registers
42-
printf( "LCD_PAR0_CMD_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_CMD_PORT_REG) );
43-
printf( "LCD_PAR0_DAT_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_DAT_PORT_REG) );
44-
printf( "LCD_PAR1_CMD_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_CMD_PORT_REG) );
45-
printf( "LCD_PAR1_DAT_PORT_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_DAT_PORT_REG) );
192+
printf( "LCD_PAR0_CMD_PORT_REG: %04x\n", *((volatile uint16_t *) LCD_PAR0_CMD_PORT_REG) );
193+
printf( "LCD_PAR0_DAT_PORT_REG: %04x\n", *((volatile uint16_t *) LCD_PAR0_DAT_PORT_REG) );
194+
printf( "LCD_PAR1_CMD_PORT_REG: %04x\n", *((volatile uint16_t *) LCD_PAR1_CMD_PORT_REG) );
195+
printf( "LCD_PAR1_DAT_PORT_REG: %04x\n", *((volatile uint16_t *) LCD_PAR1_DAT_PORT_REG) );
46196
printf( "LCD_PAR0_CFG_REG: %08x\n", *((volatile uint32_t *) LCD_PAR0_CFG_REG) );
47197
printf( "LCD_PAR1_CFG_REG: %08x\n", *((volatile uint32_t *) LCD_PAR1_CFG_REG) );
48-
printf( "LCD_STATUS_REG: %08x\n", *((volatile uint32_t *) LCD_STATUS_REG) );
49-
printf( "LCD_INT_ENA_REG: %08x\n", *((volatile uint32_t *) LCD_INT_ENA_REG) );
50-
printf( "LCD_INT_STAT_REG: %08x\n", *((volatile uint32_t *) LCD_INT_STAT_REG) );
51-
printf( "LCD_RUN_REG: %08x\n", *((volatile uint32_t *) LCD_RUN_REG) );
52-
printf( "LCD_RESET_REG: %08x\n", *((volatile uint32_t *) LCD_RESET_REG) );
198+
printf( "LCD_STATUS_REG: %04x\n", *((volatile uint16_t *) LCD_STATUS_REG) );
199+
printf( "LCD_INT_ENA_REG: %04x\n", *((volatile uint16_t *) LCD_INT_ENA_REG) );
200+
printf( "LCD_INT_STAT_REG: %04x\n", *((volatile uint16_t *) LCD_INT_STAT_REG) );
201+
printf( "LCD_RUN_REG: %04x\n", *((volatile uint16_t *) LCD_RUN_REG) );
202+
printf( "LCD_RESET_REG: %04x\n", *((volatile uint16_t *) LCD_RESET_REG) );
53203
printf( "LCD_PAR_DATA_WIDTH_REG: %08x\n", *((volatile uint32_t *) LCD_PAR_DATA_WIDTH_REG) );
54204
printf( "LCD_TEARING_CON_REG: %08x\n", *((volatile uint32_t *) LCD_TEARING_CON_REG) );
205+
printf( "LCD_AUTOCOPY_CTRL_REG: %08x\n", *((volatile uint32_t *) LCD_AUTOCOPY_CTRL_REG) );
206+
} else if( my_strncmp( subcmd, "run", 8 ) == 0 ) {
207+
// cause the interface to run
208+
*((volatile uint16_t *)LCD_RUN_REG) = 0;
209+
*((volatile uint16_t *)LCD_RUN_REG) = LCD_RUN_BIT;
210+
} else if( my_strncmp( subcmd, "stop", 8 ) == 0 ) {
211+
// cause the interface to stop
212+
*((volatile uint16_t *)LCD_RUN_REG) = 0;
213+
} else if( my_strncmp( subcmd, "init", 8 ) == 0 ) {
214+
*((volatile uint16_t *)LCD_RESET_REG) = 1;
215+
usleep(20000);
216+
*((volatile uint16_t *)LCD_RESET_REG) = 0; // turn on reset
217+
msleep(20);
218+
*((volatile uint16_t *)LCD_RESET_REG) = 1; // turn off reset
219+
msleep(150);
220+
221+
lcd_cmd(0x11); //Exit Sleep
222+
msleep(50); // Delay 50ms
223+
lcd_cmd(0xC0); //Power control
224+
lcd_dat(0x26);
225+
lcd_cmd(0xC1); //Power control
226+
lcd_dat(0x11); //SAP[2:0];BT[3:0]
227+
lcd_cmd(0xC5); //VCM control
228+
lcd_dat(0x35);
229+
lcd_dat(0x3E);
230+
lcd_cmd(0xc7);
231+
lcd_dat(0xbe);
232+
233+
lcd_cmd(0x36); // Memory Access Control
234+
lcd_dat(0x48);
235+
236+
lcd_cmd(0x3a); // pixel format set
237+
lcd_dat(0x55); // 16bpp
238+
239+
lcd_cmd(0xB1); // Frame Rate Control
240+
lcd_dat(0x00);
241+
lcd_dat(0x1b);
242+
243+
//--------------ddram ---------------------
244+
lcd_cmd(0x2a); // column set
245+
lcd_dat(0x00);
246+
lcd_dat(0x00);
247+
lcd_dat(0x00);
248+
lcd_dat(0xEF);
249+
lcd_cmd(0x2b); // page address set
250+
lcd_dat(0x00);
251+
lcd_dat(0x00);
252+
lcd_dat(0x01);
253+
lcd_dat(0x3F);
254+
lcd_cmd(0x34); // tearing effect off
255+
//lcd_cmd(0x35); // tearing effect on
256+
//lcd_cmd(0xb4); // display inversion
257+
//lcd_dat(0x00,0x00);
258+
lcd_cmd(0xb7); //entry mode set
259+
lcd_dat(0x07);
260+
//-----------------display---------------------
261+
lcd_cmd(0xb6); // display function control
262+
lcd_dat(0x0a);
263+
lcd_dat(0x82);
264+
lcd_dat(0x27);
265+
lcd_dat(0x00);
266+
lcd_cmd(0x11); //sleep out
267+
msleep(100);
268+
lcd_cmd(0x29); // display on
269+
msleep(100);
270+
lcd_cmd(0x2c); //memory write
271+
} else if( my_strncmp( subcmd, "tp1", 8 ) == 0 ) {
272+
lcd_cmd(0x2a); // column set
273+
lcd_dat(0x00);
274+
lcd_dat(0x00);
275+
lcd_dat(0x00);
276+
lcd_dat(0xEF);
277+
lcd_cmd(0x2b); // page address set
278+
lcd_dat(0x00);
279+
lcd_dat(0x00);
280+
lcd_dat(0x01);
281+
lcd_dat(0x3F);
282+
283+
lcd_cmd(0x2c); //memory write
284+
for( i = 0; i < 16384; i++ ) {
285+
lcd_dat((uint16_t) i);
286+
}
55287
} else {
56-
printf( "lcd commands: su (setup timing), dump (dump registers)\n" );
288+
printf( "lcd commands: su (setup timing), dump (dump registers), run, stop, init, tp1\n" );
57289
}
58290

59291
return 0;

include/fernvale-clockgate.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
// control set 0
88
#define CLKGATE_SYS_CTL0 (0xA0010000 + 0x0300)
9-
#define CLKGATE_SYS_CTL0_SET (0xA0010000 + 0x0310)
10-
#define CLKGATE_SYS_CTL0_CLR (0xA0010000 + 0x0320)
9+
#define CLKGATE_SYS_CTL0_SET (0xA0010000 + 0x0310) // turns the block off
10+
#define CLKGATE_SYS_CTL0_CLR (0xA0010000 + 0x0320) // turns the block on
1111

1212
#define CLKGATE_CTL0_LCD 0x0001
1313
#define CLKGATE_CTL0_RESIZER 0x0002

include/fernvale-lcd.h

+54-9
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,40 @@
2626
#define LCD_PAR_CFG_RD_TH_MASK (0xF0000000)
2727
#define LCD_PAR_CFG_RD_TH_BIT (28)
2828

29-
#define LCD_STATUS_REG (LCD_CTRL_ADDR + 0x0000)
29+
#define LCD_STATUS_REG (LCD_CTRL_ADDR + 0x0000) // 16-bit
3030
#define LCD_STATUS_RUN_BIT (0x1)
3131
#define LCD_STATUS_WAIT_CMDQ_BIT (0x2)
3232
#define LCD_STATUS_WAIT_HTT_BIT (0x8)
3333
#define LCD_STATUS_TE_PENDING_BIT (0x10)
3434
#define LCD_STATUS_BUSY_BIT (0x20)
3535
#define LCD_STATUS_GMC_REQ_BIT (0x40)
3636

37-
#define LCD_INT_ENA_REG (LCD_CTRL_ADDR + 0x0004)
37+
#define LCD_INT_ENA_REG (LCD_CTRL_ADDR + 0x0004) // 16-bit
3838
#define LCD_INT_ENA_TRIG_BIT (0x1)
3939
#define LCD_INT_ENA_REG_TRIG_BIT (0x2)
4040
#define LCD_INT_ENA_CMD_TRIG_BIT (0x4)
4141
#define LCD_INT_ENA_HTT_TRIG_BIT (0x10)
4242
#define LCD_INT_ENA_HSYNC_TRIG_BIT (0x20)
4343
#define LCD_INT_ENA_VSYNC_TRIG_BIT (0x20)
4444

45-
#define LCD_INT_STAT_REG (LCD_CTRL_ADDR + 0x0008)
45+
#define LCD_INT_STAT_REG (LCD_CTRL_ADDR + 0x0008) // 16-bit
4646
#define LCD_INT_STAT_DONE_BIT (0x1)
4747

48-
#define LCD_RUN_REG (LCD_CTRL_ADDR + 0x000C)
48+
#define LCD_RUN_REG (LCD_CTRL_ADDR + 0x000C) // 16-bit
4949
#define LCD_RUN_BIT (0x8000)
5050

51-
#define LCD_RESET_REG (LCD_CTRL_ADDR + 0x0010)
51+
#define LCD_RESET_REG (LCD_CTRL_ADDR + 0x0010) // 16-bit
5252
#define LCD_RESET_BIT (0x1) // check polarity
5353

5454
#define LCD_PAR_DATA_WIDTH_REG (LCD_CTRL_ADDR + 0x003C)
5555
#define LCD_PAR_BUS_WIDTH0_MASK (0x7)
5656
#define LCD_PAR_BUS_WIDTH0_BIT (0)
5757
#define LCD_PAR_BUS_WIDTH1_MASK (0x70)
5858
#define LCD_PAR_BUS_WIDTH1_BIT (4)
59-
#define LCD_PAR_WAIT0_MASK (0xF0000)
60-
#define LCD_PAR_WAIT0_BIT (16)
61-
#define LCD_PAR_WAIT1_MASK (0xF00000)
62-
#define LCD_PAR_WAIT1_BIT (20)
59+
#define LCD_PAR_W2W_WAIT0_MASK (0xF0000) // write 2 write delay
60+
#define LCD_PAR_W2W_WAIT0_BIT (16)
61+
#define LCD_PAR_W2W_WAIT1_MASK (0xF00000)
62+
#define LCD_PAR_W2W_WAIT1_BIT (20)
6363
#define LCD_PAR_BUS_WIDTH_8BIT (0) // valid values for LCD_PAR_BUS_WIDTHn
6464
#define LCD_PAR_BUS_WIDTH_9BIT (1)
6565
#define LCD_PAR_BUS_WIDTH_16BIT (2)
@@ -71,4 +71,49 @@
7171
#define LCD_TEARING_SYNCEDGE_BIT (0x2)
7272
#define LCD_TEARING_SW_FORCE_BIT (0x8000)
7373

74+
#define LCD_AUTOCOPY_CTRL_REG (LCD_CTRL_ADDR+0x0080)
75+
// should be:
76+
// 0 - BGR
77+
// 0 - significance (?)
78+
// 1 - padding on MSBs
79+
// 010 - RGB565 (100 for RGB888, 011 for RGB66)
80+
// 10 - 9-bit interface
81+
// 000000 - command (no commands now)
82+
// 0 -- disable W2M
83+
// 0 -- enable commands
84+
// 00000010 -- 2 cycle waiting period (may be ok to set 0 but for now set to 2)
85+
// 1 -- send residue mode, residue per frame
86+
// 0
87+
// 1 -- enable frame update counter. why not?
88+
// 0
89+
// 1000 -- enable layer 0 only
90+
// 1000 0101 0000 0010 1000 0000 1001 0100 = 0x85028094
91+
92+
#define LCD_AUTOCOPY_CTRL_SEND_RES_MOD_MASK 0x01000000
93+
#define LCD_AUTOCOPY_CTRL_PERIOD_MASK 0x00FF0000
94+
#define LCD_AUTOCOPY_CTRL_LAYER_MASK 0xF0000000
95+
#define LCD_AUTOCOPY_CTRL_CMD_ENABLE_BIT 0x00008000
96+
#define LCD_AUTOCOPY_CTRL_DATA_FORMAT_MASK 0x020000FF ///24 bit interface support
97+
98+
#define LCD_AUTOCOPY_CTRL_CMDQ_SEL_BIT 0
99+
#define LCD_AUTOCOPY_CTRL_CMD_NUMBER_MASK 0x00003F00
100+
101+
#define LCD_AUTOCOPY_OFFSET_REG (LCD_CTRL_ADDR+0x0084) // set to 0, uint 32
102+
#define LCD_AUTOCOPY_CMD_ADDR_REG (LCD_CTRL_ADDR+0x0088) // set to 0x4000, uint 16
103+
#define LCD_AUTOCOPY_DATA_ADDR_REG (LCD_CTRL_ADDR+0x008C) // set to 0x4100, uint 16
104+
#define LCD_AUTOCOPY_SIZE_REG (LCD_CTRL_ADDR+0x0090) // set to 0x014000F0, uint32 (320x240)
105+
#define LCD_AUTOCOPY_BG_COLOR_REG (LCD_CTRL_ADDR+0x009C) // set to 0x80008000 (slight greenish)
106+
107+
#define LCD_LAYER0_CTRL_REG (LCD_CTRL_ADDR+0x00B0) // set to 0x0
108+
#define LCD_LAYER0_SRC_KEY_REG (LCD_CTRL_ADDR+0x00B4)
109+
#define LCD_LAYER0_OFFSET_REG (LCD_CTRL_ADDR+0x00B8) // set to 0x0
110+
#define LCD_LAYER0_BUFF_ADDR_REG (LCD_CTRL_ADDR+0x00BC) // set to 0x0
111+
#define LCD_LAYER0_SIZE_REG (LCD_CTRL_ADDR+0x00C0) // set to 0x014000f0
112+
#define LCD_LAYER0_MEM_OFFSET_REG (LCD_CTRL_ADDR+0x00C8) // set to 0x0
113+
#define LCD_LAYER0_MEM_PITCH_REG (LCD_CTRL_ADDR+0x00CC) // set to 0x1e0
114+
115+
// there's 3 more layers, but I'm happy to just get one working for now...
116+
117+
#define LCD_CMD_LIST_ADDR (LCD_CTRL_ADDR + 0x0C00)
118+
74119
#endif /* __FV_LCD_H__ */

0 commit comments

Comments
 (0)