Mercurial > ~darius > hgwebdir.cgi > stm32test
comparison lcd.c @ 7:9404b9869c27
Make the LCD panel work (timings, GPIOE clock needs to be on, etc)
Factor out LCD init (needs more work)
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sun, 22 Jan 2012 17:10:51 +1030 |
parents | efa2c22266e3 |
children | 58d76cf522ff |
comparison
equal
deleted
inserted
replaced
6:2b92d9632999 | 7:9404b9869c27 |
---|---|
1 /* | 1 /* |
2 * Example code (I think) | 2 * Example code (I think) |
3 * ~/projects/STM32Strive/奋斗STM32开发板例程/奋斗STM32开发板例程/奋斗STM32开发板MINI/STM32奋斗版ucOS II V2.86 uCGUI 3.9 DEMO-V2/STM32奋斗版ucOS II V2.86 uCGUI 3.9 DEMO | 3 * ~/projects/STM32Strive/奋斗STM32开发板例程/奋斗STM32开发板例程/奋斗STM32开发板MINI/STM32奋斗版ucOS II V2.86 uCGUI 3.9 DEMO-V2/STM32奋斗版ucOS II V2.86 uCGUI 3.9 DEMO |
4 * | 4 * |
5 * Schematics | 5 * Schematics |
6 * Main board ~/Downloads/Strive\ Mini\ STM32\ Schematic.pdf | 6 * Main board docs/Strive\ Mini\ STM32\ Schematic.pdf |
7 * LCD board ~/Downloads/Strive Mini LCD STM32 Schematic.pdf | 7 * LCD board docs/Strive Mini LCD STM32 Schematic.pdf |
8 * MCU reference manual | 8 * MCU reference manual docs/CD00171190.pdf |
9 * ~/Downloads/CD00171190.pdf | 9 * MCU Data sheet (pinout) docs/CD00191185.pdf |
10 * MCU Data sheet (pinout) | 10 * LCD controller data sheet docs/ili9325-v0.35.pdf |
11 * ~/Downloads/CD00191185.pdf | 11 * LCD controller app notes docs/ILI9325AN_V0.22.pdf |
12 * LCD data sheet | 12 * XXX: not sure what panel is connected |
13 * | 13 * |
14 */ | 14 */ |
15 /* LCD board MCU | 15 /* LCD board MCU |
16 1 VCC | 16 1 VCC |
17 2 TC_SCK PA5/SPI1_SCK | 17 2 TC_SCK PA5/SPI1_SCK |
42 27 D2 PD0/FSMC_D2 | 42 27 D2 PD0/FSMC_D2 |
43 28 D10 PE13/FSMC_D10 | 43 28 D10 PE13/FSMC_D10 |
44 29 D1 PD15/FSMC_D1 | 44 29 D1 PD15/FSMC_D1 |
45 30 D9 PE12/FSMC_D9 | 45 30 D9 PE12/FSMC_D9 |
46 31 D0 PD14/FSMC_D0 | 46 31 D0 PD14/FSMC_D0 |
47 32 D14 PD9/FSMC_D9 | 47 32 D14 PD9/FSMC_D14 |
48 33 NC | 48 33 NC |
49 34 D8 PE11/FSMC_D8 | 49 34 D8 PE11/FSMC_D8 |
50 35 NC | 50 35 NC |
51 36 NC | 51 36 NC |
52 37 NC | 52 37 NC |
57 | 57 |
58 #include <stdio.h> | 58 #include <stdio.h> |
59 #include "stm32f10x.h" | 59 #include "stm32f10x.h" |
60 #include "lcd.h" | 60 #include "lcd.h" |
61 | 61 |
62 static void LCD_Doinit(void); | |
63 | |
62 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ | 64 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ |
63 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ | 65 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ |
64 | 66 |
65 void | 67 void |
66 LCD_WR_Reg(uint16_t index, uint16_t val) { | 68 LCD_WR_Reg(uint16_t index, uint16_t val) { |
83 | 85 |
84 return (a); | 86 return (a); |
85 } | 87 } |
86 | 88 |
87 void | 89 void |
90 LCD_WR_StartData(uint16_t x, uint16_t y) { | |
91 LCD_WR_Reg(0x20, x); | |
92 LCD_WR_Reg(0x21, y); | |
93 *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ | |
94 } | |
95 | |
96 void | |
88 LCD_WR_Data(uint16_t val) { | 97 LCD_WR_Data(uint16_t val) { |
89 *(__IO uint16_t *)(Bank1_LCD_D) = val; | 98 *(__IO uint16_t *)(Bank1_LCD_D) = val; |
90 } | 99 } |
91 | 100 |
92 /* Callers imply this is in milliseconds but that seems unlikely */ | 101 /* This is a bit rough and ready */ |
93 void | 102 void |
94 Delay(__IO uint32_t nCount) { | 103 Delay(__IO uint32_t nCount) { |
104 __IO uint32_t i; | |
105 | |
95 for(; nCount != 0; nCount--) | 106 for(; nCount != 0; nCount--) |
96 ; | 107 for (i = 0; i < 3900; i++) |
108 ; | |
97 } | 109 } |
98 | 110 |
99 uint8_t | 111 uint8_t |
100 SPI_WriteByte(uint8_t out) { | 112 SPI_WriteByte(uint8_t out) { |
101 uint8_t in = 0; | 113 uint8_t in = 0; |
219 GPIO_InitTypeDef GPIO_InitStructure; | 231 GPIO_InitTypeDef GPIO_InitStructure; |
220 SPI_InitTypeDef SPI_InitStructure; | 232 SPI_InitTypeDef SPI_InitStructure; |
221 FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; | 233 FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; |
222 FSMC_NORSRAMTimingInitTypeDef p; | 234 FSMC_NORSRAMTimingInitTypeDef p; |
223 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | 235 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; |
224 uint16_t id; | |
225 | 236 |
226 /* Enable FSMC clock */ | 237 /* Enable FSMC clock */ |
227 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); | 238 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); |
228 | 239 |
240 /* Enable alternate function IO clock */ | |
241 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); | |
242 | |
229 /* Enable GPIOD clock */ | 243 /* Enable GPIOD clock */ |
230 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); | 244 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); |
231 | 245 |
232 /* Enable alternate function IO clock */ | 246 /* Enable GPIOD clock */ |
233 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); | 247 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); |
234 | 248 |
235 /* Configures LCD Control lines (FSMC Pins) in alternate function Push-Pull mode. | 249 /* Configures LCD Control lines (FSMC Pins) in alternate function Push-Pull mode. |
236 * | 250 * |
237 * PD0(D2), PD1(D3), PD4(NOE), PD5(NWE), PD7(NE1/CS), PD8(D13), PD9(D14), | 251 * PD0(D2), PD1(D3), PD4(NOE), PD5(NWE), PD7(NE1/CS), PD8(D13), PD9(D14), |
238 * PD10(D15), PD11(A16/RS) PD14(D0), PD15(D1) | 252 * PD10(D15), PD11(A16/RS) PD14(D0), PD15(D1) |
239 */ | 253 */ |
240 GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | | 254 GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | |
241 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15); | 255 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | |
256 GPIO_Pin_14 | GPIO_Pin_15); | |
242 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | 257 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
243 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | 258 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
244 GPIO_Init(GPIOD, &GPIO_InitStructure); | 259 GPIO_Init(GPIOD, &GPIO_InitStructure); |
245 | 260 |
246 /* PE7(D4), PE8(D5), PE9(D6), PE10(D7), PE11(D8), PE12(D9), PE13(D10), | 261 /* PE7(D4), PE8(D5), PE9(D6), PE10(D7), PE11(D8), PE12(D9), PE13(D10), |
247 * PE14(D11), PE15(D12) | 262 * PE14(D11), PE15(D12) |
248 */ | 263 */ |
249 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | | 264 GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | |
250 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; | 265 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | |
266 GPIO_Pin_15); | |
251 GPIO_Init(GPIOE, &GPIO_InitStructure); | 267 GPIO_Init(GPIOE, &GPIO_InitStructure); |
252 | 268 |
253 /* Configure backlight control (PD13/FSMC_A18 remapped to TIM4_CH2) */ | 269 /* Configure backlight control (PD13/FSMC_A18 remapped to TIM4_CH2) */ |
254 /* Enable TIM4 clock */ | 270 /* Enable TIM4 clock */ |
255 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); | 271 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); |
289 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | 305 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
290 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; | 306 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; |
291 GPIO_Init(GPIOE, &GPIO_InitStructure); | 307 GPIO_Init(GPIOE, &GPIO_InitStructure); |
292 | 308 |
293 /* Configures the Parallel interface (FSMC) for LCD (Parallel mode) */ | 309 /* Configures the Parallel interface (FSMC) for LCD (Parallel mode) */ |
294 /* FSMC_Bank1_NORSRAM4 timing configuration */ | 310 /* Timing configuration */ |
295 p.FSMC_AddressSetupTime = 1; | 311 p.FSMC_AddressSetupTime = 5; |
296 p.FSMC_AddressHoldTime = 0; | 312 p.FSMC_AddressHoldTime = 5; |
297 p.FSMC_DataSetupTime = 2; | 313 p.FSMC_DataSetupTime = 5; |
298 p.FSMC_BusTurnAroundDuration = 0; | 314 p.FSMC_BusTurnAroundDuration = 0; |
299 p.FSMC_CLKDivision = 0; | 315 p.FSMC_CLKDivision = 0; |
300 p.FSMC_DataLatency = 0; | 316 p.FSMC_DataLatency = 0; |
301 p.FSMC_AccessMode = FSMC_AccessMode_A; | 317 p.FSMC_AccessMode = FSMC_AccessMode_A; |
302 | 318 |
303 /* FSMC_Bank1_NORSRAM4 configured as follows: | 319 /* FSMC_Bank1_NORSRAM1 configured as follows: |
304 - Data/Address MUX = Disable | 320 - Data/Address MUX = Disable |
305 - Memory Type = SRAM | 321 - Memory Type = SRAM |
306 - Data Width = 16bit | 322 - Data Width = 16bit |
307 - Write Operation = Enable | 323 - Write Operation = Enable |
308 - Extended Mode = Disable | 324 - Extended Mode = Disable |
309 - Asynchronous Wait = Disable */ | 325 - Asynchronous Wait = Disable */ |
310 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4; | 326 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; |
311 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; | 327 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; |
312 FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; | 328 FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; |
313 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; | 329 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; |
314 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; | 330 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; |
315 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; | 331 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; |
320 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; | 336 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; |
321 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; | 337 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; |
322 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; | 338 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; |
323 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; | 339 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; |
324 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; | 340 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; |
325 | |
326 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); | 341 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); |
327 | 342 |
328 /* Enable FSMC_Bank1_NORSRAM4 */ | 343 /* Enable FSMC_Bank1_NORSRAM1 */ |
329 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); | 344 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); |
330 | |
331 /* Initialise LCD panel */ | |
332 | |
333 /* Pull reset pin low */ | |
334 GPIO_ResetBits(GPIOE, GPIO_Pin_1); | |
335 Delay(0xafff); | |
336 GPIO_SetBits(GPIOE, GPIO_Pin_1); | |
337 Delay(0xafff); | |
338 | |
339 id = LCD_RD_Reg(0x00); | |
340 if (id != 0x9325) { | |
341 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); | |
342 return; | |
343 } | |
344 | |
345 LCD_WR_Reg(0x00e3, 0x3008); /* Set internal timing */ | |
346 LCD_WR_Reg(0x00e7, 0x0012); /* Set internal timing */ | |
347 LCD_WR_Reg(0x00ef, 0x1231); /* Set internal timing */ | |
348 LCD_WR_Reg(0x0000, 0x0001); /* Start Oscillation */ | |
349 LCD_WR_Reg(0x0001, 0x0100); /* set SS and SM bit */ | |
350 LCD_WR_Reg(0x0002, 0x0700); /* set 1 line inversion */ | |
351 | |
352 LCD_WR_Reg(0x0003, 0x1030); /* set GRAM write direction and BGR = 0, 262K colours, 1 transfers/pixel. */ | |
353 LCD_WR_Reg(0x0004, 0x0000); /* Resize register */ | |
354 LCD_WR_Reg(0x0008, 0x0202); /* set the back porch and front porch */ | |
355 LCD_WR_Reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ | |
356 LCD_WR_Reg(0x000a, 0x0000); /* FMARK function */ | |
357 LCD_WR_Reg(0x000c, 0x0000); /* RGB interface setting */ | |
358 LCD_WR_Reg(0x000d, 0x0000); /* Frame marker Position */ | |
359 LCD_WR_Reg(0x000f, 0x0000); /* RGB interface polarity */ | |
360 | |
361 /* Power On sequence */ | |
362 LCD_WR_Reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | |
363 LCD_WR_Reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ | |
364 LCD_WR_Reg(0x0012, 0x0000); /* VREG1OUT voltage */ | |
365 LCD_WR_Reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ | |
366 Delay(200); /* Dis-charge capacitor power voltage */ | |
367 LCD_WR_Reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | |
368 LCD_WR_Reg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ | |
369 Delay(50); /* Delay 50ms */ | |
370 LCD_WR_Reg(0x0012, 0x001c); /* External reference voltage= Vci; */ | |
371 Delay(50); /* Delay 50ms */ | |
372 LCD_WR_Reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ | |
373 LCD_WR_Reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ | |
374 LCD_WR_Reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ | |
375 Delay(50); /* Delay 50ms */ | |
376 LCD_WR_Reg(0x0020, 0x0000); /* GRAM horizontal Address */ | |
377 LCD_WR_Reg(0x0021, 0x0000); /* GRAM Vertical Address */ | |
378 | |
379 /* Adjust the Gamma Curve */ | |
380 LCD_WR_Reg(0x0030, 0x0007); | |
381 LCD_WR_Reg(0x0031, 0x0302); | |
382 LCD_WR_Reg(0x0032, 0x0105); | |
383 LCD_WR_Reg(0x0035, 0x0206); | |
384 LCD_WR_Reg(0x0036, 0x0808); | |
385 LCD_WR_Reg(0x0037, 0x0206); | |
386 LCD_WR_Reg(0x0038, 0x0504); | |
387 LCD_WR_Reg(0x0039, 0x0007); | |
388 LCD_WR_Reg(0x003c, 0x0105); | |
389 LCD_WR_Reg(0x003d, 0x0808); | |
390 | |
391 /* Set GRAM area */ | |
392 LCD_WR_Reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ | |
393 LCD_WR_Reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ | |
394 LCD_WR_Reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ | |
395 LCD_WR_Reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ | |
396 LCD_WR_Reg(0x0060, 0xa700); /* Gate Scan Line */ | |
397 LCD_WR_Reg(0x0061, 0x0001); /* NDL,VLE, REV */ | |
398 LCD_WR_Reg(0x006a, 0x0000); /* set scrolling line */ | |
399 | |
400 /* Partial Display Control */ | |
401 LCD_WR_Reg(0x0080, 0x0000); | |
402 LCD_WR_Reg(0x0081, 0x0000); | |
403 LCD_WR_Reg(0x0082, 0x0000); | |
404 LCD_WR_Reg(0x0083, 0x0000); | |
405 LCD_WR_Reg(0x0084, 0x0000); | |
406 LCD_WR_Reg(0x0085, 0x0000); | |
407 | |
408 /* Panel Control */ | |
409 LCD_WR_Reg(0x0090, 0x0010); | |
410 LCD_WR_Reg(0x0092, 0x0000); | |
411 LCD_WR_Reg(0x0093, 0x0003); | |
412 LCD_WR_Reg(0x0095, 0x0110); | |
413 LCD_WR_Reg(0x0097, 0x0000); | |
414 LCD_WR_Reg(0x0098, 0x0000); | |
415 LCD_WR_Reg(0x0007, 0x0133); /* 262K colour and display ON */ | |
416 | |
417 /* Fill panel with white */ | |
418 LCD_WR_Reg(0x20, 0); | |
419 LCD_WR_Reg(0x21, 0x013f); | |
420 *(__IO uint16_t *)(Bank1_LCD_C) = 34; | |
421 for (uint32_t i = 0; i < 320 * 240; i++) { | |
422 LCD_WR_Data(0xffff); | |
423 } | |
424 | 345 |
425 /* Configure touch screen controller | 346 /* Configure touch screen controller |
426 * | 347 * |
427 * Connected to SPI1 which is shared with the AT45DB161D. | 348 * Connected to SPI1 which is shared with the AT45DB161D. |
428 * | 349 * |
468 SPI_Init(SPI1, &SPI_InitStructure); | 389 SPI_Init(SPI1, &SPI_InitStructure); |
469 | 390 |
470 /* SPI1 enable */ | 391 /* SPI1 enable */ |
471 SPI_Cmd(SPI1, ENABLE); | 392 SPI_Cmd(SPI1, ENABLE); |
472 | 393 |
394 LCD_Doinit(); | |
473 } | 395 } |
474 | 396 |
475 void | 397 void |
476 lcd_setpwm(uint16_t val) { | 398 lcd_setpwm(uint16_t val) { |
477 TIM_OCInitTypeDef TIM_OCInitStructure; | 399 TIM_OCInitTypeDef TIM_OCInitStructure; |
483 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; | 405 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; |
484 | 406 |
485 TIM_OC2Init(TIM4, &TIM_OCInitStructure); | 407 TIM_OC2Init(TIM4, &TIM_OCInitStructure); |
486 | 408 |
487 } | 409 } |
410 | |
411 static void | |
412 LCD_Doinit(void) { | |
413 uint16_t id; | |
414 | |
415 /* Initialise LCD panel */ | |
416 | |
417 /* Pull reset pin low */ | |
418 Delay(1); | |
419 GPIO_ResetBits(GPIOE, GPIO_Pin_1); | |
420 Delay(10); | |
421 GPIO_SetBits(GPIOE, GPIO_Pin_1); | |
422 Delay(50); | |
423 | |
424 id = LCD_RD_Reg(0x00); | |
425 if (id != 0x9325) { | |
426 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); | |
427 return; | |
428 } | |
429 printf("LCD ID matches\r\n"); | |
430 | |
431 LCD_WR_Reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ | |
432 LCD_WR_Reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ | |
433 LCD_WR_Reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ | |
434 LCD_WR_Reg(0x0000, 0x0001); /* Start Oscillation */ | |
435 Delay(50); | |
436 LCD_WR_Reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ | |
437 LCD_WR_Reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ | |
438 LCD_WR_Reg(0x0004, 0x0000); /* no resizing */ | |
439 LCD_WR_Reg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ | |
440 LCD_WR_Reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ | |
441 LCD_WR_Reg(0x000a, 0x0000); /* FMARK function */ | |
442 | |
443 LCD_WR_Reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ | |
444 LCD_WR_Reg(0x000d, 0x0000); /* Frame marker Position */ | |
445 LCD_WR_Reg(0x000f, 0x0000); /* RGB interface polarity */ | |
446 | |
447 /* Power On sequence */ | |
448 LCD_WR_Reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | |
449 LCD_WR_Reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ | |
450 LCD_WR_Reg(0x0012, 0x0000); /* VREG1OUT voltage */ | |
451 LCD_WR_Reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ | |
452 Delay(200); /* Dis-charge capacitor power voltage */ | |
453 LCD_WR_Reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | |
454 LCD_WR_Reg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ | |
455 Delay(50); /* Delay 50ms */ | |
456 LCD_WR_Reg(0x0012, 0x001c); /* External reference voltage= Vci; */ | |
457 Delay(50); /* Delay 50ms */ | |
458 LCD_WR_Reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ | |
459 LCD_WR_Reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ | |
460 LCD_WR_Reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ | |
461 Delay(50); /* Delay 50ms */ | |
462 | |
463 /* Set GRAM area */ | |
464 LCD_WR_Reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ | |
465 LCD_WR_Reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ | |
466 LCD_WR_Reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ | |
467 LCD_WR_Reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ | |
468 | |
469 LCD_WR_Reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ | |
470 LCD_WR_Reg(0x0061, 0x0003); /* VLE & REV */ | |
471 LCD_WR_Reg(0x006a, 0x0000); /* set scrolling line */ | |
472 | |
473 /* Partial Display Control */ | |
474 LCD_WR_Reg(0x0080, 0x0000); /* Image 1 */ | |
475 LCD_WR_Reg(0x0081, 0x0000); | |
476 LCD_WR_Reg(0x0082, 0x0000); | |
477 LCD_WR_Reg(0x0083, 0x0000); /* Image 2 */ | |
478 LCD_WR_Reg(0x0084, 0x0000); | |
479 LCD_WR_Reg(0x0085, 0x0000); | |
480 | |
481 /* Panel Control */ | |
482 LCD_WR_Reg(0x0090, 0x0010); | |
483 LCD_WR_Reg(0x0092, 0x0000); | |
484 LCD_WR_Reg(0x0093, 0x0003); | |
485 LCD_WR_Reg(0x0095, 0x0110); | |
486 LCD_WR_Reg(0x0097, 0x0000); /* Undocumented */ | |
487 LCD_WR_Reg(0x0098, 0x0000); /* Undocumented */ | |
488 | |
489 LCD_WR_Reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ | |
490 | |
491 LCD_WR_Reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ | |
492 | |
493 /* Adjust the Gamma Curve */ | |
494 LCD_WR_Reg(0x0030, 0x0006); | |
495 LCD_WR_Reg(0x0031, 0x0101); | |
496 LCD_WR_Reg(0x0032, 0x0003); | |
497 LCD_WR_Reg(0x0035, 0x0106); | |
498 LCD_WR_Reg(0x0036, 0x0b02); | |
499 LCD_WR_Reg(0x0037, 0x0302); | |
500 LCD_WR_Reg(0x0038, 0x0707); | |
501 LCD_WR_Reg(0x0039, 0x0007); | |
502 LCD_WR_Reg(0x003c, 0x0600); | |
503 LCD_WR_Reg(0x003d, 0x020b); | |
504 | |
505 fputs("Testing\r\n", stdout); | |
506 LCD_WR_StartData(0, 0); | |
507 LCD_WR_Data(0xa5a5); | |
508 LCD_WR_Data(0x5a5a); | |
509 LCD_WR_StartData(0, 0); | |
510 if ((id = LCD_RD_Data(1)) != 0xa5a5) | |
511 printf("Expected 0xa5a5 got 0x%04x\r\n", id); | |
512 | |
513 if ((id = LCD_RD_Data(0)) != 0x5a5a) | |
514 printf("Expected 0x5a5a got 0x%04x\r\n", id); | |
515 | |
516 fputs("Filling\r\n", stdout); | |
517 /* Fill panel */ | |
518 LCD_WR_StartData(0, 0); | |
519 | |
520 #define RGB24_565(R, G, B) (((((R) >> 3) & 0x1f) << 11) | ((((G) >> 2) & 0x3f) << 5) | (((B) >> 3) & 0x1f)) | |
521 | |
522 for (int x = 0; x < 320; x++) { | |
523 for (int y = 0; y < 240; y++) { | |
524 if (((x / 5) % 3) == 0) | |
525 LCD_WR_Data(RGB24_565(255, 0, 0)); | |
526 else if (((x / 5) % 3) == 1) | |
527 LCD_WR_Data(RGB24_565(0, 255, 0)); | |
528 else | |
529 LCD_WR_Data(RGB24_565(0, 0, 255)); | |
530 } | |
531 } | |
532 | |
533 } | |
534 |