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