First draft
[hackover2013-badge-firmware.git] / drivers / lcd / tft / hw / st7735.c
1 /**************************************************************************/
2 /*!
3 @file st7735.c
4 @author K. Townsend (microBuilder.eu)
5
6 @section DESCRIPTION
7
8 Driver for st7735 128x160 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) 2010, microBuilder SARL
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 "st7735.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 st7735Properties = { 128, 160, FALSE, FALSE, FALSE };
49
50 /*************************************************/
51 /* Private Methods */
52 /*************************************************/
53
54 /*************************************************/
55 void st7735WriteCmd(uint8_t command)
56 {
57 CLR_CS;
58 CLR_RS;
59 uint8_t i = 0;
60 for (i=0; i<8; i++)
61 {
62 if (command & 0x80)
63 {
64 SET_SDA;
65 }
66 else
67 {
68 CLR_SDA;
69 }
70 CLR_SCL;
71 command <<= 1;
72 SET_SCL;
73 }
74 SET_CS;
75 }
76
77 /*************************************************/
78 void st7735WriteData(uint8_t data)
79 {
80 CLR_CS;
81 SET_RS;
82 uint8_t i = 0;
83 for (i=0; i<8; i++)
84 {
85 if (data & 0x80)
86 {
87 SET_SDA;
88 }
89 else
90 {
91 CLR_SDA;
92 }
93 CLR_SCL;
94 data <<= 1;
95 SET_SCL;
96 }
97 SET_CS;
98 }
99
100 /*************************************************/
101 void st7735SetAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
102 {
103 st7735WriteCmd(ST7735_CASET); // column addr set
104 st7735WriteData(0x00);
105 st7735WriteData(x0+2); // XSTART
106 st7735WriteData(0x00);
107 st7735WriteData(x1+2); // XEND
108
109 st7735WriteCmd(ST7735_RASET); // row addr set
110 st7735WriteData(0x00);
111 st7735WriteData(y0+1); // YSTART
112 st7735WriteData(0x00);
113 st7735WriteData(y1+1); // YEND
114 }
115
116 /*************************************************/
117 void st7735InitDisplay(void)
118 {
119 st7735WriteCmd(ST7735_SWRESET); // software reset
120 systickDelay(50);
121 st7735WriteCmd(ST7735_SLPOUT); // out of sleep mode
122 systickDelay(500);
123
124 st7735WriteCmd(ST7735_COLMOD); // set color mode
125 st7735WriteData(0x05); // 16-bit color
126 systickDelay(10);
127
128 st7735WriteCmd(ST7735_FRMCTR1); // frame rate control
129 st7735WriteData(0x00); // fastest refresh
130 st7735WriteData(0x06); // 6 lines front porch
131 st7735WriteData(0x03); // 3 lines backporch
132 systickDelay(10);
133
134 st7735WriteCmd(ST7735_MADCTL); // memory access control (directions)
135 st7735WriteData(0xC8); // row address/col address, bottom to top refresh
136
137 st7735WriteCmd(ST7735_DISSET5); // display settings #5
138 st7735WriteData(0x15); // 1 clock cycle nonoverlap, 2 cycle gate rise, 3 cycle oscil. equalize
139 st7735WriteData(0x02); // fix on VTL
140
141 st7735WriteCmd(ST7735_INVCTR); // display inversion control
142 st7735WriteData(0x0); // line inversion
143
144 st7735WriteCmd(ST7735_PWCTR1); // power control
145 st7735WriteData(0x02); // GVDD = 4.7V
146 st7735WriteData(0x70); // 1.0uA
147 systickDelay(10);
148 st7735WriteCmd(ST7735_PWCTR2); // power control
149 st7735WriteData(0x05); // VGH = 14.7V, VGL = -7.35V
150 st7735WriteCmd(ST7735_PWCTR3); // power control
151 st7735WriteData(0x01); // Opamp current small
152 st7735WriteData(0x02); // Boost frequency
153
154
155 st7735WriteCmd(ST7735_VMCTR1); // power control
156 st7735WriteData(0x3C); // VCOMH = 4V
157 st7735WriteData(0x38); // VCOML = -1.1V
158 systickDelay(10);
159
160 st7735WriteCmd(ST7735_PWCTR6); // power control
161 st7735WriteData(0x11);
162 st7735WriteData(0x15);
163
164 st7735WriteCmd(ST7735_GMCTRP1);
165 st7735WriteData(0x09);
166 st7735WriteData(0x16);
167 st7735WriteData(0x09);
168 st7735WriteData(0x20);
169 st7735WriteData(0x21);
170 st7735WriteData(0x1B);
171 st7735WriteData(0x13);
172 st7735WriteData(0x19);
173 st7735WriteData(0x17);
174 st7735WriteData(0x15);
175 st7735WriteData(0x1E);
176 st7735WriteData(0x2B);
177 st7735WriteData(0x04);
178 st7735WriteData(0x05);
179 st7735WriteData(0x02);
180 st7735WriteData(0x0E);
181 st7735WriteCmd(ST7735_GMCTRN1);
182 st7735WriteData(0x0B);
183 st7735WriteData(0x14);
184 st7735WriteData(0x08);
185 st7735WriteData(0x1E);
186 st7735WriteData(0x22);
187 st7735WriteData(0x1D);
188 st7735WriteData(0x18);
189 st7735WriteData(0x1E);
190 st7735WriteData(0x1B);
191 st7735WriteData(0x1A);
192 st7735WriteData(0x24);
193 st7735WriteData(0x2B);
194 st7735WriteData(0x06);
195 st7735WriteData(0x06);
196 st7735WriteData(0x02);
197 st7735WriteData(0x0F);
198 systickDelay(10);
199
200 st7735WriteCmd(ST7735_CASET); // column addr set
201 st7735WriteData(0x00);
202 st7735WriteData(0x02); // XSTART = 2
203 st7735WriteData(0x00);
204 st7735WriteData(0x81); // XEND = 129
205
206 st7735WriteCmd(ST7735_RASET); // row addr set
207 st7735WriteData(0x00);
208 st7735WriteData(0x02); // XSTART = 1
209 st7735WriteData(0x00);
210 st7735WriteData(0x81); // XEND = 160
211
212 st7735WriteCmd(ST7735_NORON); // normal display on
213 systickDelay(10);
214
215 st7735WriteCmd(ST7735_DISPON);
216 systickDelay(500);
217 }
218
219 /*************************************************/
220 /* Public Methods */
221 /*************************************************/
222
223 /*************************************************/
224 void lcdInit(void)
225 {
226 // Set control pins to output
227 gpioSetDir(ST7735_PORT, ST7735_RS_PIN, 1);
228 gpioSetDir(ST7735_PORT, ST7735_SDA_PIN, 1);
229 gpioSetDir(ST7735_PORT, ST7735_SCL_PIN, 1);
230 gpioSetDir(ST7735_PORT, ST7735_CS_PIN, 1);
231 gpioSetDir(ST7735_PORT, ST7735_RES_PIN, 1);
232 gpioSetDir(ST7735_PORT, ST7735_BL_PIN, 1);
233
234 // Set pins low by default (except reset)
235 CLR_RS;
236 CLR_SDA;
237 CLR_SCL;
238 CLR_CS;
239 CLR_BL;
240 SET_RES;
241
242 // Turn backlight on
243 lcdBacklight(TRUE);
244
245 // Reset display
246 SET_RES;
247 systickDelay(50);
248 CLR_RES;
249 systickDelay(50);
250 SET_RES;
251 systickDelay(50);
252
253 // Run LCD init sequence
254 st7735InitDisplay();
255
256 // Fill black
257 lcdFillRGB(COLOR_BLACK);
258 }
259
260 /*************************************************/
261 void lcdBacklight(bool state)
262 {
263 // Set the backlight
264 // Note: Depending on the type of transistor used
265 // to control the backlight, you made need to invert
266 // the values below
267 if (state)
268 // CLR_BL;
269 SET_BL;
270 else
271 // SET_BL;
272 CLR_BL;
273 }
274
275 /*************************************************/
276 void lcdTest(void)
277 {
278 uint8_t i = 0;
279 for (i = 0; i < 100; i++)
280 {
281 lcdDrawPixel(i, i, 0xFFFF);
282 }
283 }
284
285 /*************************************************/
286 void lcdFillRGB(uint16_t color)
287 {
288 uint8_t x, y;
289 st7735SetAddrWindow(0, 0, lcdGetWidth() - 1, lcdGetHeight() - 1);
290 st7735WriteCmd(ST7735_RAMWR); // write to RAM
291 for (x=0; x < lcdGetWidth(); x++)
292 {
293 for (y=0; y < lcdGetHeight(); y++)
294 {
295 st7735WriteData(color >> 8);
296 st7735WriteData(color);
297 }
298 }
299 st7735WriteCmd(ST7735_NOP);
300 }
301
302 /*************************************************/
303 void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
304 {
305 st7735SetAddrWindow(x,y,x+1,y+1);
306 st7735WriteCmd(ST7735_RAMWR); // write to RAM
307 st7735WriteData(color >> 8);
308 st7735WriteData(color);
309 }
310
311 /**************************************************************************/
312 /*!
313 @brief Draws an array of consecutive RGB565 pixels (much
314 faster than addressing each pixel individually)
315 */
316 /**************************************************************************/
317 void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
318 {
319 // ToDo: Optimise this function ... currently only a placeholder
320 uint32_t i = 0;
321 do
322 {
323 lcdDrawPixel(x+i, y, data[i]);
324 i++;
325 } while (i<len);
326 }
327
328 /*************************************************/
329 void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
330 {
331 // Allows for slightly better performance than setting individual pixels
332 uint16_t x, pixels;
333
334 if (x1 < x0)
335 {
336 // Switch x1 and x0
337 x = x1;
338 x1 = x0;
339 x0 = x;
340 }
341
342 // Check limits
343 if (x1 >= lcdGetWidth())
344 {
345 x1 = lcdGetWidth() - 1;
346 }
347 if (x0 >= lcdGetWidth())
348 {
349 x0 = lcdGetWidth() - 1;
350 }
351
352 st7735SetAddrWindow(x0, y, lcdGetWidth(), y + 1);
353 st7735WriteCmd(ST7735_RAMWR); // write to RAM
354 for (pixels = 0; pixels < x1 - x0 + 1; pixels++)
355 {
356 st7735WriteData(color >> 8);
357 st7735WriteData(color);
358 }
359 st7735WriteCmd(ST7735_NOP);
360 }
361
362 /*************************************************/
363 void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
364 {
365 // Allows for slightly better performance than setting individual pixels
366 uint16_t y, pixels;
367
368 if (y1 < y0)
369 {
370 // Switch y1 and y0
371 y = y1;
372 y1 = y0;
373 y0 = y;
374 }
375
376 // Check limits
377 if (y1 >= lcdGetHeight())
378 {
379 y1 = lcdGetHeight() - 1;
380 }
381 if (y0 >= lcdGetHeight())
382 {
383 y0 = lcdGetHeight() - 1;
384 }
385
386 st7735SetAddrWindow(x, y0, x, lcdGetHeight());
387 st7735WriteCmd(ST7735_RAMWR); // write to RAM
388 for (pixels = 0; pixels < y1 - y0 + 1; pixels++)
389 {
390 st7735WriteData(color >> 8);
391 st7735WriteData(color);
392 }
393 st7735WriteCmd(ST7735_NOP);
394 }
395
396 /*************************************************/
397 uint16_t lcdGetPixel(uint16_t x, uint16_t y)
398 {
399 // ToDo
400 return 0;
401 }
402
403 /*************************************************/
404 void lcdSetOrientation(lcdOrientation_t orientation)
405 {
406 // ToDo
407 }
408
409 /*************************************************/
410 lcdOrientation_t lcdGetOrientation(void)
411 {
412 return lcdOrientation;
413 }
414
415 /*************************************************/
416 uint16_t lcdGetWidth(void)
417 {
418 return st7735Properties.width;
419 }
420
421 /*************************************************/
422 uint16_t lcdGetHeight(void)
423 {
424 return st7735Properties.height;
425 }
426
427 /*************************************************/
428 void lcdScroll(int16_t pixels, uint16_t fillColor)
429 {
430 // ToDo
431 }
432
433 /*************************************************/
434 uint16_t lcdGetControllerID(void)
435 {
436 // ToDo
437 return 0;
438 }
439
440 /*************************************************/
441 lcdProperties_t lcdGetProperties(void)
442 {
443 return st7735Properties;
444 }
This page took 0.076422 seconds and 5 git commands to generate.