See changelog v0.9.8
[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 };
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 Returns the 16-bit (4-hexdigit) controller code
109 */
110 /**************************************************************************/
111 uint16_t ssd1351Type(void)
112 {
113 return 0x1351;
114 }
115
116 /**************************************************************************/
117 /*!
118 @brief Sets the cursor to the specified X/Y position
119 */
120 /**************************************************************************/
121 void ssd1351SetCursor(uint8_t x, uint8_t y)
122 {
123 if ((x >= ssd1351Properties.width) || (y >= ssd1351Properties.height))
124 return;
125
126 CMD(SSD1351_CMD_WRITERAM);
127 CMD(SSD1351_CMD_SETCOLUMNADDRESS);
128 DATA(x); // Start Address
129 DATA(ssd1351Properties.width-1); // End Address (0x7F)
130
131 CMD(SSD1351_CMD_SETROWADDRESS);
132 DATA(y); // Start Address
133 DATA(ssd1351Properties.height-1); // End Address (0x7F)
134 CMD(SSD1351_CMD_WRITERAM);
135 }
136
137 /*************************************************/
138 /* Public Methods */
139 /*************************************************/
140
141 /**************************************************************************/
142 /*!
143 @brief Configures any pins or HW and initialises the LCD controller
144 */
145 /**************************************************************************/
146 void lcdInit(void)
147 {
148 // Set all pins to output
149 gpioSetDir(SSD1351_SCK_PORT, SSD1351_SCK_PIN, gpioDirection_Output);
150 gpioSetDir(SSD1351_SID_PORT, SSD1351_SID_PIN, gpioDirection_Output);
151 gpioSetDir(SSD1351_RST_PORT, SSD1351_RST_PIN, gpioDirection_Output);
152 gpioSetDir(SSD1351_CS_PORT, SSD1351_CS_PIN, gpioDirection_Output);
153
154 #if !defined SSD1351_BUS_SPI3
155 gpioSetDir(SSD1351_DC_PORT, SSD1351_DC_PIN, gpioDirection_Output);
156 #endif
157
158 // Reset the LCD
159 SET_RST;
160 DELAY(20);
161 CLR_RST;
162 DELAY(200);
163 SET_RST;
164 DELAY(20);
165
166 // Disable pullups
167 SSD1351_DISABLEPULLUPS();
168
169 CMD(SSD1351_CMD_SETCOMMANDLOCK);
170 DATA(0x12); // Unlocked to enter commands
171 CMD(SSD1351_CMD_SETCOMMANDLOCK);
172 DATA(0xB1); // Make all commands accessible
173 CMD(SSD1351_CMD_SLEEPMODE_DISPLAYOFF);
174 CMD(SSD1351_CMD_SETFRONTCLOCKDIV);
175 DATA(0xF1);
176 CMD(SSD1351_CMD_SETMUXRRATIO);
177 DATA(0x7F);
178 CMD(SSD1351_CMD_COLORDEPTH);
179 DATA(0x74); // Bit 7:6 = 65,536 Colors, Bit 3 = BGR or RGB
180 CMD(SSD1351_CMD_SETCOLUMNADDRESS);
181 DATA(0x00);
182 DATA(0x7F);
183 CMD(SSD1351_CMD_SETROWADDRESS);
184 DATA(0x00);
185 DATA(0x7F);
186 CMD(SSD1351_CMD_SETDISPLAYSTARTLINE);
187 DATA(0x00);
188 CMD(SSD1351_CMD_SETDISPLAYOFFSET);
189 DATA(0x00);
190 CMD(SSD1351_CMD_SETGPIO);
191 DATA(0x00); // Disable GPIO pins
192 CMD(SSD1351_CMD_FUNCTIONSELECTION);
193 DATA(0x01); // External VDD (0 = External, 1 = Internal)
194 CMD(SSD1351_CMD_SETPHASELENGTH);
195 DATA(0x32);
196 CMD(SSD1351_CMD_SETSEGMENTLOWVOLTAGE);
197 DATA(0xA0); // Enable External VSL
198 DATA(0xB5);
199 DATA(0x55);
200 CMD(SSD1351_CMD_SETPRECHARGEVOLTAGE);
201 DATA(0x17);
202 CMD(SSD1351_CMD_SETVCOMHVOLTAGE);
203 DATA(0x05);
204 CMD(SSD1351_CMD_SETCONTRAST);
205 DATA(0xC8);
206 DATA(0x80);
207 DATA(0xC8);
208 CMD(SSD1351_CMD_MASTERCONTRAST);
209 DATA(0x0F); // Maximum contrast
210 CMD(SSD1351_CMD_SETSECONDPRECHARGEPERIOD);
211 DATA(0x01);
212 CMD(SSD1351_CMD_SETDISPLAYMODE_RESET);
213
214 // Use default grayscale for now to save flash space, but here are
215 // the values if someone wants to change them ...
216 // CMD(SSD1351_CMD_GRAYSCALELOOKUP);
217 // DATA(0x02);
218 // DATA(0x03);
219 // DATA(0x04);
220 // DATA(0x05);
221 // DATA(0x06);
222 // DATA(0x07);
223 // DATA(0x08);
224 // DATA(0x09);
225 // DATA(0x0A);
226 // DATA(0x0B);
227 // DATA(0x0C);
228 // DATA(0x0D);
229 // DATA(0x0E);
230 // DATA(0x0F);
231 // DATA(0x10);
232 // DATA(0x11);
233 // DATA(0x12);
234 // DATA(0x13);
235 // DATA(0x15);
236 // DATA(0x17);
237 // DATA(0x19);
238 // DATA(0x1B);
239 // DATA(0x1D);
240 // DATA(0x1F);
241 // DATA(0x21);
242 // DATA(0x23);
243 // DATA(0x25);
244 // DATA(0x27);
245 // DATA(0x2A);
246 // DATA(0x2D);
247 // DATA(0x30);
248 // DATA(0x33);
249 // DATA(0x36);
250 // DATA(0x39);
251 // DATA(0x3C);
252 // DATA(0x3F);
253 // DATA(0x42);
254 // DATA(0x45);
255 // DATA(0x48);
256 // DATA(0x4C);
257 // DATA(0x50);
258 // DATA(0x54);
259 // DATA(0x58);
260 // DATA(0x5C);
261 // DATA(0x60);
262 // DATA(0x64);
263 // DATA(0x68);
264 // DATA(0x6C);
265 // DATA(0x70);
266 // DATA(0x74);
267 // DATA(0x78);
268 // DATA(0x7D);
269 // DATA(0x82);
270 // DATA(0x87);
271 // DATA(0x8C);
272 // DATA(0x91);
273 // DATA(0x96);
274 // DATA(0x9B);
275 // DATA(0xA0);
276 // DATA(0xA5);
277 // DATA(0xAA);
278 // DATA(0xAF);
279 // DATA(0xBF);
280
281 // Clear screen
282 lcdFillRGB(COLOR_RED);
283
284 // Turn the display on
285 CMD(SSD1351_CMD_SLEEPMODE_DISPLAYON);
286 }
287
288 /**************************************************************************/
289 /*!
290 @brief Enables or disables the LCD backlight
291 */
292 /**************************************************************************/
293 void lcdBacklight(bool state)
294 {
295 // No backlight ... do nothing
296 }
297
298 /**************************************************************************/
299 /*!
300 @brief Renders a simple test pattern on the LCD
301 */
302 /**************************************************************************/
303 void lcdTest(void)
304 {
305 uint32_t i,j;
306 CMD(SSD1351_CMD_WRITERAM);
307 ssd1351SetCursor(0, 0);
308 CMD(SSD1351_CMD_WRITERAM);
309
310 for(i=0;i<128;i++)
311 {
312 for(j=0;j<128;j++)
313 {
314 if(i>111){DATA(COLOR_WHITE>>8);DATA((uint8_t)COLOR_WHITE);}
315 else if(i>95){DATA(COLOR_BLUE>>8);DATA((uint8_t)COLOR_BLUE);}
316 else if(i>79){DATA(COLOR_GREEN>>8);DATA((uint8_t)COLOR_GREEN);}
317 else if(i>63){DATA(COLOR_CYAN>>8);DATA((uint8_t)COLOR_CYAN);}
318 else if(i>47){DATA(COLOR_RED>>8);DATA((uint8_t)COLOR_RED);}
319 else if(i>31){DATA(COLOR_MAGENTA>>8);DATA((uint8_t)COLOR_MAGENTA);}
320 else if(i>15){DATA(COLOR_YELLOW>>8);DATA((uint8_t)COLOR_YELLOW);}
321 else {DATA(COLOR_BLACK>>8);DATA((uint8_t)COLOR_BLACK);}
322 }
323 }
324 }
325
326 /**************************************************************************/
327 /*!
328 @brief Fills the LCD with the specified 16-bit color
329 */
330 /**************************************************************************/
331 void lcdFillRGB(uint16_t data)
332 {
333 uint16_t i;
334 ssd1351SetCursor(0, 0);
335 for (i=1; i<=((ssd1351Properties.width)*(ssd1351Properties.height)) * 2;i++)
336 {
337 DATA(data >> 8);
338 DATA(data);
339 }
340 }
341
342 /**************************************************************************/
343 /*!
344 @brief Draws a single pixel at the specified X/Y location
345 */
346 /**************************************************************************/
347 void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
348 {
349 if ((x >= ssd1351Properties.width) || (y >= ssd1351Properties.height))
350 return;
351
352 ssd1351SetCursor((uint8_t)x, (uint8_t)y);
353 DATA(color >> 8);
354 DATA(color);
355 }
356
357 /**************************************************************************/
358 /*!
359 @brief Draws an array of consecutive RGB565 pixels (much
360 faster than addressing each pixel individually)
361 */
362 /**************************************************************************/
363 void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
364 {
365 // ToDo
366 }
367
368 /**************************************************************************/
369 /*!
370 @brief Optimised routine to draw a horizontal line faster than
371 setting individual pixels
372 */
373 /**************************************************************************/
374 void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
375 {
376 // ToDo
377 }
378
379 /**************************************************************************/
380 /*!
381 @brief Optimised routine to draw a vertical line faster than
382 setting individual pixels
383 */
384 /**************************************************************************/
385 void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
386 {
387 // ToDo
388 }
389
390 /**************************************************************************/
391 /*!
392 @brief Gets the 16-bit color of the pixel at the specified location
393 */
394 /**************************************************************************/
395 uint16_t lcdGetPixel(uint16_t x, uint16_t y)
396 {
397 // ToDo
398 return 0;
399 }
400
401 /**************************************************************************/
402 /*!
403 @brief Sets the LCD orientation to horizontal and vertical
404 */
405 /**************************************************************************/
406 void lcdSetOrientation(lcdOrientation_t orientation)
407 {
408 // Not supported
409 }
410
411 /**************************************************************************/
412 /*!
413 @brief Gets the current screen orientation (horizontal or vertical)
414 */
415 /**************************************************************************/
416 lcdOrientation_t lcdGetOrientation(void)
417 {
418 return lcdOrientation;
419 }
420
421 /**************************************************************************/
422 /*!
423 @brief Gets the width in pixels of the LCD screen (varies depending
424 on the current screen orientation)
425 */
426 /**************************************************************************/
427 uint16_t lcdGetWidth(void)
428 {
429 return ssd1351Properties.width;
430 }
431
432 /**************************************************************************/
433 /*!
434 @brief Gets the height in pixels of the LCD screen (varies depending
435 on the current screen orientation)
436 */
437 /**************************************************************************/
438 uint16_t lcdGetHeight(void)
439 {
440 return ssd1351Properties.height;
441 }
442
443 /**************************************************************************/
444 /*!
445 @brief Scrolls the contents of the LCD screen vertically the
446 specified number of pixels using a HW optimised routine
447 */
448 /**************************************************************************/
449 void lcdScroll(int16_t pixels, uint16_t fillColor)
450 {
451 // ToDo
452 }
453
454 /**************************************************************************/
455 /*!
456 @brief Gets the controller's 16-bit (4 hexdigit) ID
457 */
458 /**************************************************************************/
459 uint16_t lcdGetControllerID(void)
460 {
461 return ssd1351Type();
462 }
463
464 /**************************************************************************/
465 /*!
466 @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs
467 generic capabilities and dimensions
468 */
469 /**************************************************************************/
470 lcdProperties_t lcdGetProperties(void)
471 {
472 return ssd1351Properties;
473 }
This page took 0.089102 seconds and 5 git commands to generate.