|
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 } |