Prep for v1.2.0
[hackover2013-badge-firmware.git] / drivers / displays / tft / hw / ssd1351.c
1 /**************************************************************************/
2 /*!
3 @file SSD1351.c
4 @author K. Townsend (www.adafruit.com)
5
6 @section DESCRIPTION
7
8 Driver for SSD1351 128x128 pixel RGB OLED displays.
9
10 This driver uses a 3 or 4-pin SPI interface and 16-bit RGB565 colours.
11
12 @section LICENSE
13
14 Software License Agreement (BSD License)
15
16 Copyright (c) 2012, Adafruit Industries
17 All rights reserved.
18
19 Redistribution and use in source and binary forms, with or without
20 modification, are permitted provided that the following conditions are met:
21 1. Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23 2. Redistributions in binary form must reproduce the above copyright
24 notice, this list of conditions and the following disclaimer in the
25 documentation and/or other materials provided with the distribution.
26 3. Neither the name of the copyright holders nor the
27 names of its contributors may be used to endorse or promote products
28 derived from this software without specific prior written permission.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41 /**************************************************************************/
42 #include "ssd1351.h"
43 #include "core/systick/systick.h"
44
45 static volatile lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT;
46 static lcdProperties_t ssd1351Properties = { 128, 128, false, false, false, true, false };
47
48 /*************************************************/
49 /* Private Methods */
50 /*************************************************/
51
52 #define CMD(c) do { SET_CS; CLR_CS; CLR_DC; ssd1351SendByte( c, 1 ); SET_CS; } while (0)
53 #define DATA(c) do { SET_CS; CLR_CS; SET_DC; ssd1351SendByte( c, 0 ); SET_CS; } while (0)
54 #define DELAY(mS) do { systickDelay( mS / CFG_SYSTICK_DELAY_IN_MS ); } while(0)
55
56 /**************************************************************************/
57 /*!
58 @brief Simulates an SPI write using GPIO.
59
60 @param[in] byte
61 The byte to send
62 @param[in] command
63 1 if this is a command, 0 if it is data
64 */
65 /**************************************************************************/
66 void ssd1351SendByte(uint8_t byte, uint8_t command)
67 {
68 int8_t i;
69
70 // Make sure clock pin starts high
71 SET_SCK;
72
73 #if defined SSD1351_BUS_SPI3
74 // Prepend D/C bit (cmd = 0, data = 1)
75 CLR_SCK;
76 if (command)
77 {
78 CLR_SID;
79 }
80 else
81 {
82 SET_SID;
83 }
84 SET_SCK;
85 #endif
86
87 // Write from MSB to LSB
88 for (i=7; i>=0; i--)
89 {
90 // Set clock pin low
91 CLR_SCK;
92 // Set data pin high or low depending on the value of the current bit
93 if (byte & (1 << i))
94 {
95 SET_SID;
96 }
97 else
98 {
99 CLR_SID;
100 }
101 // Set clock pin high
102 SET_SCK;
103 }
104 }
105
106 /**************************************************************************/
107 /*!
108 @brief Sets the cursor to the specified X/Y position
109 */
110 /**************************************************************************/
111 void ssd1351SetCursor(uint8_t x, uint8_t y)
112 {
113 if ((x >= ssd1351Properties.width) || (y >= ssd1351Properties.height))
114 return;
115
116 CMD(SSD1351_CMD_SETCOLUMNADDRESS);
117 DATA(x); // Start Address
118 DATA(ssd1351Properties.width-1); // End Address (0x7F)
119
120 CMD(SSD1351_CMD_SETROWADDRESS);
121 DATA(y); // Start Address
122 DATA(ssd1351Properties.height-1); // End Address (0x7F)
123 }
124
125 /**************************************************************************/
126 /*!
127 @brief Sets the cursor to 0, 0 and resets the window size
128 */
129 /**************************************************************************/
130 void ssd1351GoHome(void)
131 {
132 ssd1351SetCursor(0, 0);
133 }
134
135 /*************************************************/
136 /* Public Methods */
137 /*************************************************/
138
139 /**************************************************************************/
140 /*!
141 @brief Configures any pins or HW and initialises the LCD controller
142 */
143 /**************************************************************************/
144 void lcdInit(void)
145 {
146 // Set all pins to output
147 gpioSetDir(SSD1351_SCK_PORT, SSD1351_SCK_PIN, gpioDirection_Output);
148 gpioSetDir(SSD1351_SID_PORT, SSD1351_SID_PIN, gpioDirection_Output);
149 gpioSetDir(SSD1351_RST_PORT, SSD1351_RST_PIN, gpioDirection_Output);
150 gpioSetDir(SSD1351_CS_PORT, SSD1351_CS_PIN, gpioDirection_Output);
151
152 #if !defined SSD1351_BUS_SPI3
153 gpioSetDir(SSD1351_DC_PORT, SSD1351_DC_PIN, gpioDirection_Output);
154 #endif
155
156 // Make sure CS starts low
157 // CLR_CS;
158
159 // Reset the LCD
160 SET_RST;
161 DELAY(20);
162 CLR_RST;
163 DELAY(200);
164 SET_RST;
165 DELAY(20);
166
167 // Disable internal pullup resistors
168 SSD1351_DISABLEPULLUPS();
169
170 CMD(SSD1351_CMD_SETCOMMANDLOCK);
171 DATA(0x12); // Unlocked to enter commands
172
173 CMD(SSD1351_CMD_SETCOMMANDLOCK);
174 DATA(0xB1); // Make all commands accessible
175
176 CMD(SSD1351_CMD_SLEEPMODE_DISPLAYOFF);
177
178 CMD(SSD1351_CMD_SETFRONTCLOCKDIV);
179 DATA(0xF1); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
180
181 CMD(SSD1351_CMD_SETMUXRRATIO);
182 DATA(0x7F);
183
184 CMD(SSD1351_CMD_COLORDEPTH);
185 DATA(0x74); // Bit 7:6 = 65,536 Colors, Bit 3 = BGR or RGB
186
187 CMD(SSD1351_CMD_SETCOLUMNADDRESS);
188 DATA(0x00);
189 DATA(0x7F);
190
191 CMD(SSD1351_CMD_SETROWADDRESS);
192 DATA(0x00);
193 DATA(0x7F);
194
195 CMD(SSD1351_CMD_SETDISPLAYSTARTLINE);
196 DATA(0x00);
197
198 CMD(SSD1351_CMD_SETDISPLAYOFFSET);
199 DATA(0x00);
200
201 CMD(SSD1351_CMD_SETGPIO);
202 DATA(0x00); // Disable GPIO pins
203
204 CMD(SSD1351_CMD_FUNCTIONSELECTION);
205 DATA(0x01); // External VDD (1 = External bias using diode drop, 0 = internal)
206
207 CMD(SSD1351_CMD_SETPHASELENGTH);
208 DATA(0x32);
209
210 CMD(SSD1351_CMD_SETPRECHARGEVOLTAGE);
211 DATA(0x32); // was 0x17
212
213 CMD(SSD1351_CMD_SETVCOMHVOLTAGE);
214 DATA(0x05);
215
216 CMD(SSD1351_CMD_SETDISPLAYMODE_RESET);
217
218 CMD(SSD1351_CMD_SETCONTRAST);
219 DATA(0xC8);
220 DATA(0x80);
221 DATA(0xC8);
222
223 CMD(SSD1351_CMD_MASTERCONTRAST);
224 DATA(0x0F); // Maximum contrast
225
226 CMD(SSD1351_CMD_SETSEGMENTLOWVOLTAGE);
227 DATA(0xA0); // Enable External VSL
228 DATA(0xB5);
229 DATA(0x55);
230
231 CMD(SSD1351_CMD_SETSECONDPRECHARGEPERIOD);
232 DATA(0x01);
233
234 // Use default grayscale for now to save flash space, but here are
235 // the values if someone wants to change them ...
236 // CMD(SSD1351_CMD_GRAYSCALELOOKUP);
237 // DATA(0x02);
238 // DATA(0x03);
239 // DATA(0x04);
240 // DATA(0x05);
241 // DATA(0x06);
242 // DATA(0x07);
243 // DATA(0x08);
244 // DATA(0x09);
245 // DATA(0x0A);
246 // DATA(0x0B);
247 // DATA(0x0C);
248 // DATA(0x0D);
249 // DATA(0x0E);
250 // DATA(0x0F);
251 // DATA(0x10);
252 // DATA(0x11);
253 // DATA(0x12);
254 // DATA(0x13);
255 // DATA(0x15);
256 // DATA(0x17);
257 // DATA(0x19);
258 // DATA(0x1B);
259 // DATA(0x1D);
260 // DATA(0x1F);
261 // DATA(0x21);
262 // DATA(0x23);
263 // DATA(0x25);
264 // DATA(0x27);
265 // DATA(0x2A);
266 // DATA(0x2D);
267 // DATA(0x30);
268 // DATA(0x33);
269 // DATA(0x36);
270 // DATA(0x39);
271 // DATA(0x3C);
272 // DATA(0x3F);
273 // DATA(0x42);
274 // DATA(0x45);
275 // DATA(0x48);
276 // DATA(0x4C);
277 // DATA(0x50);
278 // DATA(0x54);
279 // DATA(0x58);
280 // DATA(0x5C);
281 // DATA(0x60);
282 // DATA(0x64);
283 // DATA(0x68);
284 // DATA(0x6C);
285 // DATA(0x70);
286 // DATA(0x74);
287 // DATA(0x78);
288 // DATA(0x7D);
289 // DATA(0x82);
290 // DATA(0x87);
291 // DATA(0x8C);
292 // DATA(0x91);
293 // DATA(0x96);
294 // DATA(0x9B);
295 // DATA(0xA0);
296 // DATA(0xA5);
297 // DATA(0xAA);
298 // DATA(0xAF);
299 // DATA(0xBF);
300
301 // Clear screen
302 lcdFillRGB(COLOR_BLACK);
303
304 // Turn the display on
305 CMD(SSD1351_CMD_SLEEPMODE_DISPLAYON);
306 }
307
308 /**************************************************************************/
309 /*!
310 @brief Enables or disables the LCD backlight
311 */
312 /**************************************************************************/
313 void lcdBacklight(bool state)
314 {
315 // No backlight ... do nothing
316 }
317
318 /**************************************************************************/
319 /*!
320 @brief Renders a simple test pattern on the LCD
321 */
322 /**************************************************************************/
323 void lcdTest(void)
324 {
325 uint32_t i,j;
326 CMD(SSD1351_CMD_WRITERAM);
327 ssd1351SetCursor(0, 0);
328 CMD(SSD1351_CMD_WRITERAM);
329
330 for(i=0;i<128;i++)
331 {
332 for(j=0;j<128;j++)
333 {
334 if(i>111){DATA(COLOR_WHITE>>8);DATA((uint8_t)COLOR_WHITE);}
335 else if(i>95){DATA(COLOR_BLUE>>8);DATA((uint8_t)COLOR_BLUE);}
336 else if(i>79){DATA(COLOR_GREEN>>8);DATA((uint8_t)COLOR_GREEN);}
337 else if(i>63){DATA(COLOR_CYAN>>8);DATA((uint8_t)COLOR_CYAN);}
338 else if(i>47){DATA(COLOR_RED>>8);DATA((uint8_t)COLOR_RED);}
339 else if(i>31){DATA(COLOR_MAGENTA>>8);DATA((uint8_t)COLOR_MAGENTA);}
340 else if(i>15){DATA(COLOR_YELLOW>>8);DATA((uint8_t)COLOR_YELLOW);}
341 else {DATA(COLOR_BLACK>>8);DATA((uint8_t)COLOR_BLACK);}
342 }
343 }
344 }
345
346 /**************************************************************************/
347 /*!
348 @brief Fills the LCD with the specified 16-bit color
349 */
350 /**************************************************************************/
351 void lcdFillRGB(uint16_t data)
352 {
353 uint16_t i;
354 ssd1351SetCursor(0, 0);
355 CMD(SSD1351_CMD_WRITERAM);
356 for (i=1; i<=((ssd1351Properties.width)*(ssd1351Properties.height)) * 2;i++)
357 {
358 DATA(data >> 8);
359 DATA(data);
360 }
361 }
362
363 /**************************************************************************/
364 /*!
365 @brief Draws a single pixel at the specified X/Y location
366 */
367 /**************************************************************************/
368 void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
369 {
370 if ((x >= ssd1351Properties.width) || (y >= ssd1351Properties.height))
371 return;
372
373 ssd1351SetCursor((uint8_t)x, (uint8_t)y);
374 CMD(SSD1351_CMD_WRITERAM);
375 DATA(color >> 8);
376 DATA(color);
377 }
378
379 /**************************************************************************/
380 /*!
381 @brief Draws an array of consecutive RGB565 pixels (much
382 faster than addressing each pixel individually)
383 */
384 /**************************************************************************/
385 void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
386 {
387 // ToDo
388 }
389
390 /**************************************************************************/
391 /*!
392 @brief Optimised routine to draw a horizontal line faster than
393 setting individual pixels
394 */
395 /**************************************************************************/
396 void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
397 {
398 // Allows for slightly better performance than setting individual pixels
399 uint16_t x, pixels;
400
401 if (x1 < x0)
402 {
403 // Switch x1 and x0
404 x = x1;
405 x1 = x0;
406 x0 = x;
407 }
408
409 // Check limits
410 if (x1 >= ssd1351Properties.width)
411 {
412 x1 = ssd1351Properties.width - 1;
413 }
414 if (x0 >= ssd1351Properties.width)
415 {
416 x0 = ssd1351Properties.width - 1;
417 }
418
419 ssd1351SetCursor(x0, y);
420 CMD(SSD1351_CMD_WRITERAM);
421 for (pixels = 0; pixels < x1 - x0 + 1; pixels++)
422 {
423 DATA(color >> 8);
424 DATA(color);
425 }
426 ssd1351GoHome();
427 }
428
429 /**************************************************************************/
430 /*!
431 @brief Optimised routine to draw a vertical line faster than
432 setting individual pixels
433 */
434 /**************************************************************************/
435 void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
436 {
437 // Not supported
438 }
439
440 /**************************************************************************/
441 /*!
442 @brief Gets the 16-bit color of the pixel at the specified location
443 */
444 /**************************************************************************/
445 uint16_t lcdGetPixel(uint16_t x, uint16_t y)
446 {
447 // Not supported
448 return 0;
449 }
450
451 /**************************************************************************/
452 /*!
453 @brief Sets the LCD orientation to horizontal and vertical
454 */
455 /**************************************************************************/
456 void lcdSetOrientation(lcdOrientation_t orientation)
457 {
458 // Not supported
459 }
460
461 /**************************************************************************/
462 /*!
463 @brief Gets the current screen orientation (horizontal or vertical)
464 */
465 /**************************************************************************/
466 lcdOrientation_t lcdGetOrientation(void)
467 {
468 return lcdOrientation;
469 }
470
471 /**************************************************************************/
472 /*!
473 @brief Gets the width in pixels of the LCD screen (varies depending
474 on the current screen orientation)
475 */
476 /**************************************************************************/
477 uint16_t lcdGetWidth(void)
478 {
479 return ssd1351Properties.width;
480 }
481
482 /**************************************************************************/
483 /*!
484 @brief Gets the height in pixels of the LCD screen (varies depending
485 on the current screen orientation)
486 */
487 /**************************************************************************/
488 uint16_t lcdGetHeight(void)
489 {
490 return ssd1351Properties.height;
491 }
492
493 /**************************************************************************/
494 /*!
495 @brief Scrolls the contents of the LCD screen vertically the
496 specified number of pixels using a HW optimised routine
497 */
498 /**************************************************************************/
499 void lcdScroll(int16_t pixels, uint16_t fillColor)
500 {
501 // Not Supported
502 }
503
504 /**************************************************************************/
505 /*!
506 @brief Gets the controller's 16-bit (4 hexdigit) ID
507 */
508 /**************************************************************************/
509 uint16_t lcdGetControllerID(void)
510 {
511 return 0x1351;
512 }
513
514 /**************************************************************************/
515 /*!
516 @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs
517 generic capabilities and dimensions
518 */
519 /**************************************************************************/
520 lcdProperties_t lcdGetProperties(void)
521 {
522 return ssd1351Properties;
523 }
This page took 0.072619 seconds and 5 git commands to generate.