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.

Fork of UniGraphic by GraphicsDisplay

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?

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