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.
Dependents: afero_poc15_180216 afero_poc15_180223 afero_poc15_180302 afero_poc15_180403R ... more
Fork of UniGraphic by
UniGraphic for La Suno Version.
To go with La Suno, WatchDog Reset functions were added in ILI9341.
Protocols/SPI16.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 - SPI16 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 | 1:ff019d22b275 | 19 | #include "SPI16.h" |
Geremia | 1:ff019d22b275 | 20 | //#define USE_CS |
Geremia | 1:ff019d22b275 | 21 | |
Geremia | 1:ff019d22b275 | 22 | SPI16::SPI16(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC) |
Geremia | 1:ff019d22b275 | 23 | : _CS(CS), _spi(mosi, miso, sclk), _reset(reset), _DC(DC) |
Geremia | 1:ff019d22b275 | 24 | { |
Geremia | 1:ff019d22b275 | 25 | _reset = 1; |
Geremia | 1:ff019d22b275 | 26 | _DC=1; |
Geremia | 1:ff019d22b275 | 27 | _CS=1; |
Geremia | 1:ff019d22b275 | 28 | _spi.format(16,0); // 8 bit spi mode 0 |
Geremia | 1:ff019d22b275 | 29 | // _spi.frequency(12000000); // 10 Mhz SPI clock, 12mhz for F411 |
Geremia | 1:ff019d22b275 | 30 | _spi.frequency(Hz); |
Geremia | 1:ff019d22b275 | 31 | hw_reset(); |
Geremia | 1:ff019d22b275 | 32 | } |
Geremia | 1:ff019d22b275 | 33 | |
Geremia | 1:ff019d22b275 | 34 | void SPI16::wr_cmd8(unsigned char cmd) |
Geremia | 1:ff019d22b275 | 35 | { |
Geremia | 1:ff019d22b275 | 36 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 37 | _CS = 0; |
Geremia | 1:ff019d22b275 | 38 | #endif |
Geremia | 1:ff019d22b275 | 39 | _spi.format(8,0); // it takes time, better use wr_cmd16 with NOP cmd |
Geremia | 1:ff019d22b275 | 40 | _DC.write(0); // 0=cmd |
Geremia | 1:ff019d22b275 | 41 | _spi.write(cmd); // write 8bit |
Geremia | 1:ff019d22b275 | 42 | _spi.format(16,0); |
Geremia | 1:ff019d22b275 | 43 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 44 | _CS = 1; |
Geremia | 1:ff019d22b275 | 45 | #endif |
Geremia | 1:ff019d22b275 | 46 | } |
Geremia | 1:ff019d22b275 | 47 | void SPI16::wr_data8(unsigned char data) |
Geremia | 1:ff019d22b275 | 48 | { |
Geremia | 1:ff019d22b275 | 49 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 50 | _CS = 0; |
Geremia | 1:ff019d22b275 | 51 | #endif |
Geremia | 1:ff019d22b275 | 52 | _spi.format(8,0); // it takes time, check prev cmd parameter, in case use wr_data16 with repeated byte |
Geremia | 1:ff019d22b275 | 53 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 54 | _spi.write(data); // write 8bit |
Geremia | 1:ff019d22b275 | 55 | _spi.format(16,0); |
Geremia | 1:ff019d22b275 | 56 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 57 | _CS = 1; |
Geremia | 1:ff019d22b275 | 58 | #endif |
Geremia | 1:ff019d22b275 | 59 | } |
Geremia | 1:ff019d22b275 | 60 | void SPI16::wr_cmd16(unsigned short cmd) |
Geremia | 1:ff019d22b275 | 61 | { |
Geremia | 1:ff019d22b275 | 62 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 63 | _CS = 0; |
Geremia | 1:ff019d22b275 | 64 | #endif |
Geremia | 1:ff019d22b275 | 65 | _DC.write(0); // 0=cmd |
Geremia | 1:ff019d22b275 | 66 | _spi.write(cmd); // write 16bit |
Geremia | 1:ff019d22b275 | 67 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 68 | _CS = 1; |
Geremia | 1:ff019d22b275 | 69 | #endif |
Geremia | 1:ff019d22b275 | 70 | } |
Geremia | 1:ff019d22b275 | 71 | void SPI16::wr_data16(unsigned short data) |
Geremia | 1:ff019d22b275 | 72 | { |
Geremia | 1:ff019d22b275 | 73 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 74 | _CS = 0; |
Geremia | 1:ff019d22b275 | 75 | #endif |
Geremia | 1:ff019d22b275 | 76 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 77 | _spi.write(data); // write 16bit |
Geremia | 1:ff019d22b275 | 78 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 79 | _CS = 1; |
Geremia | 1:ff019d22b275 | 80 | #endif |
Geremia | 1:ff019d22b275 | 81 | } |
Geremia | 4:12ba0ecc2c1f | 82 | void SPI16::wr_gram(unsigned short data) |
Geremia | 4:12ba0ecc2c1f | 83 | { |
Geremia | 4:12ba0ecc2c1f | 84 | #ifdef USE_CS |
Geremia | 4:12ba0ecc2c1f | 85 | _CS = 0; |
Geremia | 4:12ba0ecc2c1f | 86 | #endif |
Geremia | 4:12ba0ecc2c1f | 87 | _DC.write(1); // 1=data |
Geremia | 4:12ba0ecc2c1f | 88 | _spi.write(data); // write 16bit |
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 SPI16::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 | while(count) |
Geremia | 1:ff019d22b275 | 100 | { |
Geremia | 1:ff019d22b275 | 101 | _spi.write(data); |
Geremia | 1:ff019d22b275 | 102 | count--; |
Geremia | 1:ff019d22b275 | 103 | } |
Geremia | 1:ff019d22b275 | 104 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 105 | _CS = 1; |
Geremia | 1:ff019d22b275 | 106 | #endif |
Geremia | 1:ff019d22b275 | 107 | } |
Geremia | 4:12ba0ecc2c1f | 108 | void SPI16::wr_grambuf(unsigned short* data, unsigned int lenght) |
Geremia | 1:ff019d22b275 | 109 | { |
Geremia | 1:ff019d22b275 | 110 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 111 | _CS = 0; |
Geremia | 1:ff019d22b275 | 112 | #endif |
Geremia | 1:ff019d22b275 | 113 | _DC.write(1); // 1=data |
Geremia | 1:ff019d22b275 | 114 | while(lenght) |
Geremia | 1:ff019d22b275 | 115 | { |
Geremia | 1:ff019d22b275 | 116 | _spi.write(*data); |
Geremia | 1:ff019d22b275 | 117 | data++; |
Geremia | 1:ff019d22b275 | 118 | lenght--; |
Geremia | 1:ff019d22b275 | 119 | } |
Geremia | 1:ff019d22b275 | 120 | #ifdef USE_CS |
Geremia | 1:ff019d22b275 | 121 | _CS = 1; |
Geremia | 1:ff019d22b275 | 122 | #endif |
Geremia | 1:ff019d22b275 | 123 | } |
Geremia | 11:b842b8e332cb | 124 | unsigned short SPI16::rd_gram(bool convert) |
Geremia | 5:b222a9461d6b | 125 | { |
Geremia | 5:b222a9461d6b | 126 | #ifdef USE_CS |
Geremia | 5:b222a9461d6b | 127 | _CS = 0; |
Geremia | 5:b222a9461d6b | 128 | #endif |
Geremia | 5:b222a9461d6b | 129 | unsigned int r=0; |
Geremia | 5:b222a9461d6b | 130 | _DC.write(1); // 1=data |
Geremia | 5:b222a9461d6b | 131 | r |= _spi.write(0); // 16bit, whole first byte is dummy, second is red |
Geremia | 5:b222a9461d6b | 132 | r <<= 16; |
Geremia | 5:b222a9461d6b | 133 | r |= _spi.write(0); |
Geremia | 11:b842b8e332cb | 134 | if(convert) |
Geremia | 11:b842b8e332cb | 135 | { |
Geremia | 11:b842b8e332cb | 136 | // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit |
Geremia | 11:b842b8e332cb | 137 | // during reading, you read the raw 18bit gram |
Geremia | 11:b842b8e332cb | 138 | r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit |
Geremia | 11:b842b8e332cb | 139 | } |
Geremia | 11:b842b8e332cb | 140 | else r >>= 8; |
Geremia | 5:b222a9461d6b | 141 | _CS = 1; // force CS HIG to interupt the "read state" |
Geremia | 5:b222a9461d6b | 142 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 5:b222a9461d6b | 143 | _CS = 0; |
Geremia | 5:b222a9461d6b | 144 | #endif |
Geremia | 5:b222a9461d6b | 145 | return (unsigned short)r; |
Geremia | 5:b222a9461d6b | 146 | } |
Geremia | 7:bb0383b91104 | 147 | unsigned int SPI16::rd_reg_data32(unsigned char reg) |
Geremia | 7:bb0383b91104 | 148 | { |
Geremia | 7:bb0383b91104 | 149 | #ifdef USE_CS |
Geremia | 7:bb0383b91104 | 150 | _CS = 0; |
Geremia | 7:bb0383b91104 | 151 | #endif |
Geremia | 7:bb0383b91104 | 152 | wr_cmd8(reg); |
Geremia | 7:bb0383b91104 | 153 | unsigned int r=0; |
Geremia | 7:bb0383b91104 | 154 | _DC.write(1);; // 1=data |
Geremia | 7:bb0383b91104 | 155 | |
Geremia | 7:bb0383b91104 | 156 | r |= _spi.write(0); // we get only 15bit valid, first bit was the dummy cycle |
Geremia | 7:bb0383b91104 | 157 | r <<= 16; |
Geremia | 7:bb0383b91104 | 158 | r |= _spi.write(0); |
Geremia | 7:bb0383b91104 | 159 | r <<= 1; // 32bits are aligned, now collecting bit_0 |
Geremia | 7:bb0383b91104 | 160 | r |= (_spi.write(0) >> 15); |
Geremia | 7:bb0383b91104 | 161 | // we clocked 15 more bit so ILI waiting for 16th, we need to reset spi bus |
Geremia | 7:bb0383b91104 | 162 | _CS = 1; // force CS HIG to interupt the cmd |
Geremia | 7:bb0383b91104 | 163 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 7:bb0383b91104 | 164 | _CS = 0; |
Geremia | 7:bb0383b91104 | 165 | #endif |
Geremia | 7:bb0383b91104 | 166 | return r; |
Geremia | 7:bb0383b91104 | 167 | } |
Geremia | 7:bb0383b91104 | 168 | unsigned int SPI16::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) |
Geremia | 7:bb0383b91104 | 169 | { |
Geremia | 7:bb0383b91104 | 170 | unsigned int r=0; |
Geremia | 7:bb0383b91104 | 171 | for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1 |
Geremia | 7:bb0383b91104 | 172 | { |
Geremia | 7:bb0383b91104 | 173 | wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know |
Geremia | 7:bb0383b91104 | 174 | wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want |
Geremia | 7:bb0383b91104 | 175 | wr_cmd8(reg); // now send cmd (select register we want to read) |
Geremia | 7:bb0383b91104 | 176 | _DC.write(1); // 1=data |
Geremia | 7:bb0383b91104 | 177 | r <<= 8; |
Geremia | 7:bb0383b91104 | 178 | r |= (_spi.write(0) >> 8); |
Geremia | 7:bb0383b91104 | 179 | } |
Geremia | 7:bb0383b91104 | 180 | _CS = 1; // force CS HIG to interupt the cmd |
Geremia | 7:bb0383b91104 | 181 | #ifndef USE_CS //if CS is not used, force fixed LOW again |
Geremia | 7:bb0383b91104 | 182 | _CS = 0; |
Geremia | 7:bb0383b91104 | 183 | #endif |
Geremia | 7:bb0383b91104 | 184 | return r; |
Geremia | 7:bb0383b91104 | 185 | } |
Geremia | 1:ff019d22b275 | 186 | void SPI16::hw_reset() |
Geremia | 1:ff019d22b275 | 187 | { |
Geremia | 1:ff019d22b275 | 188 | wait_ms(15); |
Geremia | 1:ff019d22b275 | 189 | _DC = 1; |
Geremia | 1:ff019d22b275 | 190 | // _CS = 1; |
Geremia | 1:ff019d22b275 | 191 | _CS = 0; |
Geremia | 1:ff019d22b275 | 192 | _reset = 0; // display reset |
Geremia | 1:ff019d22b275 | 193 | wait_us(50); |
Geremia | 1:ff019d22b275 | 194 | _reset = 1; // end reset |
Geremia | 1:ff019d22b275 | 195 | wait_ms(15); |
Geremia | 1:ff019d22b275 | 196 | #ifndef USE_CS |
Geremia | 1:ff019d22b275 | 197 | _CS=0; // put CS low now and forever |
Geremia | 1:ff019d22b275 | 198 | #endif |
Geremia | 1:ff019d22b275 | 199 | } |
Geremia | 1:ff019d22b275 | 200 | void SPI16::BusEnable(bool enable) |
Geremia | 1:ff019d22b275 | 201 | { |
Geremia | 1:ff019d22b275 | 202 | _CS = enable ? 0:1; |
Geremia | 1:ff019d22b275 | 203 | } |