st7735: Added text feature and documentation with license
[contrib/upm.git] / src / st7735 / st7735.cxx
1 /*
2  * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3  * Copyright (c) 2014 Intel Corporation.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 #include <iostream>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "st7735.h"
32
33 using namespace upm;
34
35 ST7735::ST7735 (uint8_t csLCD, uint8_t cSD, uint8_t rs, uint8_t rst) : GFX (160, 128, m_map, font) {
36     maa_init();
37
38     m_csLCD = csLCD;
39     m_cSD   = cSD;
40     m_rST   = rst;
41     m_rS    = rs;
42
43     initModule ();
44     configModule ();
45 }
46
47 ST7735::~ST7735 () {
48     maa_result_t error = MAA_SUCCESS;
49     error = maa_spi_stop(m_spi);
50     if (error != MAA_SUCCESS) {
51         maa_result_print(error);
52     }
53     error = maa_gpio_close (m_csLCDPinCtx);
54     if (error != MAA_SUCCESS) {
55         maa_result_print(error);
56     }
57     error = maa_gpio_close (m_cSDPinCtx);
58     if (error != MAA_SUCCESS) {
59         maa_result_print(error);
60     }
61     error = maa_gpio_close (m_rSTPinCtx);
62     if (error != MAA_SUCCESS) {
63         maa_result_print(error);
64     }
65     error = maa_gpio_close (m_rSPinCtx);
66     if (error != MAA_SUCCESS) {
67         maa_result_print(error);
68     }
69 }
70
71 void
72 ST7735::initModule () {
73     maa_result_t error = MAA_SUCCESS;
74
75     m_height = 160;
76     m_width  = 128;
77
78     m_csLCDPinCtx = maa_gpio_init (m_csLCD);
79     if (m_csLCDPinCtx == NULL) {
80         fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", m_csLCD);
81         exit (1);
82     }
83
84     m_cSDPinCtx = maa_gpio_init (m_cSD);
85     if (m_cSDPinCtx == NULL) {
86         fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", m_cSD);
87         exit (1);
88     }
89
90     m_rSTPinCtx = maa_gpio_init (m_rST);
91     if (m_rSTPinCtx == NULL) {
92         fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", m_rST);
93         exit (1);
94     }
95
96     m_rSPinCtx = maa_gpio_init (m_rS);
97     if (m_rSPinCtx == NULL) {
98         fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", m_rS);
99         exit (1);
100     }
101
102     error = maa_gpio_dir (m_csLCDPinCtx, MAA_GPIO_OUT);
103     if (error != MAA_SUCCESS) {
104         maa_result_print (error);
105     }
106
107     error = maa_gpio_dir (m_cSDPinCtx, MAA_GPIO_OUT);
108     if (error != MAA_SUCCESS) {
109         maa_result_print (error);
110     }
111
112     error = maa_gpio_dir (m_rSTPinCtx, MAA_GPIO_OUT);
113     if (error != MAA_SUCCESS) {
114         maa_result_print (error);
115     }
116
117     error = maa_gpio_dir (m_rSPinCtx, MAA_GPIO_OUT);
118     if (error != MAA_SUCCESS) {
119         maa_result_print (error);
120     }
121
122     m_spi = maa_spi_init (0);
123     error = maa_spi_frequency(m_spi, 15 * 1000000);
124     if (error != MAA_SUCCESS) {
125         maa_result_print (error);
126     }
127
128     lcdCSOn ();
129 }
130
131 void
132 ST7735::write (uint8_t value) {
133     rsLOW ();
134     maa_spi_write (m_spi, value);
135 }
136
137 void
138 ST7735::data (uint8_t value) {
139     rsHIGH ();
140     maa_spi_write (m_spi, value);
141 }
142
143 void
144 ST7735::executeCMDList(const uint8_t *addr) {
145     uint8_t  numCommands, numArgs;
146     uint16_t ms;
147
148     numCommands = *(addr++);           // Number of commands to follow
149     while(numCommands--) {             // For each command...
150         write (*(addr++));             // Read, issue command
151         numArgs  = *(addr++);          // Number of args to follow
152         ms       = numArgs & DELAY;    // If hibit set, delay follows args
153         numArgs &= ~DELAY;             // Mask out delay bit
154         while(numArgs--) {             // For each argument...
155             data (*(addr++));          // Read, issue argument
156         }
157
158         if(ms) {
159             ms = *(addr++);            // Read post-command delay time (ms)
160             if (ms == 255) {
161                 ms = 500;              // If 255, delay for 500 ms
162             }
163             usleep (ms * 1000);
164         }
165     }
166 }
167
168 void
169 ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
170     uint8_t colstart, rowstart;
171     colstart  = rowstart = 0;
172
173     write (ST7735_CASET);                       // Column addr set
174
175     rsHIGH ();
176     m_spiBuffer[0] = 0x00;
177     m_spiBuffer[1] = x0 + colstart;             // XSTART
178     m_spiBuffer[2] = 0x00;
179     m_spiBuffer[3] = x1 + colstart;             // XEND
180     maa_spi_write_buf(m_spi, m_spiBuffer, 4);
181
182     write (ST7735_RASET);                       // Row addr set
183
184     rsHIGH ();
185     m_spiBuffer[0] = 0x00;
186     m_spiBuffer[1] = y0 + rowstart;             // YSTART
187     m_spiBuffer[2] = 0x00;
188     m_spiBuffer[3] = y1 + rowstart;             // YEND
189     maa_spi_write_buf(m_spi, m_spiBuffer, 4);
190
191     write (ST7735_RAMWR);                       // write to RAM
192 }
193
194 void
195 ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) {
196     if (MAA_SUCCESS != setPixel (x, y, color)) {
197         return;
198     }
199
200     refresh ();
201 }
202
203 void
204 ST7735::refresh () {
205     rsHIGH ();
206
207     int fragmentSize = m_height * m_width * 2 / 20;
208     for (int fragment = 0; fragment < 20; fragment++) {
209         maa_spi_write_buf(m_spi, &m_map[fragment * fragmentSize], fragmentSize);
210     }
211 }
212
213 void
214 ST7735::configModule() {
215     rsHIGH ();
216     lcdCSOff ();
217     lcdCSOn ();
218
219     maa_gpio_write (m_rSTPinCtx, HIGH);
220     usleep (500000);
221     maa_gpio_write (m_rSTPinCtx, LOW);
222     usleep (500000);
223     maa_gpio_write (m_rSTPinCtx, HIGH);
224     usleep (500000);
225
226     executeCMDList (Rcmd1);
227     executeCMDList (Rcmd2red);
228     executeCMDList (Rcmd3);
229
230     write (ST7735_MADCTL);
231     data (0xC0);
232
233     setAddrWindow (0, 0, m_width - 1, m_height - 1);
234
235     fillScreen (ST7735_BLACK);
236     refresh ();
237 }
238
239 maa_result_t
240 ST7735::lcdCSOn () {
241     maa_result_t error = MAA_SUCCESS;
242
243     error = maa_gpio_write (m_csLCDPinCtx, LOW);
244     if (error != MAA_SUCCESS) {
245         maa_result_print (error);
246     }
247
248     error = maa_gpio_write (m_cSDPinCtx, HIGH);
249     if (error != MAA_SUCCESS) {
250         maa_result_print (error);
251     }
252
253     return error;
254 }
255
256 maa_result_t
257 ST7735::lcdCSOff () {
258     maa_result_t error = MAA_SUCCESS;
259
260     error = maa_gpio_write (m_csLCDPinCtx, HIGH);
261     if (error != MAA_SUCCESS) {
262         maa_result_print (error);
263     }
264
265     return error;
266 }
267
268 maa_result_t
269 ST7735::sdCSOn () {
270     maa_result_t error = MAA_SUCCESS;
271
272     error = maa_gpio_write (m_cSDPinCtx, LOW);
273     if (error != MAA_SUCCESS) {
274         maa_result_print (error);
275     }
276
277     error = maa_gpio_write (m_csLCDPinCtx, HIGH);
278     if (error != MAA_SUCCESS) {
279         maa_result_print (error);
280     }
281
282     return error;
283 }
284
285 maa_result_t
286 ST7735::sdCSOff () {
287     maa_result_t error = MAA_SUCCESS;
288
289     error = maa_gpio_write (m_cSDPinCtx, HIGH);
290     if (error != MAA_SUCCESS) {
291         maa_result_print (error);
292     }
293
294     return error;
295 }
296
297 maa_result_t
298 ST7735::rsHIGH () {
299     maa_result_t error = MAA_SUCCESS;
300
301     error = maa_gpio_write (m_rSPinCtx, HIGH);
302     if (error != MAA_SUCCESS) {
303         maa_result_print (error);
304     }
305
306     return error;
307 }
308
309 maa_result_t
310 ST7735::rsLOW () {
311     maa_result_t error = MAA_SUCCESS;
312
313     error = maa_gpio_write (m_rSPinCtx, LOW);
314     if (error != MAA_SUCCESS) {
315         maa_result_print (error);
316     }
317
318     return error;
319 }