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/displays/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 void st7783SetCursor(uint16_t x
, uint16_t y
)
154 uint16_t he
, ve
, al
, ah
;
156 switch (lcdOrientation
)
158 case LCD_ORIENTATION_LANDSCAPE
:
159 he
= st7783Properties
.width
-1-y
;
160 ve
= st7783Properties
.height
-1-x
;
164 case LCD_ORIENTATION_PORTRAIT
:
166 he
= st7783Properties
.width
-1;
167 ve
= st7783Properties
.height
-1;
172 st7783Command(0x0051, he
);
173 st7783Command(0x0053, ve
);
174 st7783Command(0x0020, al
);
175 st7783Command(0x0021, ah
);
178 /*************************************************/
179 void st7783InitDisplay(void)
182 GPIO_GPIO2DATA
&= ~ST7783_DATA_MASK
;
195 st7783Command(0x00FF, 0x0001);
196 st7783Command(0x00F3, 0x0008);
197 st7783WriteCmd(0x00F3);
199 st7783Command(0x0001, 0x0100); // Driver Output Control Register (R01h)
200 st7783Command(0x0002, 0x0700); // LCD Driving Waveform Control (R02h)
201 st7783Command(0x0003, 0x1030); // Entry Mode (R03h)
202 st7783Command(0x0008, 0x0302);
203 st7783Command(0x0009, 0x0000);
204 st7783Command(0x0010, 0x0000); // Power Control 1 (R10h)
205 st7783Command(0x0011, 0x0007); // Power Control 2 (R11h)
206 st7783Command(0x0012, 0x0000); // Power Control 3 (R12h)
207 st7783Command(0x0013, 0x0000); // Power Control 4 (R13h)
209 st7783Command(0x0010, 0x14B0); // Power Control 1 (R10h)
211 st7783Command(0x0011, 0x0007); // Power Control 2 (R11h)
213 st7783Command(0x0012, 0x008E); // Power Control 3 (R12h)
214 st7783Command(0x0013, 0x0C00); // Power Control 4 (R13h)
215 st7783Command(0x0029, 0x0015); // NVM read data 2 (R29h)
217 st7783Command(0x0030, 0x0000); // Gamma Control 1
218 st7783Command(0x0031, 0x0107); // Gamma Control 2
219 st7783Command(0x0032, 0x0000); // Gamma Control 3
220 st7783Command(0x0035, 0x0203); // Gamma Control 6
221 st7783Command(0x0036, 0x0402); // Gamma Control 7
222 st7783Command(0x0037, 0x0000); // Gamma Control 8
223 st7783Command(0x0038, 0x0207); // Gamma Control 9
224 st7783Command(0x0039, 0x0000); // Gamma Control 10
225 st7783Command(0x003C, 0x0203); // Gamma Control 13
226 st7783Command(0x003D, 0x0403); // Gamma Control 14
227 st7783Command(0x0050, 0x0000); // Window Horizontal RAM Address Start (R50h)
228 st7783Command(0x0051, st7783Properties
.width
- 1); // Window Horizontal RAM Address End (R51h)
229 st7783Command(0x0052, 0X0000); // Window Vertical RAM Address Start (R52h)
230 st7783Command(0x0053, st7783Properties
.height
- 1); // Window Vertical RAM Address End (R53h)
231 st7783Command(0x0060, 0xa700); // Driver Output Control (R60h)
232 st7783Command(0x0061, 0x0001); // Driver Output Control (R61h)
233 st7783Command(0x0090, 0X0029); // Panel Interface Control 1 (R90h)
236 st7783Command(0x0007, 0x0133); // Display Control (R07h)
238 st7783WriteCmd(0x0022);
241 /*************************************************/
242 void st7783Home(void)
244 st7783SetCursor(0, 0);
245 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
248 /*************************************************/
249 void st7783SetWindow(uint16_t x
, uint16_t y
, uint16_t height
, uint16_t width
)
251 // Window horizontal RAM address start
252 if (x
>= height
) st7783Command(0x50, (x
- height
+ 1));
253 else st7783Command(0x50, 0);
254 // Window horizontal GRAM address end
255 st7783Command(0x51, x
);
256 // Window vertical GRAM address start
257 if (y
>= width
) st7783Command(0x52, (y
- width
+ 1));
258 else st7783Command(0x52, 0);
259 // Window vertical GRAM address end
260 st7783Command(0x53, y
);
262 st7783SetCursor(x
, y
);
265 /*************************************************/
267 /*************************************************/
269 /*************************************************/
272 // Set control line pins to output
273 gpioSetDir(ST7783_CS_PORT
, ST7783_CS_PIN
, 1);
274 gpioSetDir(ST7783_CD_PORT
, ST7783_CD_PIN
, 1);
275 gpioSetDir(ST7783_WR_PORT
, ST7783_WR_PIN
, 1);
276 gpioSetDir(ST7783_RD_PORT
, ST7783_RD_PIN
, 1);
278 // Set data port pins to output
279 ST7783_GPIO2DATA_SETOUTPUT
;
282 ST7783_DISABLEPULLUPS();
284 // Set backlight pin to output and turn it on
285 gpioSetDir(ST7783_BL_PORT
, ST7783_BL_PIN
, 1); // set to output
288 // Set reset pin to output
289 gpioSetDir(ST7783_RES_PORT
, ST7783_RES_PIN
, 1); // Set to output
290 gpioSetValue(ST7783_RES_PORT
, ST7783_RES_PIN
, 0); // Low to reset
292 gpioSetValue(ST7783_RES_PORT
, ST7783_RES_PIN
, 1); // High to exit
294 // Initialize the display
297 // Set lcd to default orientation
298 lcdSetOrientation(lcdOrientation
);
301 lcdFillRGB(COLOR_BLACK
);
303 // Initialise the touch screen (and calibrate if necessary)
307 /*************************************************/
308 void lcdBacklight(bool state
)
311 gpioSetValue(ST7783_BL_PORT
, ST7783_BL_PIN
, state
? 0 : 1);
314 /*************************************************/
324 if(i
>279)st7783WriteData(COLOR_WHITE
);
325 else if(i
>239)st7783WriteData(COLOR_BLUE
);
326 else if(i
>199)st7783WriteData(COLOR_GREEN
);
327 else if(i
>159)st7783WriteData(COLOR_CYAN
);
328 else if(i
>119)st7783WriteData(COLOR_RED
);
329 else if(i
>79)st7783WriteData(COLOR_MAGENTA
);
330 else if(i
>39)st7783WriteData(COLOR_YELLOW
);
331 else st7783WriteData(COLOR_BLACK
);
336 /*************************************************/
337 void lcdFillRGB(uint16_t data
)
342 uint32_t pixels
= 320*240;
343 for ( i
=0; i
< pixels
; i
++ )
345 st7783WriteData(data
);
349 /*************************************************/
350 void lcdDrawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
352 st7783SetCursor(x
, y
);
353 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
354 st7783WriteData(color
);
357 /**************************************************************************/
359 @brief Draws an array of consecutive RGB565 pixels (much
360 faster than addressing each pixel individually)
362 /**************************************************************************/
363 void lcdDrawPixels(uint16_t x
, uint16_t y
, uint16_t *data
, uint32_t len
)
366 st7783SetCursor(x
, y
);
367 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
370 st7783WriteData(data
[i
]);
375 /*************************************************/
376 void lcdDrawHLine(uint16_t x0
, uint16_t x1
, uint16_t y
, uint16_t color
)
378 // Allows for slightly better performance than setting individual pixels
388 st7783SetCursor(x0
, y
);
389 st7783WriteCmd(0x0022); // Write Data to GRAM (R22h)
390 for (pixels
= 0; pixels
< x1
- x0
+ 1; pixels
++)
392 st7783WriteData(color
);
396 /*************************************************/
397 void lcdDrawVLine(uint16_t x
, uint16_t y0
, uint16_t y1
, uint16_t color
)
399 // Allows for slightly better performance than setting individual pixels
400 lcdOrientation_t orientation
= lcdOrientation
;
402 // Switch orientation
403 lcdSetOrientation(orientation
== LCD_ORIENTATION_PORTRAIT
? LCD_ORIENTATION_LANDSCAPE
: LCD_ORIENTATION_PORTRAIT
);
405 // Draw horizontal line like usual
406 lcdDrawHLine(y0
, y1
, lcdGetHeight() - x
, color
);
408 // Switch orientation back
409 lcdSetOrientation(orientation
);
412 /*************************************************/
413 uint16_t lcdGetPixel(uint16_t x
, uint16_t y
)
415 uint16_t preFetch
= 0;
417 st7783SetCursor(x
, y
);
418 st7783WriteCmd(0x0022);
419 preFetch
= st7783ReadData();
421 // Eeek ... why does this need to be done twice for a proper value?!?
422 st7783SetCursor(x
, y
);
423 st7783WriteCmd(0x0022);
424 return st7783ReadData();
427 /*************************************************/
428 void lcdSetOrientation(lcdOrientation_t orientation
)
430 uint16_t entryMode
= 0x1030;
434 case LCD_ORIENTATION_PORTRAIT
:
437 case LCD_ORIENTATION_LANDSCAPE
:
441 st7783WriteCmd(0x0003);
442 st7783WriteData(entryMode
);
443 lcdOrientation
= orientation
;
444 st7783SetCursor(0, 0);
447 /*************************************************/
448 lcdOrientation_t
lcdGetOrientation(void)
450 return lcdOrientation
;
453 /*************************************************/
454 uint16_t lcdGetWidth(void)
456 switch (lcdOrientation
)
458 case LCD_ORIENTATION_PORTRAIT
:
459 return st7783Properties
.width
;
461 case LCD_ORIENTATION_LANDSCAPE
:
463 return st7783Properties
.height
;
467 /*************************************************/
468 uint16_t lcdGetHeight(void)
470 switch (lcdOrientation
)
472 case LCD_ORIENTATION_PORTRAIT
:
473 return st7783Properties
.height
;
475 case LCD_ORIENTATION_LANDSCAPE
:
477 return st7783Properties
.width
;
481 /*************************************************/
482 void lcdScroll(int16_t pixels
, uint16_t fillColor
)
484 // Not implemented in ST7783
487 /*************************************************/
488 uint16_t lcdGetControllerID(void)
493 /*************************************************/
494 lcdProperties_t
lcdGetProperties(void)
496 return st7783Properties
;