Mercurial > ~darius > hgwebdir.cgi > stm32test
comparison lcd.c @ 8:58d76cf522ff
Split out code into separate files.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 04 Feb 2012 13:29:31 +1030 |
parents | 9404b9869c27 |
children | be0a1ac64d97 |
comparison
equal
deleted
inserted
replaced
7:9404b9869c27 | 8:58d76cf522ff |
---|---|
54 39 NC | 54 39 NC |
55 40 D15 PD10/FSMC_D15 | 55 40 D15 PD10/FSMC_D15 |
56 */ | 56 */ |
57 | 57 |
58 #include <stdio.h> | 58 #include <stdio.h> |
59 #include <stdint.h> | |
59 #include "stm32f10x.h" | 60 #include "stm32f10x.h" |
60 #include "lcd.h" | 61 #include "lcd.h" |
61 | 62 #include "delay.h" |
62 static void LCD_Doinit(void); | |
63 | 63 |
64 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ | 64 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ |
65 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ | 65 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ |
66 | 66 |
67 void | 67 void |
68 LCD_WR_Reg(uint16_t index, uint16_t val) { | 68 lcd_wr_reg(uint16_t index, uint16_t val) { |
69 *(__IO uint16_t *)(Bank1_LCD_C) = index; | 69 *(__IO uint16_t *)(Bank1_LCD_C) = index; |
70 *(__IO uint16_t *)(Bank1_LCD_D) = val; | 70 *(__IO uint16_t *)(Bank1_LCD_D) = val; |
71 } | 71 } |
72 | 72 |
73 uint16_t | 73 uint16_t |
74 LCD_RD_Reg(uint16_t index) { | 74 lcd_rd_reg(uint16_t index) { |
75 *(__IO uint16_t *)(Bank1_LCD_C) = index; | 75 *(__IO uint16_t *)(Bank1_LCD_C) = index; |
76 return(*(__IO uint16_t *)(Bank1_LCD_D)); | 76 return(*(__IO uint16_t *)(Bank1_LCD_D)); |
77 } | 77 } |
78 | 78 |
79 uint16_t | 79 uint16_t |
80 LCD_RD_Data(int first) { | 80 lcd_rd_data(int first) { |
81 uint16_t a = 0; | 81 uint16_t a = 0; |
82 if (first) | 82 if (first) |
83 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Dummy */ | 83 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Dummy */ |
84 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Read */ | 84 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Read */ |
85 | 85 |
86 return (a); | 86 return (a); |
87 } | 87 } |
88 | 88 |
89 void | 89 void |
90 LCD_WR_StartData(uint16_t x, uint16_t y) { | 90 lcd_wr_startdata(uint16_t x, uint16_t y) { |
91 LCD_WR_Reg(0x20, x); | 91 lcd_wr_reg(0x20, x); |
92 LCD_WR_Reg(0x21, y); | 92 lcd_wr_reg(0x21, y); |
93 *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ | 93 *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ |
94 } | 94 } |
95 | 95 |
96 void | 96 void |
97 LCD_WR_Data(uint16_t val) { | 97 lcd_wr_data(uint16_t val) { |
98 *(__IO uint16_t *)(Bank1_LCD_D) = val; | 98 *(__IO uint16_t *)(Bank1_LCD_D) = val; |
99 } | |
100 | |
101 /* This is a bit rough and ready */ | |
102 void | |
103 Delay(__IO uint32_t nCount) { | |
104 __IO uint32_t i; | |
105 | |
106 for(; nCount != 0; nCount--) | |
107 for (i = 0; i < 3900; i++) | |
108 ; | |
109 } | |
110 | |
111 uint8_t | |
112 SPI_WriteByte(uint8_t out) { | |
113 uint8_t in = 0; | |
114 | |
115 /* Wait until the transmit buffer is empty */ | |
116 while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET) | |
117 ; | |
118 | |
119 /* Send the byte */ | |
120 SPI_I2S_SendData(SPI1, out); | |
121 | |
122 /* Wait until a data is received */ | |
123 while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) | |
124 ; | |
125 | |
126 /* Get the received data */ | |
127 in = SPI_I2S_ReceiveData(SPI1); | |
128 | |
129 /* Return the shifted data */ | |
130 return (in); | |
131 } | |
132 | |
133 #define TP_SELECT() GPIO_ResetBits(GPIOB, GPIO_Pin_7) | |
134 #define TP_DESELECT() GPIO_SetBits(GPIOB, GPIO_Pin_7) | |
135 uint16_t | |
136 TPRead(uint8_t type) { | |
137 uint16_t x = 0; | |
138 | |
139 /* Select device */ | |
140 TP_SELECT(); | |
141 | |
142 /* Do conversion */ | |
143 Delay(10); | |
144 SPI_WriteByte(type); | |
145 | |
146 /* Read result */ | |
147 Delay(10); | |
148 x = SPI_WriteByte(0x00); | |
149 x <<= 8; | |
150 x |= SPI_WriteByte(0x00); | |
151 Delay(10); | |
152 | |
153 /* De-select device */ | |
154 TP_DESELECT(); | |
155 | |
156 /* Right justify 12 bit result */ | |
157 x = x >> 3; | |
158 return (x); | |
159 } | |
160 | |
161 #define FL_SELECT() GPIO_ResetBits(GPIOA, GPIO_Pin_4) | |
162 #define FL_DESELECT() GPIO_SetBits(GPIOA, GPIO_Pin_4) | |
163 | |
164 #define FL_READ 0x03 | |
165 #define FL_HSREAD 0x0b | |
166 #define FL_32KERASE 0x52 | |
167 #define FL_64KERASE 0xd8 | |
168 #define FL_CHIPERASE 0x60 | |
169 #define FL_BYTEPROG 0x02 | |
170 #define FL_AAIWP 0xad | |
171 #define FL_RDSR 0x05 | |
172 #define FL_EWSR 0x50 | |
173 #define FL_WRSR 0x01 | |
174 #define FL_WREN 0x06 | |
175 #define FL_WRDI 0x04 | |
176 #define FL_RDID 0x90 | |
177 #define FL_JEDECID 0x9f | |
178 #define FL_EBSY 0x70 | |
179 #define FL_DBSY 0x80 | |
180 | |
181 uint16_t | |
182 FlashReadID(void) { | |
183 uint8_t fac, dev; | |
184 | |
185 FL_SELECT(); /* Select device */ | |
186 | |
187 SPI_WriteByte(FL_RDID); /* Send command */ | |
188 SPI_WriteByte(0x00); /* Send address cycles (ID data starts at 0) */ | |
189 SPI_WriteByte(0x00); | |
190 SPI_WriteByte(0x00); | |
191 fac = SPI_WriteByte(0x00); /* Read ID */ | |
192 dev = SPI_WriteByte(0x00); | |
193 | |
194 FL_DESELECT(); /* De-select device */ | |
195 | |
196 return fac << 8 | dev; | |
197 } | |
198 | |
199 uint8_t | |
200 FlashReadStatus(void) { | |
201 uint8_t status; | |
202 | |
203 FL_SELECT(); /* Select device */ | |
204 | |
205 SPI_WriteByte(FL_RDSR); /* Send command */ | |
206 SPI_WriteByte(0x00); /* Send dummy byte for address cycle */ | |
207 status = SPI_WriteByte(0x00); /* Read status */ | |
208 | |
209 FL_DESELECT(); /* De-select device */ | |
210 | |
211 return status; | |
212 } | |
213 | |
214 void | |
215 FlashWriteStatus(uint8_t status) { | |
216 /* Enable status write */ | |
217 FL_SELECT(); /* Select device */ | |
218 SPI_WriteByte(FL_EWSR); /* Send command */ | |
219 SPI_WriteByte(0x00); /* Send data byte */ | |
220 FL_DESELECT(); | |
221 | |
222 /* Actually write status */ | |
223 FL_SELECT(); /* Re-select device for new command */ | |
224 SPI_WriteByte(FL_WRSR); /* Send command */ | |
225 SPI_WriteByte(status); /* Send data byte */ | |
226 FL_DESELECT(); /* De-select device */ | |
227 } | |
228 | |
229 void | |
230 LCD_init(void) { | |
231 GPIO_InitTypeDef GPIO_InitStructure; | |
232 SPI_InitTypeDef SPI_InitStructure; | |
233 FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; | |
234 FSMC_NORSRAMTimingInitTypeDef p; | |
235 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
236 | |
237 /* Enable FSMC clock */ | |
238 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); | |
239 | |
240 /* Enable alternate function IO clock */ | |
241 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); | |
242 | |
243 /* Enable GPIOD clock */ | |
244 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); | |
245 | |
246 /* Enable GPIOD clock */ | |
247 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); | |
248 | |
249 /* Configures LCD Control lines (FSMC Pins) in alternate function Push-Pull mode. | |
250 * | |
251 * PD0(D2), PD1(D3), PD4(NOE), PD5(NWE), PD7(NE1/CS), PD8(D13), PD9(D14), | |
252 * PD10(D15), PD11(A16/RS) PD14(D0), PD15(D1) | |
253 */ | |
254 GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | | |
255 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | | |
256 GPIO_Pin_14 | GPIO_Pin_15); | |
257 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
258 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | |
259 GPIO_Init(GPIOD, &GPIO_InitStructure); | |
260 | |
261 /* PE7(D4), PE8(D5), PE9(D6), PE10(D7), PE11(D8), PE12(D9), PE13(D10), | |
262 * PE14(D11), PE15(D12) | |
263 */ | |
264 GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | | |
265 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | | |
266 GPIO_Pin_15); | |
267 GPIO_Init(GPIOE, &GPIO_InitStructure); | |
268 | |
269 /* Configure backlight control (PD13/FSMC_A18 remapped to TIM4_CH2) */ | |
270 /* Enable TIM4 clock */ | |
271 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); | |
272 | |
273 /* Enable timer function | |
274 * Note source clock is SYSCLK / 2 = 36MHz | |
275 */ | |
276 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; | |
277 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
278 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | |
279 GPIO_Init(GPIOD, &GPIO_InitStructure); | |
280 | |
281 /* Remap TIM4_CH2 to PD13 */ | |
282 GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); | |
283 | |
284 /* Reset TIM4 */ | |
285 TIM_DeInit(TIM4); | |
286 | |
287 /* Time Base configuration */ | |
288 TIM_TimeBaseStructure.TIM_Period = 999; | |
289 TIM_TimeBaseStructure.TIM_Prescaler = 0; | |
290 TIM_TimeBaseStructure.TIM_ClockDivision = 0; | |
291 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; | |
292 | |
293 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); | |
294 | |
295 /* Init to full brightness */ | |
296 lcd_setpwm(1000); | |
297 | |
298 /* Enable timer */ | |
299 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); | |
300 TIM_ARRPreloadConfig(TIM4, ENABLE); | |
301 TIM_Cmd(TIM4, ENABLE); | |
302 | |
303 /* Configure reset pin (PE1) as GPIO out PP */ | |
304 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; | |
305 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
306 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; | |
307 GPIO_Init(GPIOE, &GPIO_InitStructure); | |
308 | |
309 /* Configures the Parallel interface (FSMC) for LCD (Parallel mode) */ | |
310 /* Timing configuration */ | |
311 p.FSMC_AddressSetupTime = 5; | |
312 p.FSMC_AddressHoldTime = 5; | |
313 p.FSMC_DataSetupTime = 5; | |
314 p.FSMC_BusTurnAroundDuration = 0; | |
315 p.FSMC_CLKDivision = 0; | |
316 p.FSMC_DataLatency = 0; | |
317 p.FSMC_AccessMode = FSMC_AccessMode_A; | |
318 | |
319 /* FSMC_Bank1_NORSRAM1 configured as follows: | |
320 - Data/Address MUX = Disable | |
321 - Memory Type = SRAM | |
322 - Data Width = 16bit | |
323 - Write Operation = Enable | |
324 - Extended Mode = Disable | |
325 - Asynchronous Wait = Disable */ | |
326 FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; | |
327 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; | |
328 FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; | |
329 FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; | |
330 FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; | |
331 FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; | |
332 FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; | |
333 FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; | |
334 FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; | |
335 FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; | |
336 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; | |
337 FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; | |
338 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; | |
339 FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; | |
340 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; | |
341 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); | |
342 | |
343 /* Enable FSMC_Bank1_NORSRAM1 */ | |
344 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); | |
345 | |
346 /* Configure touch screen controller | |
347 * | |
348 * Connected to SPI1 which is shared with the AT45DB161D. | |
349 * | |
350 * The touch screen is selected with PB7. | |
351 * The flash chip is selected with PA4. | |
352 */ | |
353 | |
354 /* Enable SPI1 clock */ | |
355 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); | |
356 | |
357 /* Configure MOSI, MISO and SCLK as alternate function PP */ | |
358 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; | |
359 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
360 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | |
361 GPIO_Init(GPIOA, &GPIO_InitStructure); | |
362 | |
363 /* Configure flash chip select pin (PA4) as GPIO out PP */ | |
364 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; | |
365 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
366 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; | |
367 GPIO_Init(GPIOA, &GPIO_InitStructure); | |
368 | |
369 /* Configure touch chip select pin (PB7) as GPIO out PP */ | |
370 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; | |
371 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
372 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; | |
373 GPIO_Init(GPIOB, &GPIO_InitStructure); | |
374 | |
375 /* De-select touch & flash */ | |
376 GPIO_SetBits(GPIOA, GPIO_Pin_4); | |
377 GPIO_SetBits(GPIOB, GPIO_Pin_7); | |
378 | |
379 /* SPI1 Config */ | |
380 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; | |
381 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; | |
382 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; | |
383 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; | |
384 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; | |
385 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; | |
386 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; | |
387 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; | |
388 SPI_InitStructure.SPI_CRCPolynomial = 7; | |
389 SPI_Init(SPI1, &SPI_InitStructure); | |
390 | |
391 /* SPI1 enable */ | |
392 SPI_Cmd(SPI1, ENABLE); | |
393 | |
394 LCD_Doinit(); | |
395 } | 99 } |
396 | 100 |
397 void | 101 void |
398 lcd_setpwm(uint16_t val) { | 102 lcd_setpwm(uint16_t val) { |
399 TIM_OCInitTypeDef TIM_OCInitStructure; | 103 TIM_OCInitTypeDef TIM_OCInitStructure; |
406 | 110 |
407 TIM_OC2Init(TIM4, &TIM_OCInitStructure); | 111 TIM_OC2Init(TIM4, &TIM_OCInitStructure); |
408 | 112 |
409 } | 113 } |
410 | 114 |
411 static void | 115 void |
412 LCD_Doinit(void) { | 116 lcd_init(void) { |
413 uint16_t id; | 117 uint16_t id; |
414 | 118 |
415 /* Initialise LCD panel */ | 119 /* Initialise LCD panel */ |
416 | 120 |
417 /* Pull reset pin low */ | 121 /* Pull reset pin low */ |
418 Delay(1); | 122 delay(1); |
419 GPIO_ResetBits(GPIOE, GPIO_Pin_1); | 123 GPIO_ResetBits(GPIOE, GPIO_Pin_1); |
420 Delay(10); | 124 delay(10); |
421 GPIO_SetBits(GPIOE, GPIO_Pin_1); | 125 GPIO_SetBits(GPIOE, GPIO_Pin_1); |
422 Delay(50); | 126 delay(50); |
423 | 127 |
424 id = LCD_RD_Reg(0x00); | 128 id = lcd_rd_reg(0x00); |
425 if (id != 0x9325) { | 129 if (id != 0x9325) { |
426 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); | 130 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); |
427 return; | 131 return; |
428 } | 132 } |
429 printf("LCD ID matches\r\n"); | 133 printf("LCD ID matches\r\n"); |
430 | 134 |
431 LCD_WR_Reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ | 135 lcd_wr_reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ |
432 LCD_WR_Reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ | 136 lcd_wr_reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ |
433 LCD_WR_Reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ | 137 lcd_wr_reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ |
434 LCD_WR_Reg(0x0000, 0x0001); /* Start Oscillation */ | 138 lcd_wr_reg(0x0000, 0x0001); /* Start Oscillation */ |
435 Delay(50); | 139 delay(50); |
436 LCD_WR_Reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ | 140 lcd_wr_reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ |
437 LCD_WR_Reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ | 141 lcd_wr_reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ |
438 LCD_WR_Reg(0x0004, 0x0000); /* no resizing */ | 142 lcd_wr_reg(0x0004, 0x0000); /* no resizing */ |
439 LCD_WR_Reg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ | 143 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] */ | 144 lcd_wr_reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ |
441 LCD_WR_Reg(0x000a, 0x0000); /* FMARK function */ | 145 lcd_wr_reg(0x000a, 0x0000); /* FMARK function */ |
442 | 146 |
443 LCD_WR_Reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ | 147 lcd_wr_reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ |
444 LCD_WR_Reg(0x000d, 0x0000); /* Frame marker Position */ | 148 lcd_wr_reg(0x000d, 0x0000); /* Frame marker Position */ |
445 LCD_WR_Reg(0x000f, 0x0000); /* RGB interface polarity */ | 149 lcd_wr_reg(0x000f, 0x0000); /* RGB interface polarity */ |
446 | 150 |
447 /* Power On sequence */ | 151 /* Power On sequence */ |
448 LCD_WR_Reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | 152 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] */ | 153 lcd_wr_reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ |
450 LCD_WR_Reg(0x0012, 0x0000); /* VREG1OUT voltage */ | 154 lcd_wr_reg(0x0012, 0x0000); /* VREG1OUT voltage */ |
451 LCD_WR_Reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ | 155 lcd_wr_reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ |
452 Delay(200); /* Dis-charge capacitor power voltage */ | 156 delay(200); /* Dis-charge capacitor power voltage */ |
453 LCD_WR_Reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | 157 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] */ | 158 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 */ | 159 delay(50); /* delay 50ms */ |
456 LCD_WR_Reg(0x0012, 0x001c); /* External reference voltage= Vci; */ | 160 lcd_wr_reg(0x0012, 0x001c); /* External reference voltage= Vci; */ |
457 Delay(50); /* Delay 50ms */ | 161 delay(50); /* delay 50ms */ |
458 LCD_WR_Reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ | 162 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 */ | 163 lcd_wr_reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ |
460 LCD_WR_Reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ | 164 lcd_wr_reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ |
461 Delay(50); /* Delay 50ms */ | 165 delay(50); /* delay 50ms */ |
462 | 166 |
463 /* Set GRAM area */ | 167 /* Set GRAM area */ |
464 LCD_WR_Reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ | 168 lcd_wr_reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ |
465 LCD_WR_Reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ | 169 lcd_wr_reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ |
466 LCD_WR_Reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ | 170 lcd_wr_reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ |
467 LCD_WR_Reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ | 171 lcd_wr_reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ |
468 | 172 |
469 LCD_WR_Reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ | 173 lcd_wr_reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ |
470 LCD_WR_Reg(0x0061, 0x0003); /* VLE & REV */ | 174 lcd_wr_reg(0x0061, 0x0003); /* VLE & REV */ |
471 LCD_WR_Reg(0x006a, 0x0000); /* set scrolling line */ | 175 lcd_wr_reg(0x006a, 0x0000); /* set scrolling line */ |
472 | 176 |
473 /* Partial Display Control */ | 177 /* Partial Display Control */ |
474 LCD_WR_Reg(0x0080, 0x0000); /* Image 1 */ | 178 lcd_wr_reg(0x0080, 0x0000); /* Image 1 */ |
475 LCD_WR_Reg(0x0081, 0x0000); | 179 lcd_wr_reg(0x0081, 0x0000); |
476 LCD_WR_Reg(0x0082, 0x0000); | 180 lcd_wr_reg(0x0082, 0x0000); |
477 LCD_WR_Reg(0x0083, 0x0000); /* Image 2 */ | 181 lcd_wr_reg(0x0083, 0x0000); /* Image 2 */ |
478 LCD_WR_Reg(0x0084, 0x0000); | 182 lcd_wr_reg(0x0084, 0x0000); |
479 LCD_WR_Reg(0x0085, 0x0000); | 183 lcd_wr_reg(0x0085, 0x0000); |
480 | 184 |
481 /* Panel Control */ | 185 /* Panel Control */ |
482 LCD_WR_Reg(0x0090, 0x0010); | 186 lcd_wr_reg(0x0090, 0x0010); |
483 LCD_WR_Reg(0x0092, 0x0000); | 187 lcd_wr_reg(0x0092, 0x0000); |
484 LCD_WR_Reg(0x0093, 0x0003); | 188 lcd_wr_reg(0x0093, 0x0003); |
485 LCD_WR_Reg(0x0095, 0x0110); | 189 lcd_wr_reg(0x0095, 0x0110); |
486 LCD_WR_Reg(0x0097, 0x0000); /* Undocumented */ | 190 lcd_wr_reg(0x0097, 0x0000); /* Undocumented */ |
487 LCD_WR_Reg(0x0098, 0x0000); /* Undocumented */ | 191 lcd_wr_reg(0x0098, 0x0000); /* Undocumented */ |
488 | 192 |
489 LCD_WR_Reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ | 193 lcd_wr_reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ |
490 | 194 |
491 LCD_WR_Reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ | 195 lcd_wr_reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ |
492 | 196 |
493 /* Adjust the Gamma Curve */ | 197 /* Adjust the Gamma Curve */ |
494 LCD_WR_Reg(0x0030, 0x0006); | 198 lcd_wr_reg(0x0030, 0x0006); |
495 LCD_WR_Reg(0x0031, 0x0101); | 199 lcd_wr_reg(0x0031, 0x0101); |
496 LCD_WR_Reg(0x0032, 0x0003); | 200 lcd_wr_reg(0x0032, 0x0003); |
497 LCD_WR_Reg(0x0035, 0x0106); | 201 lcd_wr_reg(0x0035, 0x0106); |
498 LCD_WR_Reg(0x0036, 0x0b02); | 202 lcd_wr_reg(0x0036, 0x0b02); |
499 LCD_WR_Reg(0x0037, 0x0302); | 203 lcd_wr_reg(0x0037, 0x0302); |
500 LCD_WR_Reg(0x0038, 0x0707); | 204 lcd_wr_reg(0x0038, 0x0707); |
501 LCD_WR_Reg(0x0039, 0x0007); | 205 lcd_wr_reg(0x0039, 0x0007); |
502 LCD_WR_Reg(0x003c, 0x0600); | 206 lcd_wr_reg(0x003c, 0x0600); |
503 LCD_WR_Reg(0x003d, 0x020b); | 207 lcd_wr_reg(0x003d, 0x020b); |
504 | 208 |
505 fputs("Testing\r\n", stdout); | 209 fputs("Testing\r\n", stdout); |
506 LCD_WR_StartData(0, 0); | 210 lcd_wr_startdata(0, 0); |
507 LCD_WR_Data(0xa5a5); | 211 lcd_wr_data(0xa5a5); |
508 LCD_WR_Data(0x5a5a); | 212 lcd_wr_data(0x5a5a); |
509 LCD_WR_StartData(0, 0); | 213 lcd_wr_startdata(0, 0); |
510 if ((id = LCD_RD_Data(1)) != 0xa5a5) | 214 if ((id = lcd_rd_data(1)) != 0xa5a5) |
511 printf("Expected 0xa5a5 got 0x%04x\r\n", id); | 215 printf("Expected 0xa5a5 got 0x%04x\r\n", id); |
512 | 216 |
513 if ((id = LCD_RD_Data(0)) != 0x5a5a) | 217 if ((id = lcd_rd_data(0)) != 0x5a5a) |
514 printf("Expected 0x5a5a got 0x%04x\r\n", id); | 218 printf("Expected 0x5a5a got 0x%04x\r\n", id); |
515 | 219 |
516 fputs("Filling\r\n", stdout); | 220 fputs("Filling\r\n", stdout); |
517 /* Fill panel */ | 221 /* Fill panel */ |
518 LCD_WR_StartData(0, 0); | 222 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 | 223 |
522 for (int x = 0; x < 320; x++) { | 224 for (int x = 0; x < 320; x++) { |
523 for (int y = 0; y < 240; y++) { | 225 for (int y = 0; y < 240; y++) { |
524 if (((x / 5) % 3) == 0) | 226 if (((x / 5) % 3) == 0) |
525 LCD_WR_Data(RGB24_565(255, 0, 0)); | 227 lcd_wr_data(LCD_RED); |
526 else if (((x / 5) % 3) == 1) | 228 else if (((x / 5) % 3) == 1) |
527 LCD_WR_Data(RGB24_565(0, 255, 0)); | 229 lcd_wr_data(LCD_GREEN); |
528 else | 230 else |
529 LCD_WR_Data(RGB24_565(0, 0, 255)); | 231 lcd_wr_data(LCD_BLUE); |
530 } | 232 } |
531 } | 233 } |
532 | 234 |
533 } | 235 lcd_circle(50, 50, 20, LCD_BLACK); |
534 | 236 |
237 } | |
238 | |
239 void | |
240 lcd_pixel(uint16_t x, uint16_t y, uint16_t colour) { | |
241 if (x > LCD_HEIGHT || y > LCD_WIDTH) | |
242 return; | |
243 | |
244 lcd_wr_startdata(x, y); | |
245 lcd_wr_data(colour); | |
246 } | |
247 | |
248 /* | |
249 * Draw a circle | |
250 * From http://en.wikipedia.org/wiki/Midpoint_circle_algorithm | |
251 */ | |
252 void | |
253 lcd_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t colour) { | |
254 int16_t f; | |
255 uint16_t ddF_x, ddF_y, x, y; | |
256 | |
257 f = 1 - radius; | |
258 ddF_x = 1; | |
259 ddF_y = -2 * radius; | |
260 x = 0; | |
261 y = radius; | |
262 | |
263 lcd_pixel(x0, y0 + radius, colour); | |
264 lcd_pixel(x0, y0 - radius, colour); | |
265 lcd_pixel(x0 + radius, y0, colour); | |
266 lcd_pixel(x0 - radius, y0, colour); | |
267 | |
268 while(x < y) { | |
269 // ddF_x == 2 * x + 1; | |
270 // ddF_y == -2 * y; | |
271 // f == x*x + y*y - radius*radius + 2*x - y + 1; | |
272 if(f >= 0) { | |
273 y--; | |
274 ddF_y += 2; | |
275 f += ddF_y; | |
276 } | |
277 x++; | |
278 ddF_x += 2; | |
279 f += ddF_x; | |
280 lcd_pixel(x0 + x, y0 + y, colour); | |
281 lcd_pixel(x0 - x, y0 + y, colour); | |
282 lcd_pixel(x0 + x, y0 - y, colour); | |
283 lcd_pixel(x0 - x, y0 - y, colour); | |
284 lcd_pixel(x0 + y, y0 + x, colour); | |
285 lcd_pixel(x0 - y, y0 + x, colour); | |
286 lcd_pixel(x0 + y, y0 - x, colour); | |
287 lcd_pixel(x0 - y, y0 - x, colour); | |
288 } | |
289 } | |
290 | |
291 | |
292 /* | |
293 * Draw a line | |
294 * From http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm | |
295 */ | |
296 void | |
297 lcd_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t colour) { | |
298 uint16_t dx, dy, d, x, y; | |
299 | |
300 dx = x1 - x0; | |
301 dy = y1 - y0; | |
302 | |
303 d = 2 * dy - dx; | |
304 lcd_pixel(x0, y0, colour); | |
305 y = y0; | |
306 | |
307 for (x = x0 + 1; x <= x1; x++) { | |
308 if (d > 0) { | |
309 y++; | |
310 lcd_pixel(x, y, colour); | |
311 d += 2 * dy - 2 * dx; | |
312 } else { | |
313 lcd_pixel(x, y, colour); | |
314 d += 2 * dy; | |
315 } | |
316 } | |
317 } |