Prep for v1.2.0
[hackover2013-badge-firmware.git] / drivers / displays / tft / hw / hx8340b.c
1 /**************************************************************************/
2 /*!
3 @file hx8340b.c
4 @author K. Townsend (microBuilder.eu)
5
6 @section DESCRIPTION
7
8 Driver for HX8340B 176x220 pixel TFT LCD displays.
9
10 This driver uses a bit-banged SPI interface and a 16-bit RGB565
11 colour palette.
12
13 @section LICENSE
14
15 Software License Agreement (BSD License)
16
17 Copyright (c) 2012 Kevin Townsend
18 All rights reserved.
19
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions are met:
22 1. Redistributions of source code must retain the above copyright
23 notice, this list of conditions and the following disclaimer.
24 2. Redistributions in binary form must reproduce the above copyright
25 notice, this list of conditions and the following disclaimer in the
26 documentation and/or other materials provided with the distribution.
27 3. Neither the name of the copyright holders nor the
28 names of its contributors may be used to endorse or promote products
29 derived from this software without specific prior written permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
32 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42 /**************************************************************************/
43 #include "hx8340b.h"
44 #include "core/systick/systick.h"
45 #include "core/gpio/gpio.h"
46
47 static lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT;
48 static lcdProperties_t hx8340bProperties = { 176, 220, false, false, false, true, true };
49
50 /*************************************************/
51 /* Private Methods */
52 /*************************************************/
53
54 /*************************************************/
55 void hx8340bWriteCmd(uint8_t command)
56 {
57 CLR_CS;
58
59 CLR_SDI;
60 CLR_SCL;
61 SET_SCL;
62
63 uint8_t i = 0;
64 for (i=0; i<8; i++)
65 {
66 if (command & 0x80)
67 {
68 SET_SDI;
69 }
70 else
71 {
72 CLR_SDI;
73 }
74 CLR_SCL;
75 command <<= 1;
76 SET_SCL;
77 }
78 SET_CS;
79 }
80
81 /*************************************************/
82 void hx8340bWriteData(uint8_t data)
83 {
84 CLR_CS;
85
86 SET_SDI;
87 CLR_SCL;
88 SET_SCL;
89
90 uint8_t i = 0;
91 for (i=0; i<8; i++)
92 {
93 if (data & 0x80)
94 {
95 SET_SDI;
96 }
97 else
98 {
99 CLR_SDI;
100 }
101 CLR_SCL;
102 data <<= 1;
103 SET_SCL;
104 }
105 SET_CS;
106 }
107
108 /*************************************************/
109 void hx8340bWriteData16(uint16_t data)
110 {
111 hx8340bWriteData((data>>8) & 0xFF);
112 hx8340bWriteData(data & 0xFF);
113 }
114
115 /*************************************************/
116 void hx8340bWriteRegister(uint8_t reg, uint8_t value)
117 {
118 hx8340bWriteCmd(reg);
119 hx8340bWriteCmd(value);
120 }
121
122 /*************************************************/
123 void hx8340bInitDisplay(void)
124 {
125 #if defined HX8340B_ICVERSION_T
126 // Power Settings
127 hx8340bWriteRegister(HX8340B_OSCCONTROLA, 0x02); // 0x18: Frequency = 100% (60fps)
128 hx8340bWriteRegister(HX8340B_OSCCONTROLB, 0x00); // 0x21: Disable Internal Oscillator
129 hx8340bWriteRegister(HX8340B_VCOMCONTROL1, 0x30); // 0x23: VCOM Offset voltage
130 hx8340bWriteRegister(HX8340B_VCOMCONTROL2, 0x36); // 0x24: VCOM High Voltage
131 hx8340bWriteRegister(HX8340B_VCOMCONTROL3, 0x1a); // 0x25: VCOM Low Voltage
132
133 // Power Supply Settings
134 hx8340bWriteRegister(HX8340B_OSCCONTROLA, 0x44); // 0x18: Frequency = 100% (60fps) (Internal 2.52MHz RC oscillator is +/-5% and made need to be tuned)
135 hx8340bWriteRegister(HX8340B_OSCCONTROLB, 0x01); // 0x21: Enable Internal Oscillator
136 hx8340bWriteRegister(HX8340B_DISPLAYMODECONTROL, 0x00); // 0x01: Partial mode off, Sleep off, Scroll off, Invert off, Idle off
137 hx8340bWriteRegister(HX8340B_MEMACCESSCONTROL, 0x08); // 0x16: Read/Write scanning direction and color order (0x08 = BGR, 0x00 = RGB)
138 hx8340bWriteRegister(HX8340B_COLMOD, 0x55); // 0x17: RGB Data Format - 0x55 = 16bpp, 0x66 = 18bpp
139 hx8340bWriteRegister(HX8340B_POWERCONTROL5, 0x03); // 0x1C: Current driving the power-supply op-amp, 0x03 = medium
140 hx8340bWriteRegister(HX8340B_POWERCONTROL1, 0x06); // 0x19: B0 = DDVDH Step-up on/off, B1 = VGH/VGL step-up off/on, B2 = VCL step-up off/on (0x06 = all on)
141 systickDelay(6);
142
143 // Driving Settings
144 hx8340bWriteRegister(HX8340B_POWERCONTROL_INT1, 0x00); // 0x60
145 hx8340bWriteRegister(HX8340B_POWERCONTROL_INT2, 0x06); // 0x61
146 hx8340bWriteRegister(HX8340B_SOURCECONTROL_INT1, 0x00); // 0x62
147 hx8340bWriteRegister(HX8340B_SOURCECONTROL_INT2, 0xC8); // 0x63
148
149 // Gamma Settings
150 hx8340bWriteRegister(0x40,0x70);
151 hx8340bWriteRegister(0x41,0x51);
152 hx8340bWriteRegister(0x42,0x36);
153 hx8340bWriteRegister(0x43,0x04);
154 hx8340bWriteRegister(0x44,0x3B);
155 hx8340bWriteRegister(0x45,0x0E);
156 hx8340bWriteRegister(0x46,0x01);
157 hx8340bWriteRegister(0x47,0x1D);
158 hx8340bWriteRegister(0x48,0x09);
159 hx8340bWriteRegister(0x50,0x72);
160 hx8340bWriteRegister(0x51,0x20);
161 hx8340bWriteRegister(0x52,0x60);
162 hx8340bWriteRegister(0x53,0x01);
163 hx8340bWriteRegister(0x54,0x33);
164 hx8340bWriteRegister(0x55,0x0E);
165 hx8340bWriteRegister(0x56,0x02);
166 hx8340bWriteRegister(0x57,0x73);
167 hx8340bWriteRegister(HX8340B_DISPLAYCONTROL1, 0x84); // 0x26: B3 = display off/on (1 = on, 0 = off), also controls gate for VGH/VGL
168 systickDelay(40);
169 hx8340bWriteRegister(HX8340B_DISPLAYCONTROL1, 0xB8); // 0x26: Display on
170 systickDelay(40);
171 hx8340bWriteRegister(HX8340B_DISPLAYCONTROL1, 0xBC);
172
173 // Set GRAM Area
174 hx8340bWriteRegister(HX8340B_COLADDR_START2, 0x00);
175 hx8340bWriteRegister(HX8340B_COLADDR_START1, 0x00);
176 hx8340bWriteRegister(HX8340B_COLADDR_END2, 0x00);
177 hx8340bWriteRegister(HX8340B_COLADDR_END1, 0xAF); // 175
178 hx8340bWriteRegister(HX8340B_ROWADDR_START2, 0x00);
179 hx8340bWriteRegister(HX8340B_ROWADDR_START1, 0x00);
180 hx8340bWriteRegister(HX8340B_ROWADDR_END2, 0x00);
181 hx8340bWriteRegister(HX8340B_ROWADDR_END1, 0xDB); // 219
182
183 hx8340bWriteCmd(HX8340B_SRAMWRITECONTROL);
184 #endif
185
186 #if defined HX8340B_ICVERSION_N
187 hx8340bWriteCmd(HX8340B_N_SETEXTCMD);
188 hx8340bWriteData(0xFF);
189 hx8340bWriteData(0x83);
190 hx8340bWriteData(0x40);
191
192 hx8340bWriteCmd(HX8340B_N_SPLOUT);
193 systickDelay(100);
194
195 hx8340bWriteCmd(0xCA); // Undocumented register?
196 hx8340bWriteData(0x70);
197 hx8340bWriteData(0x00);
198 hx8340bWriteData(0xD9);
199 hx8340bWriteData(0x01);
200 hx8340bWriteData(0x11);
201
202 hx8340bWriteCmd(0xC9); // Undocumented register?
203 hx8340bWriteData(0x90);
204 hx8340bWriteData(0x49);
205 hx8340bWriteData(0x10);
206 hx8340bWriteData(0x28);
207 hx8340bWriteData(0x28);
208 hx8340bWriteData(0x10);
209 hx8340bWriteData(0x00);
210 hx8340bWriteData(0x06);
211 systickDelay(20);
212
213 hx8340bWriteCmd(HX8340B_N_SETGAMMAP);
214 hx8340bWriteData(0x60);
215 hx8340bWriteData(0x71);
216 hx8340bWriteData(0x01);
217 hx8340bWriteData(0x0E);
218 hx8340bWriteData(0x05);
219 hx8340bWriteData(0x02);
220 hx8340bWriteData(0x09);
221 hx8340bWriteData(0x31);
222 hx8340bWriteData(0x0A);
223
224 hx8340bWriteCmd(HX8340B_N_SETGAMMAN);
225 hx8340bWriteData(0x67);
226 hx8340bWriteData(0x30);
227 hx8340bWriteData(0x61);
228 hx8340bWriteData(0x17);
229 hx8340bWriteData(0x48);
230 hx8340bWriteData(0x07);
231 hx8340bWriteData(0x05);
232 hx8340bWriteData(0x33);
233 systickDelay(10);
234
235 hx8340bWriteCmd(HX8340B_N_SETPWCTR5);
236 hx8340bWriteData(0x35);
237 hx8340bWriteData(0x20);
238 hx8340bWriteData(0x45);
239
240 hx8340bWriteCmd(HX8340B_N_SETPWCTR4);
241 hx8340bWriteData(0x33);
242 hx8340bWriteData(0x25);
243 hx8340bWriteData(0x4c);
244 systickDelay(10);
245
246 hx8340bWriteCmd(HX8340B_N_COLMOD); // Color Mode
247 hx8340bWriteData(0x05); // 0x05 = 16bpp, 0x06 = 18bpp
248
249 hx8340bWriteCmd(HX8340B_N_DISPON);
250 systickDelay(10);
251
252 hx8340bWriteCmd(HX8340B_N_CASET);
253 hx8340bWriteData(0x00);
254 hx8340bWriteData(0x00);
255 hx8340bWriteData(0x00);
256 hx8340bWriteData(0xaf); // 175
257
258 hx8340bWriteCmd(HX8340B_N_PASET);
259 hx8340bWriteData(0x00);
260 hx8340bWriteData(0x00);
261 hx8340bWriteData(0x00);
262 hx8340bWriteData(0xdb); // 219
263
264 hx8340bWriteCmd(HX8340B_N_RAMWR);
265 #endif
266 }
267
268 /*************************************************/
269 void hx8340bHome(void)
270 {
271 #if defined HX8340B_ICVERSION_N
272 hx8340bWriteCmd(HX8340B_N_CASET);
273 hx8340bWriteData(0x00);
274 hx8340bWriteData(0x00);
275 hx8340bWriteData(0x00);
276 hx8340bWriteData(0xaf);
277 hx8340bWriteCmd(HX8340B_N_PASET);
278 hx8340bWriteData(0x00);
279 hx8340bWriteData(0x00);
280 hx8340bWriteData(0x00);
281 hx8340bWriteData(0xdb);
282 #endif
283 }
284
285 /*************************************************/
286 static inline void hx8340bSetPosition(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
287 {
288 #if defined HX8340B_ICVERSION_N
289 hx8340bWriteCmd(HX8340B_N_CASET);
290 hx8340bWriteData(x0>>8);
291 hx8340bWriteData(x0);
292 hx8340bWriteData(x1>>8);
293 hx8340bWriteData(x1);
294
295 hx8340bWriteCmd(HX8340B_N_PASET);
296 hx8340bWriteData(y0>>8);
297 hx8340bWriteData(y0);
298 hx8340bWriteData(y1>>8);
299 hx8340bWriteData(y1);
300
301 hx8340bWriteCmd(HX8340B_N_RAMWR);
302 #endif
303 }
304
305 /*************************************************/
306 /* Public Methods */
307 /*************************************************/
308
309 /*************************************************/
310 void lcdInit(void)
311 {
312 // Set control pins to output
313 gpioSetDir(HX8340B_PORT, HX8340B_SDI_PIN, 1);
314 gpioSetDir(HX8340B_PORT, HX8340B_SCL_PIN, 1);
315 gpioSetDir(HX8340B_PORT, HX8340B_CS_PIN, 1);
316 gpioSetDir(HX8340B_PORT, HX8340B_RES_PIN, 1);
317 gpioSetDir(HX8340B_PORT, HX8340B_BL_PIN, 1);
318
319 // Set pins low by default (except reset)
320 CLR_SDI;
321 CLR_SCL;
322 CLR_CS;
323 CLR_BL;
324 SET_RES;
325
326 // Turn backlight on
327 lcdBacklight(TRUE);
328
329 // Reset display
330 SET_RES;
331 systickDelay(100);
332 CLR_RES;
333 systickDelay(50);
334 SET_RES;
335 systickDelay(50);
336
337 // Run LCD init sequence
338 hx8340bInitDisplay();
339
340 // Fill black
341 lcdFillRGB(COLOR_BLACK);
342 }
343
344 /*************************************************/
345 void lcdBacklight(bool state)
346 {
347 // Set the backlight
348 // Note: Depending on the type of transistor used
349 // to control the backlight, you made need to invert
350 // the values below
351 if (state)
352 // CLR_BL;
353 SET_BL;
354 else
355 // SET_BL;
356 CLR_BL;
357 }
358
359 /*************************************************/
360 void lcdTest(void)
361 {
362 #if defined HX8340B_ICVERSION_N
363 lcdFillRGB(COLOR_GREEN);
364 #endif
365 }
366
367 /*************************************************/
368 void lcdFillRGB(uint16_t color)
369 {
370 #if defined HX8340B_ICVERSION_N
371 uint8_t i,j;
372 for (i=0;i<220;i++)
373 {
374 for (j=0;j<176;j++)
375 {
376 hx8340bWriteData16(color);
377 }
378 }
379 #endif
380 }
381
382 /*************************************************/
383 void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
384 {
385 hx8340bSetPosition(x, y, x+1, y+1);
386 hx8340bWriteData16(color);
387 }
388
389 /**************************************************************************/
390 /*!
391 @brief Draws an array of consecutive RGB565 pixels (much
392 faster than addressing each pixel individually)
393 */
394 /**************************************************************************/
395 void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
396 {
397 // ToDo: Optimise this function ... currently only a placeholder
398 uint32_t i = 0;
399 do
400 {
401 lcdDrawPixel(x+i, y, data[i]);
402 i++;
403 } while (i<len);
404 }
405
406 /*************************************************/
407 void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
408 {
409 // Allows for slightly better performance than setting individual pixels
410 uint16_t x, pixels;
411
412 if (x1 < x0)
413 {
414 // Switch x1 and x0
415 x = x1;
416 x1 = x0;
417 x0 = x;
418 }
419
420 // Check limits
421 if (x1 >= lcdGetWidth())
422 {
423 x1 = lcdGetWidth() - 1;
424 }
425 if (x0 >= lcdGetWidth())
426 {
427 x0 = lcdGetWidth() - 1;
428 }
429
430 hx8340bSetPosition(x0, y, x1, y+1);
431 for (pixels = 0; pixels < x1 - x0 + 1; pixels++)
432 {
433 hx8340bWriteData16(color);
434 }
435 }
436
437 /*************************************************/
438 void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
439 {
440 // Allows for slightly better performance than setting individual pixels
441 uint16_t y, pixels;
442
443 if (y1 < y0)
444 {
445 // Switch y1 and y0
446 y = y1;
447 y1 = y0;
448 y0 = y;
449 }
450
451 // Check limits
452 if (y1 >= lcdGetHeight())
453 {
454 y1 = lcdGetHeight() - 1;
455 }
456 if (y0 >= lcdGetHeight())
457 {
458 y0 = lcdGetHeight() - 1;
459 }
460
461 for (pixels = 0; pixels < y1 - y0 + 1; pixels++)
462 {
463 hx8340bSetPosition(x, y0+pixels, x+1, y0+pixels+1);
464 hx8340bWriteData16(color);
465 }
466 }
467
468 /*************************************************/
469 uint16_t lcdGetPixel(uint16_t x, uint16_t y)
470 {
471 // ToDo
472 return 0;
473 }
474
475 /*************************************************/
476 void lcdSetOrientation(lcdOrientation_t orientation)
477 {
478 // ToDo
479 }
480
481 /*************************************************/
482 lcdOrientation_t lcdGetOrientation(void)
483 {
484 return lcdOrientation;
485 }
486
487 /*************************************************/
488 uint16_t lcdGetWidth(void)
489 {
490 return hx8340bProperties.width;
491 }
492
493 /*************************************************/
494 uint16_t lcdGetHeight(void)
495 {
496 return hx8340bProperties.height;
497 }
498
499 /*************************************************/
500 void lcdScroll(int16_t pixels, uint16_t fillColor)
501 {
502 // ToDo
503 }
504
505 /*************************************************/
506 uint16_t lcdGetControllerID(void)
507 {
508 return 0x8340;
509 }
510
511 /*************************************************/
512 lcdProperties_t lcdGetProperties(void)
513 {
514 return hx8340bProperties;
515 }
This page took 0.082705 seconds and 5 git commands to generate.