Basically i glued Peter Drescher and Simon Ford libs in a GraphicsDisplay class, then derived TFT or LCD class (which inherits Protocols class), then the most derived ones (Inits), which are per-display and are the only part needed to be adapted to diff hw.
Protocols/SPI8.cpp@11:b842b8e332cb, 2015-02-20 (annotated)
- Committer:
- Geremia
- Date:
- Fri Feb 20 21:32:25 2015 +0000
- Revision:
- 11:b842b8e332cb
- Parent:
- 7:bb0383b91104
- Child:
- 20:14daa48ffd4c
added auto_gram_read_format() to TFt inits. Even if write is set to 16bit RGB color, for some controllers the read cmd outputs 18bit BGR. Now that function will autodetect and set internal flags accordingly, so pixelread() is always correct.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Geremia | 4:12ba0ecc2c1f | 1 | /* mbed UniGraphic library - SPI8 protocol class |
Geremia | 4:12ba0ecc2c1f | 2 | * Copyright (c) 2015 Giuliano Dianda |
Geremia | 4:12ba0ecc2c1f | 3 | * Released under the MIT License: http://mbed.org/license/mit |
Geremia | 4:12ba0ecc2c1f | 4 | * |
Geremia | 4:12ba0ecc2c1f | 5 | * Derived work of: |
Geremia | 4:12ba0ecc2c1f | 6 | * |
Geremia | 4:12ba0ecc2c1f | 7 | * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller |
Geremia | 4:12ba0ecc2c1f | 8 | * Copyright (c) 2013 Peter Drescher - DC2PD |
Geremia | 4:12ba0ecc2c1f | 9 | * |
Geremia | 4:12ba0ecc2c1f | 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Geremia | 4:12ba0ecc2c1f | 11 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Geremia | 4:12ba0ecc2c1f | 12 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
Geremia | 4:12ba0ecc2c1f | 13 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
Geremia | 4:12ba0ecc2c1f | 14 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
Geremia | 4:12ba0ecc2c1f | 15 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
Geremia | 4:12ba0ecc2c1f | 16 | * THE SOFTWARE. |
Geremia | 4:12ba0ecc2c1f | 17 | */ |
Geremia | 4:12ba0ecc2c1f | 18 | |
Geremia | 0:75ec1b3cde17 | 19 | #include "SPI8.h" |
Geremia | 0:75ec1b3cde17 | 20 | |
Geremia | 0:75ec1b3cde17 | 21 | //#define USE_CS |
Geremia | 0:75ec1b3cde17 | 22 | |
Geremia | 1:ff019d22b275 | 23 | SPI8::SPI8(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC) |
Geremia | 0:75ec1b3cde17 | 24 | : _CS(CS), _spi(mosi, miso, sclk), _reset(reset), _DC(DC) |
Geremia | 0:75ec1b3cde17 | 25 | { |
Geremia | 0:75ec1b3cde17 | 26 | _reset = 1; |
Geremia | 0:75ec1b3cde17 | 27 | _DC=1; |
Geremia | 0:75ec1b3cde17 | 28 | _CS=1; |
Geremia | 0:75ec1b3cde17 | 29 | _spi.format(8,0); // 8 bit spi mode 0 |
Geremia | 0:75ec1b3cde17 | 30 | // _spi.frequency(12000000); // 10 Mhz SPI clock, 12mhz for F411 |
Geremia | 1:ff019d22b275 | 31 | _spi.frequency(Hz); |
Geremia | 0:75ec1b3cde17 | 32 | hw_reset(); |
Geremia | 0:75ec1b3cde17 | 33 | } |
Geremia | 0:75ec1b3cde17 | 34 | |
Geremia | 1:ff019d22b275 | 35 | void SPI8::wr_cmd8(unsigned char cmd) |
Geremia | 0:75ec1b3cde17 | 36 | { |
Geremia | 0:75ec1b3cde17 | 37 | #ifdef USE_CS |
Geremia | 0:75ec1b3cde17 | 38 | _CS = 0; |
Geremia | 0:75ec1b3cde17 | 39 | #endif |
Geremia | 0:75ec1b3cde17 | 40 | _DC.write(0); // 0=cmd |
Geremia | 0:75ec1b3cde17 | 41 | _spi.write(cmd); // write 8bit |
Geremia | 0:75ec1b3cde17 | 42 | #ifdef USE_CS |
Geremia | 0:75ec1b3cde17 | 43 | _CS = 1; |
Geremia | 0:75ec1b3cde17 | 44 | #endif |
Geremia | 0:75ec1b3cde17 | 45 | } |
Geremia | 1:ff019d22b275 | 46 | void SPI8::wr_data8(unsigned char data) |
Geremia | 0:75ec1b3cde17 | 47 | { |
Geremia | 0:75ec1b3cde17 | 48 | #ifdef USE_CS |
Geremia | 0:75ec1b3cde17 | 49 | _CS = 0; |
Geremia | 0:75ec1b3cde17 | 50 | #endif |
Geremia | 0:75ec1b3cde17 | 51 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 52 | _spi.write(data); // write 8bit |
Geremia | 0:75ec1b3cde17 | 53 | #ifdef USE_CS |
Geremia | 0:75ec1b3cde17 | 54 | _CS = 1; |
Geremia | 0:75ec1b3cde17 | 55 | #endif |
Geremia | 0:75ec1b3cde17 | 56 | } |
Geremia | 1:ff019d22b275 | 57 | void SPI8::wr_cmd16(unsigned short cmd) |
Geremia | 1:ff019d22b275 | 58 | { |
Geremia | 1:ff019d22b275 | 59 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 60 | _CS = 0; |
Geremia | 1:ff019d22b275 | 61 | #endif |
Geremia | 1:ff019d22b275 | 62 | _DC.write(0); // 0=cmd |
Geremia | 1:ff019d22b275 | 63 | _spi.write(cmd>>8); // write 8bit |
Geremia | 1:ff019d22b275 | 64 | _spi.write(cmd&0xFF); // write 8bit |
Geremia | 1:ff019d22b275 | 65 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 66 | _CS = 1; |
Geremia | 1:ff019d22b275 | 67 | #endif |
Geremia | 1:ff019d22b275 | 68 | } |
Geremia | 1:ff019d22b275 | 69 | void SPI8::wr_data16(unsigned short data) |
Geremia | 1:ff019d22b275 | 70 | { |
Geremia | 1:ff019d22b275 | 71 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 72 | _CS = 0; |
Geremia | 1:ff019d22b275 | 73 | #endif |
Geremia | 1:ff019d22b275 | 74 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 75 | _spi.write(data>>8); // write 8bit |
Geremia | 1:ff019d22b275 | 76 | _spi.write(data&0xFF); // write 8bit |
Geremia | 1:ff019d22b275 | 77 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 78 | _CS = 1; |
Geremia | 1:ff019d22b275 | 79 | #endif |
Geremia | 1:ff019d22b275 | 80 | } |
Geremia | 4:12ba0ecc2c1f | 81 | void SPI8::wr_gram(unsigned short data) |
Geremia | 4:12ba0ecc2c1f | 82 | { |
Geremia | 4:12ba0ecc2c1f | 83 | #ifdef USE_CS |
Geremia | 4:12ba0ecc2c1f | 84 | _CS = 0; |
Geremia | 4:12ba0ecc2c1f | 85 | #endif |
Geremia | 4:12ba0ecc2c1f | 86 | _DC.write(1); // 1=data |
Geremia | 4:12ba0ecc2c1f | 87 | _spi.write(data>>8); // write 8bit |
Geremia | 4:12ba0ecc2c1f | 88 | _spi.write(data&0xFF); // write 8bit |
Geremia | 4:12ba0ecc2c1f | 89 | #ifdef USE_CS |
Geremia | 4:12ba0ecc2c1f | 90 | _CS = 1; |
Geremia | 4:12ba0ecc2c1f | 91 | #endif |
Geremia | 4:12ba0ecc2c1f | 92 | } |
Geremia | 4:12ba0ecc2c1f | 93 | void SPI8::wr_gram(unsigned short data, unsigned int count) |
Geremia | 1:ff019d22b275 | 94 | { |
Geremia | 1:ff019d22b275 | 95 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 96 | _CS = 0; |
Geremia | 1:ff019d22b275 | 97 | #endif |
Geremia | 1:ff019d22b275 | 98 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 99 | if((data>>8)==(data&0xFF)) |
Geremia | 1:ff019d22b275 | 100 | { |
Geremia | 1:ff019d22b275 | 101 | count<<=1; |
Geremia | 1:ff019d22b275 | 102 | while(count) |
Geremia | 1:ff019d22b275 | 103 | { |
Geremia | 1:ff019d22b275 | 104 | _spi.write(data); // write 8bit |
Geremia | 1:ff019d22b275 | 105 | count--; |
Geremia | 1:ff019d22b275 | 106 | } |
Geremia | 1:ff019d22b275 | 107 | } |
Geremia | 1:ff019d22b275 | 108 | else |
Geremia | 1:ff019d22b275 | 109 | { |
Geremia | 1:ff019d22b275 | 110 | while(count) |
Geremia | 1:ff019d22b275 | 111 | { |
Geremia | 1:ff019d22b275 | 112 | _spi.write(data>>8); // write 8bit |
Geremia | 1:ff019d22b275 | 113 | _spi.write(data&0xFF); // write 8bit |
Geremia | 1:ff019d22b275 | 114 | count--; |
Geremia | 1:ff019d22b275 | 115 | } |
Geremia | 1:ff019d22b275 | 116 | } |
Geremia | 1:ff019d22b275 | 117 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 118 | _CS = 1; |
Geremia | 1:ff019d22b275 | 119 | #endif |
Geremia | 1:ff019d22b275 | 120 | } |
Geremia | 4:12ba0ecc2c1f | 121 | void SPI8::wr_grambuf(unsigned short* data, unsigned int lenght) |
Geremia | 1:ff019d22b275 | 122 | { |
Geremia | 1:ff019d22b275 | 123 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 124 | _CS = 0; |
Geremia | 1:ff019d22b275 | 125 | #endif |
Geremia | 1:ff019d22b275 | 126 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 127 | while(lenght) |
Geremia | 1:ff019d22b275 | 128 | { |
Geremia | 1:ff019d22b275 | 129 | _spi.write((*data)>>8); // write 8bit |
Geremia | 1:ff019d22b275 | 130 | _spi.write((*data)&0xFF); // write 8bit |
Geremia | 1:ff019d22b275 | 131 | data++; |
Geremia | 0:75ec1b3cde17 | 132 | lenght--; |
Geremia | 0:75ec1b3cde17 | 133 | } |
Geremia | 0:75ec1b3cde17 | 134 | #ifdef USE_CS |
Geremia | 0:75ec1b3cde17 | 135 | _CS = 1; |
Geremia | 0:75ec1b3cde17 | 136 | #endif |
Geremia | 0:75ec1b3cde17 | 137 | } |
Geremia | 11:b842b8e332cb | 138 | unsigned short SPI8::rd_gram(bool convert) |
Geremia | 5:b222a9461d6b | 139 | { |
Geremia | 5:b222a9461d6b | 140 | #ifdef USE_CS |
Geremia | 5:b222a9461d6b | 141 | _CS = 0; |
Geremia | 5:b222a9461d6b | 142 | #endif |
Geremia | 5:b222a9461d6b | 143 | unsigned int r=0; |
Geremia | 5:b222a9461d6b | 144 | _DC.write(1); // 1=data |
Geremia | 5:b222a9461d6b | 145 | _spi.write(0); // whole first byte is dummy |
Geremia | 5:b222a9461d6b | 146 | r |= _spi.write(0); |
Geremia | 5:b222a9461d6b | 147 | r <<= 8; |
Geremia | 5:b222a9461d6b | 148 | r |= _spi.write(0); |
Geremia | 11:b842b8e332cb | 149 | if(convert) |
Geremia | 11:b842b8e332cb | 150 | { |
Geremia | 11:b842b8e332cb | 151 | r <<= 8; |
Geremia | 11:b842b8e332cb | 152 | r |= _spi.write(0); |
Geremia | 11:b842b8e332cb | 153 | // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit |
Geremia | 11:b842b8e332cb | 154 | // during reading, you read the raw 18bit gram |
Geremia | 11:b842b8e332cb | 155 | r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit |
Geremia | 11:b842b8e332cb | 156 | } |
Geremia | 5:b222a9461d6b | 157 | _CS = 1; // force CS HIG to interupt the "read state" |
Geremia | 5:b222a9461d6b | 158 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 5:b222a9461d6b | 159 | _CS = 0; |
Geremia | 5:b222a9461d6b | 160 | #endif |
Geremia | 5:b222a9461d6b | 161 | return (unsigned short)r; |
Geremia | 5:b222a9461d6b | 162 | } |
Geremia | 7:bb0383b91104 | 163 | unsigned int SPI8::rd_reg_data32(unsigned char reg) |
Geremia | 7:bb0383b91104 | 164 | { |
Geremia | 7:bb0383b91104 | 165 | #ifdef USE_CS |
Geremia | 7:bb0383b91104 | 166 | _CS = 0; |
Geremia | 7:bb0383b91104 | 167 | #endif |
Geremia | 7:bb0383b91104 | 168 | wr_cmd8(reg); |
Geremia | 7:bb0383b91104 | 169 | unsigned int r=0; |
Geremia | 7:bb0383b91104 | 170 | _DC.write(1); // 1=data |
Geremia | 7:bb0383b91104 | 171 | |
Geremia | 7:bb0383b91104 | 172 | r |= _spi.write(0); // we get only 7bit valid, first bit was the dummy cycle |
Geremia | 7:bb0383b91104 | 173 | r <<= 8; |
Geremia | 7:bb0383b91104 | 174 | r |= _spi.write(0); |
Geremia | 7:bb0383b91104 | 175 | r <<= 8; |
Geremia | 7:bb0383b91104 | 176 | r |= _spi.write(0); |
Geremia | 7:bb0383b91104 | 177 | r <<= 8; |
Geremia | 7:bb0383b91104 | 178 | r |= _spi.write(0); |
Geremia | 7:bb0383b91104 | 179 | r <<= 1; // 32bits are aligned, now collecting bit_0 |
Geremia | 7:bb0383b91104 | 180 | r |= (_spi.write(0) >> 7); |
Geremia | 7:bb0383b91104 | 181 | // we clocked 7 more bit so ILI waiting for 8th, we need to reset spi bus |
Geremia | 7:bb0383b91104 | 182 | _CS = 1; // force CS HIG to interupt the cmd |
Geremia | 7:bb0383b91104 | 183 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 7:bb0383b91104 | 184 | _CS = 0; |
Geremia | 7:bb0383b91104 | 185 | #endif |
Geremia | 7:bb0383b91104 | 186 | return r; |
Geremia | 7:bb0383b91104 | 187 | } |
Geremia | 7:bb0383b91104 | 188 | unsigned int SPI8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) |
Geremia | 7:bb0383b91104 | 189 | { |
Geremia | 7:bb0383b91104 | 190 | unsigned int r=0; |
Geremia | 7:bb0383b91104 | 191 | for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1 |
Geremia | 7:bb0383b91104 | 192 | { |
Geremia | 7:bb0383b91104 | 193 | wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know |
Geremia | 7:bb0383b91104 | 194 | wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want |
Geremia | 7:bb0383b91104 | 195 | wr_cmd8(reg); // now send cmd (select register we want to read) |
Geremia | 7:bb0383b91104 | 196 | _DC.write(1); // 1=data |
Geremia | 7:bb0383b91104 | 197 | r <<= 8; |
Geremia | 7:bb0383b91104 | 198 | r |= _spi.write(0); |
Geremia | 7:bb0383b91104 | 199 | // r = _spi.write(0) >> 8; for 16bit |
Geremia | 7:bb0383b91104 | 200 | } |
Geremia | 7:bb0383b91104 | 201 | _CS = 1; // force CS HIG to interupt the cmd |
Geremia | 7:bb0383b91104 | 202 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 7:bb0383b91104 | 203 | _CS = 0; |
Geremia | 7:bb0383b91104 | 204 | #endif |
Geremia | 7:bb0383b91104 | 205 | return r; |
Geremia | 7:bb0383b91104 | 206 | } |
Geremia | 0:75ec1b3cde17 | 207 | void SPI8::hw_reset() |
Geremia | 0:75ec1b3cde17 | 208 | { |
Geremia | 0:75ec1b3cde17 | 209 | wait_ms(15); |
Geremia | 0:75ec1b3cde17 | 210 | _DC = 1; |
Geremia | 0:75ec1b3cde17 | 211 | // _CS = 1; |
Geremia | 0:75ec1b3cde17 | 212 | _CS = 0; |
Geremia | 0:75ec1b3cde17 | 213 | _reset = 0; // display reset |
Geremia | 0:75ec1b3cde17 | 214 | wait_us(50); |
Geremia | 0:75ec1b3cde17 | 215 | _reset = 1; // end reset |
Geremia | 0:75ec1b3cde17 | 216 | wait_ms(15); |
Geremia | 0:75ec1b3cde17 | 217 | #ifndef USE_CS |
Geremia | 0:75ec1b3cde17 | 218 | _CS=0; // put CS low now and forever |
Geremia | 0:75ec1b3cde17 | 219 | #endif |
Geremia | 0:75ec1b3cde17 | 220 | } |
Geremia | 0:75ec1b3cde17 | 221 | void SPI8::BusEnable(bool enable) |
Geremia | 0:75ec1b3cde17 | 222 | { |
Geremia | 0:75ec1b3cde17 | 223 | _CS = enable ? 0:1; |
Geremia | 0:75ec1b3cde17 | 224 | } |