1 /**************************************************************************/
4 @author K. Townsend (microBuilder.eu)
8 Driver for st7783 240x320 pixel TFT LCD displays.
10 This driver uses an 8-bit interface and a 16-bit RGB565 colour palette.
14 26-11-2010: st7783ReadData contributed by Adafruit Industries
18 Software License Agreement (BSD License)
20 Copyright (c) 2010, microBuilder SARL
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions are met:
25 1. Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 2. Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in the
29 documentation and/or other materials provided with the distribution.
30 3. Neither the name of the copyright holders nor the
31 names of its contributors may be used to endorse or promote products
32 derived from this software without specific prior written permission.
34 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
35 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
38 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 /**************************************************************************/
47 #include "core/systick/systick.h"
48 #include "drivers/lcd/tft/touchscreen.h"
50 static lcdOrientation_t lcdOrientation
= LCD_ORIENTATION_PORTRAIT
;
51 static lcdProperties_t st7783Properties
= { 240, 320, TRUE
, TRUE
, FALSE
};
53 /*************************************************/
55 /*************************************************/
57 /*************************************************/
58 void st7783Delay(unsigned int t
)
62 for ( t1
=10; t1
> 0; t1
-- )
68 /*************************************************/
69 void st7783WriteCmd(uint16_t command
)
71 // Compiled with -Os on GCC 4.4 this works out to 25 cycles
72 // (versus 36 compiled with no optimisations). I'm not sure it
73 // can be improved further, so that means 25 cycles/350nS for
74 // continuous writes (cmd, data, data, data, ...) or ~150 cycles/
75 // ~2.1uS for a random pixel (Set X [cmd+data], Set Y [cmd+data],
76 // Set color [cmd+data]) (times assumes 72MHz clock).
78 CLR_CS_CD_SET_RD_WR
; // Saves 18 commands compared to "CLR_CS; CLR_CD; SET_RD; SET_WR;"
79 ST7783_GPIO2DATA_DATA
= (command
>> (8 - ST7783_DATA_OFFSET
));
82 ST7783_GPIO2DATA_DATA
= command
<< ST7783_DATA_OFFSET
;
84 SET_WR_CS
; // Saves 7 commands compared to "SET_WR; SET_CS;"
87 /*************************************************/
88 void st7783WriteData(uint16_t data
)
90 CLR_CS_SET_CD_RD_WR
; // Saves 18 commands compared to SET_CD; SET_RD; SET_WR; CLR_CS"
91 ST7783_GPIO2DATA_DATA
= (data
>> (8 - ST7783_DATA_OFFSET
));
94 ST7783_GPIO2DATA_DATA
= data
<< ST7783_DATA_OFFSET
;
96 SET_WR_CS
; // Saves 7 commands compared to "SET_WR, SET_CS;"
99 /*************************************************/
100 uint16_t st7783ReadData(void)
102 // ToDo: Optimise this method!
108 SET_CD_RD_WR
; // Saves 14 commands compared to "SET_CD; SET_RD; SET_WR"
112 ST7783_GPIO2DATA_SETINPUT
;
115 high
= ST7783_GPIO2DATA_DATA
;
116 high
>>= ST7783_DATA_OFFSET
;
122 low
= ST7783_GPIO2DATA_DATA
;
123 low
>>= ST7783_DATA_OFFSET
;
128 ST7783_GPIO2DATA_SETOUTPUT
;
137 /*************************************************/
138 uint16_t st7783Read(uint16_t addr
)
140 st7783WriteCmd(addr
);
141 return st7783ReadData();
144 /*************************************************/
145 void st7783Command(uint16_t command
, uint16_t data
)
147 st7783WriteCmd(command
);
148 st7783WriteData(data
);
151 /*************************************************/
152 /* Returns the 4-hexdigit controller code */
153 /*************************************************/
154 uint16_t st7783Type(void)
157 return st7783ReadData();
160 /*************************************************/
161 void st7783SetCursor(uint16_t x
, uint16_t y
)
163 uint16_t he
, ve
, al
, ah
;
165 switch (lcdOrientation
)
167 case LCD_ORIENTATION_LANDSCAPE
:
168 he
= st7783Properties
.width
-1-y
;
169 ve
= st7783Properties
.height
-1-x
;
173 case LCD_ORIENTATION_PORTRAIT
:
175 he
= st7783Properties
.width
-1;
176 ve
= st7783Properties
.height
-1;
181 st7783Command(0x0051, he
);
182 st7783Command(0x0053, ve
);
183 st7783Command(0x0020, al
);
184 st7783Command(0x0021, ah
);
187 /*************************************************/
188 void st7783InitDisplay(void)
191 GPIO_GPIO2DATA
&= ~ST7783_DATA_MASK
;
204 st7783Command(0x00FF, 0x0001);
205 st7783Command(0x00F3, 0x0008);
206 st7783WriteCmd(0x00F3);
208 st7783Command(0x0001, 0x0100); // Driver Output Control Register (R01h)
209 st7783Command(0x0002, 0x0700); // LCD Driving Waveform Control (R02h)
210 st7783Command(0x0003, 0x1030); // Entry Mode (R03h)
211 st7783Command(0x0008, 0x0302);
212 st7783Command(0x0009, 0x0000);
213 st7783Command(0x0010, 0x0000); // Power Control 1 (R10h)
214 st7783Command(0x0011, 0x0007); // Power Control 2 (R11h)
215 st7783Command(0x0012, 0x0000); // Power Control 3 (R12h)
216 st7783Command(0x0013, 0x0000); // Power Control 4 (R13h)
218 st7783Command(0x0010, 0x14B0); // Power Control 1 (R10h)
220 st7783Command(0x0011, 0x0007); // Power Control 2 (R11h)
222 st7783Command(0x0012, 0x008E); // Power Control 3 (R12h)
223 st7783Command(0x0013, 0x0C00); // Power Control 4 (R13h)
224 st7783Command(0x0029, 0x0015); // NVM read data 2 (R29h)
226 st7783Command(0x0030, 0x0000); // Gamma Control 1
227 st7783Command(0x0031, 0x0107); // Gamma Control 2
228 st7783Command(0x0032, 0x0000); // Gamma Control 3
229 st7783Command(0x0035, 0x0203); // Gamma Control 6
230 st7783Command(0x0036, 0x0402); // Gamma Control 7
231 st7783Command(0x0037, 0x0000); // Gamma Control 8
232 st7783Command(0x0038, 0x0207); // Gamma Control 9
233 st7783Command(0x0039, 0x0000); // Gamma Control 10
234 st7783Command(0x003C, 0x0203); // Gamma Control 13
235 st7783Command(0x003D, 0x0403); // Gamma Control 14
236 st7783Command(0x0050, 0x0000); // Window Horizontal RAM Address Start (R50h)
237 st7783Command(0x0051, st7783Properties
.width
- 1); // Window Horizontal RAM Address End (R51h)
238 st7783Command(0x0052, 0X0000); // Window Vertical RAM Address Start (R52h)
239 st7783Command(0x0053, st7783Properties
.height
- 1); // Window Vertical RAM Address End (R53h)
240 st7783Command(0x0060, 0xa700); // Driver Output Control (R60h)
241 st7783Command(0x0061, 0x0001); // Driver Output Control (R61h)
242 st7783Command(0x0090, 0X0029); // Panel Interface Control 1 (R90h)
245 st7783Command(0x0007, 0x0133); // Display Control (R07h)
247 st7783WriteCmd(0x0022);
250 /*************************************************/
251 void st7783Home(void)
253 st7783SetCursor(0, 0);
254 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
257 /*************************************************/
258 void st7783SetWindow(uint16_t x
, uint16_t y
, uint16_t height
, uint16_t width
)
260 // Window horizontal RAM address start
261 if (x
>= height
) st7783Command(0x50, (x
- height
+ 1));
262 else st7783Command(0x50, 0);
263 // Window horizontal GRAM address end
264 st7783Command(0x51, x
);
265 // Window vertical GRAM address start
266 if (y
>= width
) st7783Command(0x52, (y
- width
+ 1));
267 else st7783Command(0x52, 0);
268 // Window vertical GRAM address end
269 st7783Command(0x53, y
);
271 st7783SetCursor(x
, y
);
274 /*************************************************/
276 /*************************************************/
278 /*************************************************/
281 // Set control line pins to output
282 gpioSetDir(ST7783_CS_PORT
, ST7783_CS_PIN
, 1);
283 gpioSetDir(ST7783_CD_PORT
, ST7783_CD_PIN
, 1);
284 gpioSetDir(ST7783_WR_PORT
, ST7783_WR_PIN
, 1);
285 gpioSetDir(ST7783_RD_PORT
, ST7783_RD_PIN
, 1);
287 // Set data port pins to output
288 ST7783_GPIO2DATA_SETOUTPUT
;
291 ST7783_DISABLEPULLUPS();
293 // Set backlight pin to output and turn it on
294 gpioSetDir(ST7783_BL_PORT
, ST7783_BL_PIN
, 1); // set to output
297 // Set reset pin to output
298 gpioSetDir(ST7783_RES_PORT
, ST7783_RES_PIN
, 1); // Set to output
299 gpioSetValue(ST7783_RES_PORT
, ST7783_RES_PIN
, 0); // Low to reset
301 gpioSetValue(ST7783_RES_PORT
, ST7783_RES_PIN
, 1); // High to exit
303 // Initialize the display
306 // Set lcd to default orientation
307 lcdSetOrientation(lcdOrientation
);
310 lcdFillRGB(COLOR_BLACK
);
312 // Initialise the touch screen (and calibrate if necessary)
316 /*************************************************/
317 void lcdBacklight(bool state
)
320 gpioSetValue(ST7783_BL_PORT
, ST7783_BL_PIN
, state
? 0 : 1);
323 /*************************************************/
333 if(i
>279)st7783WriteData(COLOR_WHITE
);
334 else if(i
>239)st7783WriteData(COLOR_BLUE
);
335 else if(i
>199)st7783WriteData(COLOR_GREEN
);
336 else if(i
>159)st7783WriteData(COLOR_CYAN
);
337 else if(i
>119)st7783WriteData(COLOR_RED
);
338 else if(i
>79)st7783WriteData(COLOR_MAGENTA
);
339 else if(i
>39)st7783WriteData(COLOR_YELLOW
);
340 else st7783WriteData(COLOR_BLACK
);
345 /*************************************************/
346 void lcdFillRGB(uint16_t data
)
351 uint32_t pixels
= 320*240;
352 for ( i
=0; i
< pixels
; i
++ )
354 st7783WriteData(data
);
358 /*************************************************/
359 void lcdDrawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
361 st7783SetCursor(x
, y
);
362 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
363 st7783WriteData(color
);
366 /**************************************************************************/
368 @brief Draws an array of consecutive RGB565 pixels (much
369 faster than addressing each pixel individually)
371 /**************************************************************************/
372 void lcdDrawPixels(uint16_t x
, uint16_t y
, uint16_t *data
, uint32_t len
)
375 st7783SetCursor(x
, y
);
376 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
379 st7783WriteData(data
[i
]);
384 /*************************************************/
385 void lcdDrawHLine(uint16_t x0
, uint16_t x1
, uint16_t y
, uint16_t color
)
387 // Allows for slightly better performance than setting individual pixels
397 st7783SetCursor(x0
, y
);
398 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
399 for (pixels
= 0; pixels
< x1
- x0
+ 1; pixels
++)
401 st7783WriteData(color
);
405 /*************************************************/
406 void lcdDrawVLine(uint16_t x
, uint16_t y0
, uint16_t y1
, uint16_t color
)
408 // Allows for slightly better performance than setting individual pixels
409 lcdOrientation_t orientation
= lcdOrientation
;
411 // Switch orientation
412 lcdSetOrientation(orientation
== LCD_ORIENTATION_PORTRAIT
? LCD_ORIENTATION_LANDSCAPE
: LCD_ORIENTATION_PORTRAIT
);
414 // Draw horizontal line like usual
415 lcdDrawHLine(y0
, y1
, lcdGetHeight() - x
, color
);
417 // Switch orientation back
418 lcdSetOrientation(orientation
);
421 /*************************************************/
422 uint16_t lcdGetPixel(uint16_t x
, uint16_t y
)
424 uint16_t preFetch
= 0;
426 st7783SetCursor(x
, y
);
427 st7783WriteCmd(0x0022);
428 preFetch
= st7783ReadData();
430 // Eeek ... why does this need to be done twice for a proper value?!?
431 st7783SetCursor(x
, y
);
432 st7783WriteCmd(0x0022);
433 return st7783ReadData();
436 /*************************************************/
437 void lcdSetOrientation(lcdOrientation_t orientation
)
439 uint16_t entryMode
= 0x1030;
443 case LCD_ORIENTATION_PORTRAIT
:
446 case LCD_ORIENTATION_LANDSCAPE
:
450 st7783WriteCmd(0x0003);
451 st7783WriteData(entryMode
);
452 lcdOrientation
= orientation
;
453 st7783SetCursor(0, 0);
456 /*************************************************/
457 lcdOrientation_t
lcdGetOrientation(void)
459 return lcdOrientation
;
462 /*************************************************/
463 uint16_t lcdGetWidth(void)
465 switch (lcdOrientation
)
467 case LCD_ORIENTATION_PORTRAIT
:
468 return st7783Properties
.width
;
470 case LCD_ORIENTATION_LANDSCAPE
:
472 return st7783Properties
.height
;
476 /*************************************************/
477 uint16_t lcdGetHeight(void)
479 switch (lcdOrientation
)
481 case LCD_ORIENTATION_PORTRAIT
:
482 return st7783Properties
.height
;
484 case LCD_ORIENTATION_LANDSCAPE
:
486 return st7783Properties
.width
;
490 /*************************************************/
491 void lcdScroll(int16_t pixels
, uint16_t fillColor
)
493 // Not implemented in ST7783
496 /*************************************************/
497 uint16_t lcdGetControllerID(void)
502 /*************************************************/
503 lcdProperties_t
lcdGetProperties(void)
505 return st7783Properties
;