YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
sharp96_drv.cpp
1/*
2 * sharp96_drv.cpp
3 *
4 * Created on: 29.06.2018
5 * Author: Andreas Terstegge
6 */
7
8#include "sharp96_drv.h"
9#include "pixel_stream_const.h"
10
11sharp96_drv::sharp96_drv(spi_interface & spi,
12 gpio_interface & disp,
13 gpio_interface & pwr,
14 timer_interface & timer)
15 : _spi(spi), _disp_on_pin(disp), _pwr_pin(pwr),
16 _timer(timer), _dirty(true), _setVCOM(false) {
17
18 // Clear the display buffer
19 for(int y=0; y < getSizeY(); y++) {
20 for(unsigned int x=0; x < sizeof(_display_buffer[0]); x++) {
21 _display_buffer[y][x] = 0xff;
22 }
23 }
24
25 // Initialize disp and pwr pins
26 _disp_on_pin.gpioMode(GPIO::OUTPUT | GPIO::INIT_HIGH);
27 _pwr_pin.gpioMode (GPIO::OUTPUT | GPIO::INIT_HIGH);
28
29 // Initialize SPI interface
30 _spi.setSpeed(1000000);
31 _spi.generateCS(false);
32 _spi.setCS(HIGH);
33
34 // Initialize timer
35 _timer.setPeriod(50000, TIMER::PERIODIC);
36 _timer.setCallback([this]() {
37 flush();
38 });
39 _timer.start();
40}
41
42void sharp96_drv::drawPixel(uint16_t x, uint16_t y, color_t c)
43{
44 if(COLOR_RGB(c) == 0)
45 _display_buffer[y][x>>3] &= ~(0x80 >> (x & 0x7));
46 else
47 _display_buffer[y][x>>3] |= (0x80 >> (x & 0x7));
48 _dirty = true;
49}
50
51void sharp96_drv::drawHLine(uint16_t xs, uint16_t y, uint16_t xe, color_t c)
52{
53 for (int x=xs; x <= xe; ++x)
54 drawPixel(x, y, c);
55}
56
57void sharp96_drv::drawVLine(uint16_t x, uint16_t ys, uint16_t ye, color_t c)
58{
59 for (int y=ys; y <= ye; ++y)
60 drawPixel(x, y, c);
61}
62
63void sharp96_drv::drawArea(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye,
64 pixel_stream & ps)
65{
66 for (int y=ys; y <= ye; ++y)
67 for (int x=xs; x <= xe; ++x)
68 drawPixel(x, y, ps.getNext());
69}
70
71void sharp96_drv::fillArea(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye,
72 color_t c)
73{
74 for (int y=ys; y <= ye; ++y)
75 for (int x=xs; x <= xe; ++x)
76 drawPixel(x, y, c);
77}
78
79void sharp96_drv::flush()
80{
81 // Handle VCOM bit
82 uint8_t cmd = 0;
83 if (_setVCOM) cmd |= 0x40;
84 _setVCOM ^= true;
85
86 // Start SPI transfer by setting CS high
87 _spi.setCS(HIGH);
88
89 if (_dirty) {
90 uint8_t * data_ptr = _display_buffer[0];
91 cmd |= 0x80; // Update data
92 writeData(cmd);
93 for (int y=0; y < getSizeY(); ++y) {
94 writeData(reverseByte(y+1));
95 _spi.spiTx(data_ptr, sizeof(_display_buffer[0]));
96 data_ptr += sizeof(_display_buffer[0]);
97 writeData(0x00); // dummy
98 }
99 } else {
100 // Only toggle VCOM, display memory not changed
101 writeData(cmd);
102 }
103 writeData(0x00); // dummy
104
105 // Short delay and set CS low
106 for (int i=0; i < 5; ++i) ;
107 _spi.setCS(LOW);
108
109 // Reset the dirty flag
110 _dirty = false;
111}
112
113void sharp96_drv::writeData(uint8_t data)
114{
115 _spi.spiTx(&data, 1);
116}
117
118// Bit reversal helper
119uint8_t sharp96_drv::reverseByte(uint8_t data)
120{
121#ifdef __MSP432P401R__
122 uint32_t input = data;
123 uint32_t output;
124 __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
125 return output >> 24;
126#else
127 uint8_t y = 0, i = 0;
128 for (i=0; i < 8; i++) {
129 y = y << 1;
130 y |= (data & 1);
131 data = data >> 1;
132 }
133 return y;
134#endif
135}