YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
st7735s_drv.cpp
1/*
2 * st7735s.cpp
3 *
4 * Created on: 29.02.2016
5 * Author: Andreas Terstegge
6 */
7
8#include "st7735s_drv.h"
9#include "pixel_stream_const.h"
10#include "task.h"
11
12// Hardware Configurations
14st7735s_drv::config st7735s_drv::Crystalfontz_128x128(
15 128, 128, 132, 132, 2, 1, st7735s_drv::BGR_COLOR_FILTER);
16
17// ST7735s Commands
19
20// Read Commands
22#define CMD_RDDID 0x04 // Read Display ID
23#define CMD_RDDST 0x09 // Read Display Status
24#define CMD_RDDPM 0x0A // Read Display Power Mode
25#define CMD_RDDMADCTL 0x0B // Read Display MADCTL
26#define CMD_RDDCOLMOD 0x0C // Read Display Pixel Format (Color Mode)
27#define CMD_RDDIM 0x0D // Read Display Image Mode
28#define CMD_RDDSM 0x0E // Read Display Signal Mode
29#define CMD_RDDSDR 0x0F // Read Display Self-Diagnostic Result
30#define CMD_RAMRD 0x2E // Memory Read
31#define CMD_RDID1 0xDA // Read ID1 Value
32#define CMD_RDID2 0xDB // Read ID2 Value
33#define CMD_RDID3 0xDC // Read ID3 Value
34
35// Write Commands
37#define CMD_NOP 0x00 // Non operation
38#define CMD_SWRESET 0x01 // Soft Reset
39#define CMD_SLPIN 0x10 // Sleep On (120ms)
40#define CMD_SLPOUT 0x11 // Sleep Off (120ms)
41#define CMD_PTLON 0x12 // Partial Display Mode On
42#define CMD_NORON 0x13 // Normal Display Mode On
43#define CMD_INVOFF 0x20 // Display Inversion Off
44#define CMD_INVON 0x21 // Display Inversion On
45#define CMD_GAMSET 0x26 // Gamma Set
46#define CMD_DISPOFF 0x28 // Display Off
47#define CMD_DISPON 0x29 // Display On
48#define CMD_CASET 0x2A // Column Address Set
49#define CMD_RASET 0x2B // Row Address Set
50#define CMD_RAMWR 0x2C // Memory Write
51#define CMD_RGBSET 0x2D // Color Setting for 4K, 65K, 262K
52#define CMD_PTLAR 0x30 // Partial Area
53#define CMD_SCRLAR 0x33 // Scroll Area Set
54#define CMD_TEOFF 0x34 // Tearing Effect Line Off
55#define CMD_TEON 0x35 // Tearing Effect Line On
56#define CMD_MADCTL 0x36 // Memory Data Access Control
57#define CMD_VSCSAD 0x37 // Vertical Scroll Start Address of RAM
58#define CMD_IDMOFF 0x38 // Idle Mode Off
59#define CMD_IDMON 0x39 // Idle Mode On
60#define CMD_COLMOD 0x3A // Interface Pixel Format
61
62// Panel Function Command List
64#define CMD_FRMCTR1 0xB1 // Frame Rate Control (in normal mode/Full colors)
65#define CMD_FRMCTR2 0xB2 // Frame Rate Control (in Idle mode/8-colors)
66#define CMD_FRMCTR3 0xB3 // Frame Rate Control (in Partial mode/full colors)
67#define CMD_INVCTR 0xB4 // Display Inversion Control
68#define CMD_PWCTR1 0xC0 // Power Control 1
69#define CMD_PWCTR2 0xC1 // Power Control 2
70#define CMD_PWCTR3 0xC2 // Power Control 3 (in normal mode/Full colors)
71#define CMD_PWCTR4 0xC3 // Power Control 4 (in Idle mode/8-colors)
72#define CMD_PWCTR5 0xC4 // Power Control 5 (in Partial mode/full colors)
73#define CMD_VMCTR1 0xC5 // VCOM Control 1
74#define CMD_VMOFCTR 0xC7 // VCOM Offset Control
75#define CMD_WRID2 0xD1 // Write ID2 Value
76#define CMD_WRID3 0xD2 // Write ID3 Value
77#define CMD_NVCTR1 0xD9 // NVM Control Status
78#define CMD_NVCTR2 0xDE // NVM Read Command
79#define CMD_NVCTR3 0xDF // NWM Write Command
80#define CMD_GAMCTRP1 0xE0 // Gamma ('+' polarity) Correction Characteristics Setting
81#define CMD_GAMCTRN1 0xE1 // Gamma ('-' polarity) Correction Characteristics Setting
82#define CMD_GCV 0xFC // Gate Pump Clock Frequency Variable
83
84st7735s_drv::st7735s_drv(spi_interface & spi, gpio_interface & rst_pin,
85 gpio_interface & dc_pin, config & lcd,
87 : _spi(spi), _rst_pin(rst_pin), _dc_pin(dc_pin), _lcd(lcd), _mutex(mutex)
88{
89
90 // Initialize Reset & D/C pins
91 _rst_pin.gpioMode(GPIO::OUTPUT | GPIO::INIT_HIGH);
92 _dc_pin. gpioMode(GPIO::OUTPUT | GPIO::INIT_HIGH);
93
94 // Make a HW-reset
95 _rst_pin.gpioWrite(LOW);
96 task::sleep_ms(10);
97 _rst_pin.gpioWrite(HIGH);
98 task::sleep_ms(300);
99
100 // if (_mutex) _mutex->lock();
101
102 writeCommand(CMD_SLPOUT); // Wake up ...
103 task::sleep_ms(150);
104
105 writeCommand(CMD_GAMSET);
106 writeData(0x03);
107
108 writeCommand(CMD_COLMOD);
109 writeData(0x05);
110
111 writeCommand(CMD_SCRLAR);
112 writeData(0);
113 writeData(_lcd.offsetY);
114 writeData(0);
115 writeData(_lcd.sizeY);
116 writeData(0);
117 writeData(_lcd.sizeRamY - _lcd.sizeY - _lcd.offsetY);
118
119 setOrientation(UP);
120 _first_row = 0;
121 scroll(0);
122
123 writeCommand(CMD_DISPON);
124
125 // if (_mutex) _mutex->unlock();
126}
127
128st7735s_drv::~st7735s_drv()
129{
130}
131
132uint16_t st7735s_drv::getSizeX()
133{
134 if ((_orientation == UP) || (_orientation == DOWN))
135 return _lcd.sizeX;
136 else
137 return _lcd.sizeY;
138}
139
140uint16_t st7735s_drv::getSizeY()
141{
142 if ((_orientation == UP) || (_orientation == DOWN))
143 return _lcd.sizeY;
144 else
145 return _lcd.sizeX;
146}
147
148void st7735s_drv::setOrientation(Orientation o)
149{
150 _orientation = o;
151 uint8_t madctl = (_lcd.flags & BGR_COLOR_FILTER) ? 0x8 : 0;
152 if (_mutex)
153 _mutex->lock();
154 writeCommand(CMD_MADCTL);
155 switch (o)
156 {
157 case UP:
158 writeData(madctl | 0xC0);
159 break;
160 case DOWN:
161 writeData(madctl);
162 break;
163 case LEFT:
164 writeData(madctl | 0xA0);
165 break;
166 case RIGHT:
167 writeData(madctl | 0x60);
168 break;
169 }
170 if (_mutex)
171 _mutex->unlock();
172}
173
174void st7735s_drv::drawPixel(uint16_t x, uint16_t y, color_t c)
175{
176 color_t color = convertColor(c, LCD::COLORTYPE_RGB565);
177 change(x, y);
178 if (_mutex)
179 _mutex->lock();
180 setFrame(x, y, x, y);
181 writeCommand(CMD_RAMWR);
182 _tx_buffer[0] = color >> 8;
183 _tx_buffer[1] = color & 0xff;
184 writeDataBuffer(2);
185 if (_mutex)
186 _mutex->unlock();
187}
188
189void st7735s_drv::drawHLine(uint16_t xs, uint16_t y, uint16_t xe, color_t c)
190{
191 color_t color = convertColor(c, LCD::COLORTYPE_RGB565);
192 uint16_t dummy;
193 change(xs, y);
194 change(xe, dummy);
195 if (_mutex)
196 _mutex->lock();
197 setFrame(xs, y, xe, y);
198 writeCommand(CMD_RAMWR);
199 int buf_index = 0;
200 for (int i = xs; i <= xe; ++i)
201 {
202 _tx_buffer[buf_index++] = color >> 8;
203 _tx_buffer[buf_index++] = color & 0xff;
204 }
205 writeDataBuffer(buf_index);
206 if (_mutex)
207 _mutex->unlock();
208}
209
210void st7735s_drv::drawVLine(uint16_t x, uint16_t ys, uint16_t ye, color_t c)
211{
212 color_t color = convertColor(c, LCD::COLORTYPE_RGB565);
213 uint16_t dummy;
214 change(x, ys);
215 change(dummy, ye);
216 if (_mutex)
217 _mutex->lock();
218 setFrame(x, ys, x, ye);
219 writeCommand(CMD_RAMWR);
220 int buf_index = 0;
221 for (int i = ys; i <= ye; ++i)
222 {
223 _tx_buffer[buf_index++] = color >> 8;
224 _tx_buffer[buf_index++] = color & 0xff;
225 }
226 writeDataBuffer(buf_index);
227 if (_mutex)
228 _mutex->unlock();
229}
230
231void st7735s_drv::drawArea(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye,
232 pixel_stream & ps)
233{
234 bool color_conversion = (ps.getColorType() != LCD::COLORTYPE_RGB565);
235 ps.reset();
236 change(xs, ys);
237 change(xe, ye);
238 if (_mutex)
239 _mutex->lock();
240 setFrame(xs, ys, xe, ye);
241 int16_t pixels = (xe - xs + 1) * (ye - ys + 1);
242 writeCommand(CMD_RAMWR);
243 int index = 0;
244 for (int i = 0; i < pixels; i++)
245 {
246 color_t color = ps.getNext();
247 if (color_conversion)
248 {
249 color = convertColor(color, LCD::COLORTYPE_RGB565);
250 }
251 _tx_buffer[index++] = color >> 8;
252 _tx_buffer[index++] = color & 0xff;
253 if (index == BUF_LEN) {
254 writeDataBuffer(index);
255 index = 0;
256 }
257 }
258 if (index) {
259 writeDataBuffer(index);
260 }
261 if (_mutex)
262 _mutex->unlock();
263}
264
265void st7735s_drv::fillArea(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye,
266 color_t c)
267{
268 pixel_stream_const ps(convertColor(c, LCD::COLORTYPE_RGB565));
269 drawArea(xs, ys, xe, ye, ps);
270}
271
272void st7735s_drv::scroll(int16_t rows)
273{
274 _first_row += rows;
275 if (_first_row < 0)
276 _first_row += _lcd.sizeY;
277 else if (_first_row >= _lcd.sizeY)
278 _first_row -= _lcd.sizeY;
279 if (_mutex)
280 _mutex->lock();
281 writeCommand(CMD_VSCSAD);
282 writeData(0);
283 writeData(_lcd.offsetY + _first_row);
284 if (_mutex)
285 _mutex->unlock();
286}
287
288void st7735s_drv::clearScreen(color_t c)
289{
290 color_t color = convertColor(c, LCD::COLORTYPE_RGB565);
291 scroll(-_first_row); // Reset scrolling
292 if (_mutex)
293 _mutex->lock();
294 setFrame(0, 0, _lcd.sizeX - 1, _lcd.sizeY - 1);
295 int16_t pixels = _lcd.sizeX * _lcd.sizeY;
296 writeCommand(CMD_RAMWR);
297 uint8_t msb = color >> 8;
298 uint8_t lsb = color & 0xff;
299 int index = 0;
300 for (int i = 0; i <= pixels; i++) {
301 _tx_buffer[index++] = msb;
302 _tx_buffer[index++] = lsb;
303 if (index == BUF_LEN) {
304 writeDataBuffer(index);
305 index = 0;
306 }
307 }
308 if (index) {
309 writeDataBuffer(index);
310 }
311 if (_mutex)
312 _mutex->unlock();
313}
314
315void st7735s_drv::inverseColors(bool b)
316{
317 if (_mutex)
318 _mutex->lock();
319 if (b)
320 writeCommand(CMD_INVON);
321 else
322 writeCommand(CMD_INVOFF);
323 if (_mutex)
324 _mutex->unlock();
325}
326
327// private methods.
329void st7735s_drv::change(uint16_t & x, uint16_t & y)
330{
331 switch (_orientation)
332 {
333 case UP:
334 y += _lcd.sizeY + _lcd.offsetY - _first_row - 1;
335 break;
336 case DOWN:
337 y += _first_row;
338 break;
339 case LEFT:
340 x += _lcd.sizeY + _lcd.offsetY - _first_row - 1;
341 break;
342 case RIGHT:
343 x += _first_row;
344 break;
345 }
346 if (y >= _lcd.sizeY)
347 y -= _lcd.sizeY;
348 if (x >= _lcd.sizeY)
349 x -= _lcd.sizeY;
350}
351
352void st7735s_drv::setFrame(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye)
353{
354 switch (_orientation)
355 {
356 case UP:
357 xs += (_lcd.sizeRamX - _lcd.sizeX - _lcd.offsetX);
358 ys += (_lcd.sizeRamY - _lcd.sizeY - _lcd.offsetY);
359 xe += (_lcd.sizeRamX - _lcd.sizeX - _lcd.offsetX);
360 ye += (_lcd.sizeRamY - _lcd.sizeY - _lcd.offsetY);
361 break;
362 case DOWN:
363 xs += _lcd.offsetX;
364 ys += _lcd.offsetY;
365 xe += _lcd.offsetX;
366 ye += _lcd.offsetY;
367 break;
368 case LEFT:
369 xs += (_lcd.sizeRamY - _lcd.sizeY - _lcd.offsetY);
370 ys += _lcd.offsetX;
371 xe += (_lcd.sizeRamY - _lcd.sizeY - _lcd.offsetY);
372 ye += _lcd.offsetX;
373 break;
374 case RIGHT:
375 xs += _lcd.offsetY;
376 ys += (_lcd.sizeRamX - _lcd.sizeX - _lcd.offsetX);
377 xe += _lcd.offsetY;
378 ye += (_lcd.sizeRamX - _lcd.sizeX - _lcd.offsetX);
379 break;
380 }
381 writeCommand(CMD_CASET);
382 _tx_buffer[0] = 0;
383 _tx_buffer[1] = xs;
384 _tx_buffer[2] = 0;
385 _tx_buffer[3] = xe;
386 writeDataBuffer(4);
387
388 writeCommand(CMD_RASET);
389 _tx_buffer[0] = 0;
390 _tx_buffer[1] = ys;
391 _tx_buffer[2] = 0;
392 _tx_buffer[3] = ye;
393 writeDataBuffer(4);
394}
395
396void st7735s_drv::writeData(uint8_t data)
397{
398 _spi.spiTx(&data, 1);
399}
400
401void st7735s_drv::writeDataBuffer(int len)
402{
403 _spi.spiTx(_tx_buffer, len);
404}
405
406void st7735s_drv::writeCommand(uint8_t cmd)
407{
408 _dc_pin.gpioWrite(LOW);
409 uint8_t rcv_data;
410 _spi.spiTxRx(&cmd, &rcv_data, 1);
411 _dc_pin.gpioWrite(HIGH);
412}
413
Definition mutex.h:27