ILI9341_SPI

Dependencies:   fonts

Dependents:   ov7670_dma_nucleo_f4 NUCLEO-F446RE_testDCMI

ILI9341.cpp

Committer:
tmnt
Date:
2016-11-20
Revision:
1:2446b5e1a4fb
Parent:
0:2d4605aef62f

File content as of revision 1:2446b5e1a4fb:


#include <mbed.h>
#include "ILI9341.h"
#include "font6x12.h"

ili9341_spi::ili9341_spi(SPI& _spi, PinName _cs,PinName _dc,PinName _rs) : spi(_spi), cs(_cs),dc(_dc),rs(_rs) {}


void ili9341_spi::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
    wr_cmd(0x2A);
    spi.write(x >> 8);
    spi.write(x);
    spi.write((x+w-1) >> 8);
    spi.write(x+w-1);
    
    cs = 1;
    wr_cmd(0x2B);
    spi.write(y >> 8);
    spi.write(y);
    spi.write((y+h-1) >> 8);
    spi.write(y+h-1);
    cs = 1;
}
void ili9341_spi::wr_cmd(unsigned char cmd)
{
    dc = 0;
    cs = 0;
    spi.write(cmd);      // mbed lib
    dc = 1;
}
void ili9341_spi::wr_dat(unsigned char dat)
{
   spi.write(dat);      // mbed lib
}
char ili9341_spi::rd_byte(unsigned char cmd)
{
    char r;
    dc = 0;
    cs = 0;
    spi.write(cmd);      // mbed lib
    cs = 1;
    r = spi.write(0xff);
    cs = 1;    
    return(r);
}
int ili9341_spi::rd_32(unsigned char cmd)
{
    int d;
    char r;
    dc = 0;
    cs = 0;
    d = cmd;
    d = d << 1;
    spi.format(9,3);    // we have to add a dummy clock cycle
    spi.write(d);
    spi.format(8,3);   
    dc = 1;
    r = spi.write(0xff);
    d = r;
    r = spi.write(0xff);
    d = (d << 8) | r;
    r = spi.write(0xff);
    d = (d << 8) | r;
    r = spi.write(0xff);
    d = (d << 8) | r;
    cs = 1;    
    return(d);
}
int ili9341_spi:: Read_ID(void){
    int r;
    r = rd_byte(0x0A);
    r = rd_byte(0x0A);
    r = rd_byte(0x0A);
    r = rd_byte(0x0A);
    return(r);
}

void ili9341_spi::tft_reset()
{
    cs = 1;                           // cs high
    dc = 1;                           // dc high 
    rs = 0;                        // display reset
 
    wait_us(50);
    rs = 1;                       // end hardware reset
    wait_ms(5);
     
    wr_cmd(0x01);                     // SW reset  
    wait_ms(5);
    wr_cmd(0x28);                     // display off  
 
    /* Start Initial Sequence ----------------------------------------------------*/
     wr_cmd(0xCF);                     
     spi.write(0x00);
     spi.write(0x83);
     spi.write(0x30);
     cs = 1;
     
     wr_cmd(0xED);                     
     spi.write(0x64);
     spi.write(0x03);
     spi.write(0x12);
     spi.write(0x81);
     cs = 1;
     
     wr_cmd(0xE8);                     
     spi.write(0x85);
     spi.write(0x01);
     spi.write(0x79);
     cs = 1;
     
     wr_cmd(0xCB);                     
     spi.write(0x39);
     spi.write(0x2C);
     spi.write(0x00);
     spi.write(0x34);
     spi.write(0x02);
     cs = 1;
           
     wr_cmd(0xF7);                     
     spi.write(0x20);
     cs = 1;
           
     wr_cmd(0xEA);                     
     spi.write(0x00);
     spi.write(0x00);
     cs = 1;
     
     wr_cmd(0xC0);                     // POWER_CONTROL_1
     spi.write(0x26);
     cs = 1;
 
     wr_cmd(0xC1);                     // POWER_CONTROL_2
     spi.write(0x11);
     cs = 1;
     
     wr_cmd(0xC5);                     // VCOM_CONTROL_1
     spi.write(0x35);
     spi.write(0x3E);
     cs = 1;
     
     wr_cmd(0xC7);                     // VCOM_CONTROL_2
     spi.write(0xBE);
     cs = 1; 
     
     wr_cmd(0x36);                     // MEMORY_ACCESS_CONTROL
     spi.write(0x48);
     cs = 1; 
     
     wr_cmd(0x3A);                     // COLMOD_PIXEL_FORMAT_SET
     spi.write(0x55);                 // 16 bit pixel 
     cs = 1;
     
     wr_cmd(0xB1);                     // Frame Rate
     spi.write(0x00);
     spi.write(0x1B);               
     cs = 1;
     
     wr_cmd(0xF2);                     // Gamma Function Disable
     spi.write(0x08);
     cs = 1; 
     
     wr_cmd(0x26);                     
     spi.write(0x01);                 // gamma set for curve 01/2/04/08
     cs = 1; 
     
     wr_cmd(0xE0);                     // positive gamma correction
     spi.write(0x1F); 
     spi.write(0x1A); 
     spi.write(0x18); 
     spi.write(0x0A); 
     spi.write(0x0F); 
     spi.write(0x06); 
     spi.write(0x45); 
     spi.write(0x87); 
     spi.write(0x32); 
     spi.write(0x0A); 
     spi.write(0x07); 
     spi.write(0x02); 
     spi.write(0x07);
     spi.write(0x05); 
     spi.write(0x00);
     cs = 1;
     
     wr_cmd(0xE1);                     // negativ gamma correction
     spi.write(0x00); 
     spi.write(0x25); 
     spi.write(0x27); 
     spi.write(0x05); 
     spi.write(0x10); 
     spi.write(0x09); 
     spi.write(0x3A); 
     spi.write(0x78); 
     spi.write(0x4D); 
     spi.write(0x05); 
     spi.write(0x18); 
     spi.write(0x0D); 
     spi.write(0x38);
     spi.write(0x3A); 
     spi.write(0x1F);
     cs = 1;
     
     wr_cmd(0x2A);
    spi.write(0);
    spi.write(0);
    spi.write(0);
    spi.write(0x95);//95
    
    cs = 1;
    wr_cmd(0x2B);
    spi.write(0);
    spi.write(0);
    spi.write(0x00);
    spi.write(0x90);//90
    cs = 1;
     
     //wr_cmd(0x34);                     // tearing effect off
     //_cs = 1;
     
     //wr_cmd(0x35);                     // tearing effect on
     //_cs = 1;
      
     wr_cmd(0xB7);                       // entry mode
     spi.write(0x07);
     cs = 1;
     
     wr_cmd(0xB6);                       // display function control
     spi.write(0x0A);
     spi.write(0x82);
     spi.write(0x27);
     spi.write(0x00);
     cs = 1;
     
     wr_cmd(0x11);                     // sleep out
     cs = 1;
     
     wait_ms(100);
     
     wr_cmd(0x29);                     // display on
     cs = 1;
     
     wait_ms(100);
     
 }
void ili9341_spi::pixel(int x, int y, int color)
{
    wr_cmd(0x2A);
    spi.write(x >> 8);
    spi.write(x);
    cs = 1;
    wr_cmd(0x2B);
    spi.write(y >> 8);
    spi.write(y);
    cs = 1;
    wr_cmd(0x2C);  // send pixel
    //#if defined TARGET_KL25Z  // 8 Bit SPI
    spi.write(color >> 8);
    spi.write(color & 0xff);
    /*#else 
    SPI::format(16,3);                            // switch to 16 bit Mode 3
    SPI::write(color);                              // Write D0..D15
    SPI::format(8,3);
    #endif*/
    cs = 1;
}
void ili9341_spi::vline(int x, int y0, int y1, int color)
{
    int h;
    h = y1 - y0 + 1;
    window(x,y0,1,h);
    wr_cmd(0x2C);  // send pixel
    //#if defined TARGET_KL25Z  // 8 Bit SPI
    for (int y=0; y<h; y++) {
        spi.write(color >> 8);
        spi.write(color & 0xff);
    } 
  /*  #else 
    SPI::format(16,3);                            // switch to 16 bit Mode 3
    for (int y=0; y<h; y++) {
        SPI::write(color);
    }
    SPI::format(8,3);*/
    //#endif
    cs = 1;
    //WindowMax();
    return;
}

void ili9341_spi::circle(int x0, int y0, int r, int color)
{
 
    int x = -r, y = 0, err = 2-2*r, e2;
    do {
        pixel(x0-x, y0+y,color);
        pixel(x0+x, y0+y,color);
        pixel(x0+x, y0-y,color);
        pixel(x0-x, y0-y,color);
        e2 = err;
        if (e2 <= y) {
            err += ++y*2+1;
            if (-x == y && e2 <= x) e2 = 0;
        }
        if (e2 > x) err += ++x*2+1;
    } while (x <= 0);
    }
    
void ili9341_spi::fillrect(int x0, int y0, int x1, int y1, int color)
{
 
    int h = y1 - y0 + 1;
    int w = x1 - x0 + 1;
    int pixel = h * w;
    window(x0,y0,w,h);
    wr_cmd(0x2C);  // send pixel 
    //#if defined TARGET_KL25Z  // 8 Bit SPI
    for (int p=0; p<pixel; p++) {
        spi.write(color >> 8);
        spi.write(color & 0xff);
    }
   /*#else
    SPI::format(16,3);                            // switch to 16 bit Mode 3
    for (int p=0; p<pixel; p++) {
        SPI::write(color);
    }
    SPI::format(8,3);
    #endif*/
    cs = 1;
    //WindowMax();
    return;
}    

void ili9341_spi::draw_str(const char* str,uint8_t line)
{
    uint8_t len = strlen(str);

    for (int i = 0; i < len; i++)
    {
        if(i==0){draw_char(str[i],1,line);}
     else   draw_char(str[i],0,line);
    }
}

void ili9341_spi::draw_char(char ch,uint8_t rs,uint8_t line)
{
static ushort col=0,row=0;
static ushort pos_x = LEFT_PADDING, pos_y = TOP_PADDING;
    // 画面の右側に達したら改行する
    if(rs){pos_x=2;}
    pos_y = line*(FONT_6x12_HEIGHT + 2);
    if(pos_y==0){pos_y=2;}
    if (/*(col > 240 - 1) ||*/ ch == 10) 
    {
        col = 0; row++;
        pos_x = LEFT_PADDING; pos_y += FONT_6x12_HEIGHT + 2;
    }
    if (ch == 10) return;
  // 文字の出力範囲を設定
    window(pos_x,pos_y, FONT_6x12_WIDTH+1,FONT_6x12_HEIGHT+1);
  // 文字がASCII表にある位置を探す
    const byte* fc = fc_tab[(ushort)ch];
    if (fc != 0)
    {
        wr_cmd(0x2C);
        
        for (int y = 0; y < FONT_6x12_HEIGHT; y++)
        {
            for (int x = 0; x <= FONT_6x12_WIDTH; x++)
            {
                ushort k = (*fc) & (1 << (FONT_6x12_WIDTH - x));
           // フォントのピクセルを出力する
                spi.write(k ? /*(fcolor >> 8)*/0xff : /*(bcolor >> 8)*/0xf8);
                spi.write(k ? /*fcolor*/0xff : /*bcolor*/0x00);
            }
            fc++;
        }
    }
    col++;
    pos_x += FONT_6x12_WIDTH + 2;
}

void ili9341_spi::select() {
    //Set CS low to start transmission (interrupts conversion)
    cs = 0;   spi.frequency(60000000);
}
void ili9341_spi::deselect() {
    //Set CS high to stop transmission (restarts conversion)
    cs = 1;   spi.frequency(20000000);
}