Tue, 20 Sep 2016 23:50:45 +0200
several improvements
- add (used parts of) unigraphics in repo
- extract hp communication protocol listener in a dedicated file
5 | 1 | /* mbed UniGraphic library - SPI8 protocol class |
2 | * Copyright (c) 2015 Giuliano Dianda | |
3 | * Released under the MIT License: http://mbed.org/license/mit | |
4 | * | |
5 | * Derived work of: | |
6 | * | |
7 | * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller | |
8 | * Copyright (c) 2013 Peter Drescher - DC2PD | |
9 | * | |
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
11 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
12 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
13 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
14 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
15 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
16 | * THE SOFTWARE. | |
17 | */ | |
18 | ||
19 | #include "SPI8.h" | |
20 | ||
21 | ||
22 | SPI8::SPI8(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC) | |
23 | : _CS(CS), _spi(mosi, miso, sclk), _reset(reset), _DC(DC) | |
24 | { | |
25 | _reset = 1; | |
26 | _DC=1; | |
27 | _CS=1; | |
28 | _spi.format(8,0); // 8 bit spi mode 0 | |
29 | _spi.frequency(Hz); | |
30 | hw_reset(); | |
31 | } | |
32 | ||
33 | void SPI8::wr_cmd8(unsigned char cmd) | |
34 | { | |
35 | _DC.write(0); // 0=cmd | |
36 | _spi.write(cmd); // write 8bit | |
37 | _DC.write(1); // 1=data next | |
38 | } | |
39 | void SPI8::wr_data8(unsigned char data) | |
40 | { | |
41 | _spi.write(data); // write 8bit | |
42 | } | |
43 | ||
44 | void SPI8::wr_cmd16(unsigned short cmd) | |
45 | { | |
46 | _DC.write(0); // 0=cmd | |
47 | _spi.write(cmd>>8); // write 8bit | |
48 | _spi.write(cmd&0xFF); // write 8bit | |
49 | _DC.write(1); // 1=data next | |
50 | } | |
51 | void SPI8::wr_data16(unsigned short data) | |
52 | { | |
53 | _spi.write(data>>8); // write 8bit | |
54 | _spi.write(data&0xFF); // write 8bit | |
55 | } | |
56 | void SPI8::wr_gram(unsigned short data) | |
57 | { | |
58 | _spi.write(data>>8); // write 8bit | |
59 | _spi.write(data&0xFF); // write 8bit | |
60 | } | |
61 | void SPI8::wr_gram(unsigned short data, unsigned int count) | |
62 | { | |
63 | if((data>>8)==(data&0xFF)) | |
64 | { | |
65 | count<<=1; | |
66 | while(count) | |
67 | { | |
68 | _spi.write(data); // write 8bit | |
69 | count--; | |
70 | } | |
71 | } | |
72 | else | |
73 | { | |
74 | while(count) | |
75 | { | |
76 | _spi.write(data>>8); // write 8bit | |
77 | _spi.write(data&0xFF); // write 8bit | |
78 | count--; | |
79 | } | |
80 | } | |
81 | } | |
82 | void SPI8::wr_grambuf(unsigned short* data, unsigned int lenght) | |
83 | { | |
84 | while(lenght) | |
85 | { | |
86 | _spi.write((*data)>>8); // write 8bit | |
87 | _spi.write((*data)&0xFF); // write 8bit | |
88 | data++; | |
89 | lenght--; | |
90 | } | |
91 | } | |
92 | unsigned short SPI8::rd_gram(bool convert) | |
93 | { | |
94 | unsigned int r=0; | |
95 | _spi.write(0); // whole first byte is dummy | |
96 | r |= _spi.write(0); | |
97 | r <<= 8; | |
98 | r |= _spi.write(0); | |
99 | if(convert) | |
100 | { | |
101 | r <<= 8; | |
102 | r |= _spi.write(0); | |
103 | // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit | |
104 | // during reading, you read the raw 18bit gram | |
105 | r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit | |
106 | } | |
107 | _CS = 1; // force CS HIG to interupt the "read state" | |
108 | _CS = 0; | |
109 | return (unsigned short)r; | |
110 | } | |
111 | unsigned int SPI8::rd_reg_data32(unsigned char reg) | |
112 | { | |
113 | wr_cmd8(reg); | |
114 | unsigned int r=0; | |
115 | ||
116 | r |= _spi.write(0); // we get only 7bit valid, first bit was the dummy cycle | |
117 | r <<= 8; | |
118 | r |= _spi.write(0); | |
119 | r <<= 8; | |
120 | r |= _spi.write(0); | |
121 | r <<= 8; | |
122 | r |= _spi.write(0); | |
123 | r <<= 1; // 32bits are aligned, now collecting bit_0 | |
124 | r |= (_spi.write(0) >> 7); | |
125 | // we clocked 7 more bit so ILI waiting for 8th, we need to reset spi bus | |
126 | _CS = 1; // force CS HIG to interupt the cmd | |
127 | _CS = 0; | |
128 | return r; | |
129 | } | |
130 | unsigned int SPI8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) | |
131 | { | |
132 | unsigned int r=0; | |
133 | for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1 | |
134 | { | |
135 | wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know | |
136 | wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want | |
137 | wr_cmd8(reg); // now send cmd (select register we want to read) | |
138 | r <<= 8; | |
139 | r |= _spi.write(0); | |
140 | // r = _spi.write(0) >> 8; for 16bit | |
141 | } | |
142 | _CS = 1; // force CS HIG to interupt the cmd | |
143 | _CS = 0; | |
144 | return r; | |
145 | } | |
146 | // ILI932x specific | |
147 | void SPI8::dummyread() | |
148 | { | |
149 | _spi.write(0); // dummy read | |
150 | } | |
151 | // ILI932x specific | |
152 | void SPI8::reg_select(unsigned char reg, bool forread) | |
153 | { | |
154 | _CS = 1; //fixme: really needed? | |
155 | _CS = 0; //fixme: really needed? | |
156 | _spi.write(0x70); | |
157 | _spi.write(0); // write MSB | |
158 | _spi.write(reg); // write LSB | |
159 | _CS = 1; //fixme: really needed? | |
160 | _CS = 0; //fixme: really needed? | |
161 | if(forread) _spi.write(0x73); | |
162 | else _spi.write(0x72); | |
163 | } | |
164 | // ILI932x specific | |
165 | void SPI8::reg_write(unsigned char reg, unsigned short data) | |
166 | { | |
167 | _CS = 1; //fixme: really needed? | |
168 | _CS = 0; //fixme: really needed? | |
169 | _spi.write(0x70); | |
170 | _spi.write(0); // write MSB | |
171 | _spi.write(reg); // write LSB | |
172 | _CS = 1; //fixme: really needed? | |
173 | _CS = 0; //fixme: really needed? | |
174 | _spi.write(0x72); | |
175 | _spi.write(data>>8); | |
176 | _spi.write(data&0xFF); | |
177 | } | |
178 | // ILI932x specific | |
179 | unsigned short SPI8::reg_read(unsigned char reg) | |
180 | { | |
181 | unsigned short r=0; | |
182 | _CS = 1; //fixme: really needed? | |
183 | _CS = 0; //fixme: really needed? | |
184 | _spi.write(0x70); | |
185 | _spi.write(0); // write MSB | |
186 | _spi.write(reg); // write LSB | |
187 | _CS = 1; //fixme: really needed? | |
188 | _CS = 0; //fixme: really needed? | |
189 | _spi.write(0x73); | |
190 | _spi.write(0); // dummy read | |
191 | r = _spi.write(0); // read 8bit | |
192 | r <<= 8; | |
193 | r |= _spi.write(0); // read 8bit | |
194 | return r; | |
195 | } | |
196 | void SPI8::hw_reset() | |
197 | { | |
198 | wait_ms(15); | |
199 | _DC = 1; | |
200 | _CS = 1; | |
201 | _reset = 0; // display reset | |
202 | wait_ms(2); | |
203 | _reset = 1; // end reset | |
204 | wait_ms(100); | |
205 | } | |
206 | void SPI8::BusEnable(bool enable) | |
207 | { | |
208 | _CS = enable ? 0:1; | |
209 | } |