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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI8.cpp Source File

SPI8.cpp

00001  /* mbed UniGraphic library - SPI8 protocol class
00002  * Copyright (c) 2015 Giuliano Dianda
00003  * Released under the MIT License: http://mbed.org/license/mit
00004  *
00005  * Derived work of:
00006  *
00007  * mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller
00008  * Copyright (c) 2013 Peter Drescher - DC2PD
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00011  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00012  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00013  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00014  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00015  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00016  * THE SOFTWARE.
00017  */
00018  
00019 #include "SPI8.h"
00020 
00021 
00022 SPI8::SPI8(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC)
00023     : _CS(CS), _spi(mosi, miso, sclk), _reset(reset), _DC(DC)
00024 {
00025     _reset = 1;
00026     _DC=1;
00027     _CS=1;
00028     _spi.format(8,0);                  // 8 bit spi mode 0
00029     _spi.frequency(Hz);
00030     hw_reset();    
00031 }
00032 
00033 void SPI8::wr_cmd8(unsigned char cmd)
00034 {     
00035     _DC.write(0); // 0=cmd
00036     _spi.write(cmd);      // write 8bit
00037     _DC.write(1); // 1=data next
00038 }
00039 void SPI8::wr_data8(unsigned char data)
00040 {
00041     _spi.write(data);    // write 8bit
00042 }
00043 void SPI8::wr_cmd16(unsigned short cmd)
00044 {     
00045     _DC.write(0); // 0=cmd
00046     _spi.write(cmd>>8);      // write 8bit
00047     _spi.write(cmd&0xFF);      // write 8bit
00048     _DC.write(1); // 1=data next
00049 }
00050 void SPI8::wr_data16(unsigned short data)
00051 {
00052     _spi.write(data>>8);    // write 8bit
00053     _spi.write(data&0xFF);    // write 8bit
00054 }
00055 void SPI8::wr_gram(unsigned short data)
00056 {
00057     _spi.write(data>>8);    // write 8bit
00058     _spi.write(data&0xFF);    // write 8bit
00059 }
00060 void SPI8::wr_gram(unsigned short data, unsigned int count)
00061 {
00062     if((data>>8)==(data&0xFF))
00063     {
00064         count<<=1;
00065         while(count)
00066         {
00067             _spi.write(data);    // write 8bit
00068             count--;
00069         }
00070     }
00071     else
00072     {
00073         while(count)
00074         {
00075             _spi.write(data>>8);    // write 8bit
00076             _spi.write(data&0xFF);    // write 8bit
00077             count--;
00078         }
00079     }
00080 }
00081 void SPI8::wr_grambuf(unsigned short* data, unsigned int lenght)
00082 {
00083     while(lenght)
00084     {
00085         _spi.write((*data)>>8);    // write 8bit
00086         _spi.write((*data)&0xFF);    // write 8bit
00087         data++;
00088         lenght--;
00089     }
00090 }
00091 unsigned short SPI8::rd_gram(bool convert)
00092 {
00093     unsigned int r=0;
00094     _spi.write(0); // whole first byte is dummy
00095     r |= _spi.write(0);
00096     r <<= 8;
00097     r |= _spi.write(0);
00098     if(convert)
00099     {
00100         r <<= 8;
00101         r |= _spi.write(0);
00102         // gram is 18bit/pixel, if you set 16bit/pixel (cmd 3A), during writing the 16bits are expanded to 18bit
00103         // during reading, you read the raw 18bit gram
00104         r = RGB24to16((r&0xFF0000)>>16, (r&0xFF00)>>8, r&0xFF);// 18bit pixel padded to 24bits, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
00105     } 
00106     _CS = 1; // force CS HIG to interupt the "read state"
00107     _CS = 0;
00108     return (unsigned short)r;
00109 }
00110 unsigned int SPI8::rd_reg_data32(unsigned char reg)
00111 {
00112     wr_cmd8(reg);
00113     unsigned int r=0;
00114    
00115     r |= _spi.write(0); // we get only 7bit valid, first bit was the dummy cycle
00116     r <<= 8;
00117     r |= _spi.write(0);
00118     r <<= 8;
00119     r |= _spi.write(0);
00120     r <<= 8;
00121     r |= _spi.write(0);
00122     r <<= 1; // 32bits are aligned, now collecting bit_0
00123     r |= (_spi.write(0) >> 7);
00124     // we clocked 7 more bit so ILI waiting for 8th, we need to reset spi bus
00125     _CS = 1; // force CS HIG to interupt the cmd
00126     _CS = 0;
00127     return r;
00128 }
00129 unsigned int SPI8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
00130 {
00131     unsigned int r=0;
00132     for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1
00133     {
00134         wr_cmd8(SPIreadenablecmd);  // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know
00135         wr_data8(0xF0|regparam);    // in low nibble specify which reg parameter we want
00136         wr_cmd8(reg);               // now send cmd (select register we want to read)
00137         r <<= 8;
00138         r |= _spi.write(0);
00139         // r = _spi.write(0) >> 8; for 16bit
00140     }
00141     _CS = 1; // force CS HIG to interupt the cmd
00142     _CS = 0;
00143     return r;
00144 }
00145 // ILI932x specific
00146 void SPI8::dummyread()
00147 {
00148     _spi.write(0);    // dummy read
00149 }
00150 // ILI932x specific
00151 void SPI8::reg_select(unsigned char reg, bool forread)
00152 {
00153     _CS = 1;    //fixme: really needed?
00154     _CS = 0;    //fixme: really needed?
00155     _spi.write(0x70);
00156     _spi.write(0);    // write MSB
00157     _spi.write(reg);    // write LSB
00158     _CS = 1;    //fixme: really needed?
00159     _CS = 0;    //fixme: really needed?
00160     if(forread) _spi.write(0x73);
00161     else _spi.write(0x72);
00162 }
00163 // ILI932x specific
00164 void SPI8::reg_write(unsigned char reg, unsigned short data)
00165 {
00166     _CS = 1;    //fixme: really needed?
00167     _CS = 0;    //fixme: really needed?
00168     _spi.write(0x70);
00169     _spi.write(0);    // write MSB
00170     _spi.write(reg);    // write LSB
00171     _CS = 1;    //fixme: really needed?
00172     _CS = 0;    //fixme: really needed?
00173     _spi.write(0x72);
00174     _spi.write(data>>8);
00175     _spi.write(data&0xFF);
00176 }
00177 // ILI932x specific
00178 unsigned short SPI8::reg_read(unsigned char reg)
00179 {
00180     unsigned short r=0;
00181     _CS = 1;    //fixme: really needed?
00182     _CS = 0;    //fixme: really needed?
00183     _spi.write(0x70);
00184     _spi.write(0);    // write MSB
00185     _spi.write(reg);    // write LSB
00186     _CS = 1;    //fixme: really needed?
00187     _CS = 0;    //fixme: really needed?
00188     _spi.write(0x73);
00189     _spi.write(0);    // dummy read
00190     r = _spi.write(0);    // read 8bit
00191     r <<= 8;
00192     r |= _spi.write(0);    // read 8bit
00193     return r;
00194 }
00195 void SPI8::hw_reset()
00196 {
00197     wait_ms(15);
00198     _DC = 1;
00199     _CS = 1;
00200     _reset = 0;                        // display reset
00201     wait_ms(2);
00202     _reset = 1;                       // end reset
00203     wait_ms(100);
00204 }
00205 void SPI8::BusEnable(bool enable)
00206 {
00207     _CS = enable ? 0:1;
00208 }