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:   Brew

Committer:
Geremia
Date:
Mon Mar 23 14:08:04 2015 +0000
Revision:
20:14daa48ffd4c
Parent:
11:b842b8e332cb
Add  ILI 9320/9325/9328 custom TFT932x class, parallel/spi 8/16bit, with orientation, scroll, pixelread, fastwindow.; Par8 and 16 tested, SPI not at all, needs checking if the CS toggle is necessary (see SPI8.cpp SPI16.cpp).

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
Geremia 1:ff019d22b275 21 SPI16::SPI16(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC)
Geremia 1:ff019d22b275 22 : _CS(CS), _spi(mosi, miso, sclk), _reset(reset), _DC(DC)
Geremia 1:ff019d22b275 23 {
Geremia 1:ff019d22b275 24 _reset = 1;
Geremia 1:ff019d22b275 25 _DC=1;
Geremia 1:ff019d22b275 26 _CS=1;
Geremia 1:ff019d22b275 27 _spi.format(16,0); // 8 bit spi mode 0
Geremia 1:ff019d22b275 28 // _spi.frequency(12000000); // 10 Mhz SPI clock, 12mhz for F411
Geremia 1:ff019d22b275 29 _spi.frequency(Hz);
Geremia 1:ff019d22b275 30 hw_reset();
Geremia 1:ff019d22b275 31 }
Geremia 1:ff019d22b275 32
Geremia 1:ff019d22b275 33 void SPI16::wr_cmd8(unsigned char cmd)
Geremia 1:ff019d22b275 34 {
Geremia 1:ff019d22b275 35 _spi.format(8,0); // it takes time, better use wr_cmd16 with NOP cmd
Geremia 1:ff019d22b275 36 _DC.write(0); // 0=cmd
Geremia 1:ff019d22b275 37 _spi.write(cmd); // write 8bit
Geremia 1:ff019d22b275 38 _spi.format(16,0);
Geremia 20:14daa48ffd4c 39 _DC.write(1); // 1=data next
Geremia 1:ff019d22b275 40 }
Geremia 1:ff019d22b275 41 void SPI16::wr_data8(unsigned char data)
Geremia 1:ff019d22b275 42 {
Geremia 1:ff019d22b275 43 _spi.format(8,0); // it takes time, check prev cmd parameter, in case use wr_data16 with repeated byte
Geremia 1:ff019d22b275 44 _spi.write(data); // write 8bit
Geremia 1:ff019d22b275 45 _spi.format(16,0);
Geremia 1:ff019d22b275 46 }
Geremia 1:ff019d22b275 47 void SPI16::wr_cmd16(unsigned short cmd)
Geremia 20:14daa48ffd4c 48 {
Geremia 1:ff019d22b275 49 _DC.write(0); // 0=cmd
Geremia 1:ff019d22b275 50 _spi.write(cmd); // write 16bit
Geremia 20:14daa48ffd4c 51 _DC.write(1); // 1=data next
Geremia 1:ff019d22b275 52 }
Geremia 1:ff019d22b275 53 void SPI16::wr_data16(unsigned short data)
Geremia 1:ff019d22b275 54 {
Geremia 1:ff019d22b275 55 _spi.write(data); // write 16bit
Geremia 1:ff019d22b275 56 }
Geremia 4:12ba0ecc2c1f 57 void SPI16::wr_gram(unsigned short data)
Geremia 4:12ba0ecc2c1f 58 {
Geremia 4:12ba0ecc2c1f 59 _spi.write(data); // write 16bit
Geremia 4:12ba0ecc2c1f 60 }
Geremia 4:12ba0ecc2c1f 61 void SPI16::wr_gram(unsigned short data, unsigned int count)
Geremia 1:ff019d22b275 62 {
Geremia 1:ff019d22b275 63 while(count)
Geremia 1:ff019d22b275 64 {
Geremia 1:ff019d22b275 65 _spi.write(data);
Geremia 1:ff019d22b275 66 count--;
Geremia 1:ff019d22b275 67 }
Geremia 1:ff019d22b275 68 }
Geremia 4:12ba0ecc2c1f 69 void SPI16::wr_grambuf(unsigned short* data, unsigned int lenght)
Geremia 1:ff019d22b275 70 {
Geremia 1:ff019d22b275 71 while(lenght)
Geremia 1:ff019d22b275 72 {
Geremia 1:ff019d22b275 73 _spi.write(*data);
Geremia 1:ff019d22b275 74 data++;
Geremia 1:ff019d22b275 75 lenght--;
Geremia 1:ff019d22b275 76 }
Geremia 1:ff019d22b275 77 }
Geremia 11:b842b8e332cb 78 unsigned short SPI16::rd_gram(bool convert)
Geremia 5:b222a9461d6b 79 {
Geremia 5:b222a9461d6b 80 unsigned int r=0;
Geremia 5:b222a9461d6b 81 r |= _spi.write(0); // 16bit, whole first byte is dummy, second is red
Geremia 5:b222a9461d6b 82 r <<= 16;
Geremia 5:b222a9461d6b 83 r |= _spi.write(0);
Geremia 11:b842b8e332cb 84 if(convert)
Geremia 11:b842b8e332cb 85 {
Geremia 11:b842b8e332cb 86 // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit
Geremia 11:b842b8e332cb 87 // during reading, you read the raw 18bit gram
Geremia 11:b842b8e332cb 88 r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
Geremia 11:b842b8e332cb 89 }
Geremia 11:b842b8e332cb 90 else r >>= 8;
Geremia 20:14daa48ffd4c 91 _CS = 1; // force CS HIG to interupt the "read state"
Geremia 5:b222a9461d6b 92 _CS = 0;
Geremia 20:14daa48ffd4c 93
Geremia 5:b222a9461d6b 94 return (unsigned short)r;
Geremia 5:b222a9461d6b 95 }
Geremia 7:bb0383b91104 96 unsigned int SPI16::rd_reg_data32(unsigned char reg)
Geremia 7:bb0383b91104 97 {
Geremia 7:bb0383b91104 98 wr_cmd8(reg);
Geremia 7:bb0383b91104 99 unsigned int r=0;
Geremia 7:bb0383b91104 100
Geremia 7:bb0383b91104 101 r |= _spi.write(0); // we get only 15bit valid, first bit was the dummy cycle
Geremia 7:bb0383b91104 102 r <<= 16;
Geremia 7:bb0383b91104 103 r |= _spi.write(0);
Geremia 7:bb0383b91104 104 r <<= 1; // 32bits are aligned, now collecting bit_0
Geremia 7:bb0383b91104 105 r |= (_spi.write(0) >> 15);
Geremia 7:bb0383b91104 106 // we clocked 15 more bit so ILI waiting for 16th, we need to reset spi bus
Geremia 7:bb0383b91104 107 _CS = 1; // force CS HIG to interupt the cmd
Geremia 7:bb0383b91104 108 _CS = 0;
Geremia 7:bb0383b91104 109 return r;
Geremia 7:bb0383b91104 110 }
Geremia 7:bb0383b91104 111 unsigned int SPI16::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
Geremia 7:bb0383b91104 112 {
Geremia 7:bb0383b91104 113 unsigned int r=0;
Geremia 7:bb0383b91104 114 for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1
Geremia 7:bb0383b91104 115 {
Geremia 7:bb0383b91104 116 wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know
Geremia 7:bb0383b91104 117 wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want
Geremia 7:bb0383b91104 118 wr_cmd8(reg); // now send cmd (select register we want to read)
Geremia 7:bb0383b91104 119 r <<= 8;
Geremia 7:bb0383b91104 120 r |= (_spi.write(0) >> 8);
Geremia 7:bb0383b91104 121 }
Geremia 20:14daa48ffd4c 122 _CS = 1; // force CS HIG to interupt the cmd
Geremia 7:bb0383b91104 123 _CS = 0;
Geremia 20:14daa48ffd4c 124
Geremia 7:bb0383b91104 125 return r;
Geremia 7:bb0383b91104 126 }
Geremia 20:14daa48ffd4c 127 // ILI932x specific
Geremia 20:14daa48ffd4c 128 void SPI16::dummyread()
Geremia 20:14daa48ffd4c 129 {
Geremia 20:14daa48ffd4c 130 _spi.write(0); // dummy read
Geremia 20:14daa48ffd4c 131 }
Geremia 20:14daa48ffd4c 132 // ILI932x specific
Geremia 20:14daa48ffd4c 133 void SPI16::reg_select(unsigned char reg, bool forread)
Geremia 20:14daa48ffd4c 134 {
Geremia 20:14daa48ffd4c 135 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 136 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 137 _spi.write(0x70); // write 0070
Geremia 20:14daa48ffd4c 138 _spi.write(reg); // write 16bit
Geremia 20:14daa48ffd4c 139 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 140 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 141 if(forread) _spi.write(0x73);
Geremia 20:14daa48ffd4c 142 else _spi.write(0x72);
Geremia 20:14daa48ffd4c 143 }
Geremia 20:14daa48ffd4c 144 // ILI932x specific
Geremia 20:14daa48ffd4c 145 void SPI16::reg_write(unsigned char reg, unsigned short data)
Geremia 20:14daa48ffd4c 146 {
Geremia 20:14daa48ffd4c 147 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 148 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 149 _spi.write(0x70); // write 0070
Geremia 20:14daa48ffd4c 150 _spi.write(reg); // write 16bit
Geremia 20:14daa48ffd4c 151 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 152 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 153 _spi.write(0x72); // write 0072
Geremia 20:14daa48ffd4c 154 _spi.write(data); // write 16bit
Geremia 20:14daa48ffd4c 155 }
Geremia 20:14daa48ffd4c 156 // ILI932x specific
Geremia 20:14daa48ffd4c 157 unsigned short SPI16::reg_read(unsigned char reg)
Geremia 20:14daa48ffd4c 158 {
Geremia 20:14daa48ffd4c 159 unsigned int r=0;
Geremia 20:14daa48ffd4c 160 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 161 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 162 _spi.write(0x70); // write 0070
Geremia 20:14daa48ffd4c 163 _spi.write(reg); // write 16bit
Geremia 20:14daa48ffd4c 164 _CS = 1; //fixme: really needed?
Geremia 20:14daa48ffd4c 165 _CS = 0; //fixme: really needed?
Geremia 20:14daa48ffd4c 166 _spi.write(0x73); // write 0073
Geremia 20:14daa48ffd4c 167 r |= _spi.write(0); // read 16bit, 8bit dummy + 8bit valid
Geremia 20:14daa48ffd4c 168 r <<= 16;
Geremia 20:14daa48ffd4c 169 r |= _spi.write(0); // read 16bit
Geremia 20:14daa48ffd4c 170
Geremia 20:14daa48ffd4c 171 _CS = 1; //fixme: to resync, maybe really needed
Geremia 20:14daa48ffd4c 172 _CS = 0; //fixme: to resync, maybe really needed
Geremia 20:14daa48ffd4c 173 return (r>>8);
Geremia 20:14daa48ffd4c 174 }
Geremia 1:ff019d22b275 175 void SPI16::hw_reset()
Geremia 1:ff019d22b275 176 {
Geremia 1:ff019d22b275 177 wait_ms(15);
Geremia 1:ff019d22b275 178 _DC = 1;
Geremia 20:14daa48ffd4c 179 _CS = 1;
Geremia 1:ff019d22b275 180 _reset = 0; // display reset
Geremia 20:14daa48ffd4c 181 wait_ms(2);
Geremia 1:ff019d22b275 182 _reset = 1; // end reset
Geremia 20:14daa48ffd4c 183 wait_ms(100);
Geremia 1:ff019d22b275 184 }
Geremia 1:ff019d22b275 185 void SPI16::BusEnable(bool enable)
Geremia 1:ff019d22b275 186 {
Geremia 1:ff019d22b275 187 _CS = enable ? 0:1;
Geremia 1:ff019d22b275 188 }