ssd1963

SSD1963.cpp

Committer:
sPymbed
Date:
2020-10-16
Revision:
4:84a51911fb31
Parent:
3:31ca3cd96572

File content as of revision 4:84a51911fb31:

/*****************************************************************************
 * Project      : 7" TFT LCD 800x480 [AT070TN92]
 * Compiler     : mbed Online
 * Type         : Libraries
 * Comment      : Support mbed ST Nucleo Board.
 *              : Support Chip = SSD1963
 * File         : SSD1963.c
 *
 * Author       : Mr.Thongchai Artsamart [Bird Techstep]
 * E-Mail       : t.artsamart@gmail.com
 *              : tbird_th@hotmail.com
 * Start Date   : 20/03/2014 [dd/mm/yyyy]
 * Version Date : 20/03/2014 [dd/mm/yyyy]
 * Licensed under a Creative Commons Attribution-ShareAlike 3.0 License.
 *****************************************************************************
 * Remark    : Thank you -. no1wudi [CooCox]
 *                       -.
 *****************************************************************************/
#include "mbed.h"
#include "SSD1963.h"

/*
#define  HDP 799     // [ 799][ 799] Horizontal Display Period
#define  HT  928     // [ 928][1000] Horizontal Total
#define  HPS 46      // [  46][  51] LLINE Pulse Start Position
#define  LPS 15      // [  15][   3] Horizontal Display Period Start Position
#define  HPW 48      // [  48][   8] LLINE Pulse Width
#define  VDP 479     // [ 479][ 479] Vertical Display Period
#define  VT  525     // [ 525][ 530] Vertical Total
#define  VPS 16      // [  16][  24] LFRAME Pulse Start Position
#define  FPS 8       // [   8][  23] Vertical Display Period Start Position
#define  VPW 16      // [  16][   3] LFRAME Pulse Width
*/

SSD1963::SSD1963(PinName CS, PinName RESET, PinName RS, PinName WR, BusInOut* DATA_PORT, PinName RD, PinName BL, backlight_t blType):
LCD( 272, 480, CS, RS, RESET, BL, blType, 1.0 ), _lcd_pin_wr( WR ), _lcd_pin_rd(RD)
{
    _lcd_port = DATA_PORT;
}

void SSD1963::WriteData(unsigned short data) {
    Activate();
    _lcd_pin_rs = HIGH;
    _lcd_pin_wr = LOW;
     _lcd_port->output();
    _lcd_port->write( data );
    wait_us(1);
    _lcd_pin_wr = HIGH;
    Deactivate();
}

void SSD1963::WriteCmd(unsigned short cmd) {
    Activate();
    _lcd_pin_rs = LOW;
    _lcd_pin_wr = LOW;
    _lcd_port->output();
    _lcd_port->write( cmd );
    wait_us(1);
    _lcd_pin_wr = HIGH;
    _lcd_pin_rs = HIGH;
    Deactivate();
}

uint16_t SSD1963::readData(void) {
    uint16_t data = 0x0000;
    Activate();
    _lcd_pin_rs = HIGH; _lcd_pin_rd = LOW;
    wait_us(10);
    _lcd_port->input();
    data = _lcd_port->read() & 0xFFFF;
    wait_us(1);
    _lcd_pin_rd = HIGH;
    Deactivate();
    return data;
}

void SSD1963::writeRegister(uint16_t addr, uint16_t data) {
    WriteCmd(addr);
    WriteData(data);
}

void SSD1963::reset(void) {
    _lcd_pin_reset = HIGH;
    wait_ms( 5 );
    _lcd_pin_reset = LOW;
    wait_ms( 15 );
    _lcd_pin_reset = HIGH;
    _lcd_pin_cs = HIGH;
    _lcd_pin_rd = HIGH;
    _lcd_pin_wr = HIGH;
    _lcd_pin_rs = HIGH;
    if ( _lcd_pin_bl != 0 )
        *_lcd_pin_bl = HIGH;
    else if ( _bl_pwm != 0 )
        *_bl_pwm = _bl_pwm_default;
}

void SSD1963::begin() {
    reset();
    wait_ms(10);
    // Set PLL MN -------------------------------------------------------------
    // @Parameters : 3
    WriteCmd(Com_SetPLLConfig);
    WriteData(0x1d);             // N[7:0] : Multiplier (N) of PLL. (POR = 00101101) b00100011
    WriteData(0x02);             // M[3:0] : Divider (M) of PLL. (POR = 0011)
    WriteData(0x54);             // C[2] : Effectuate MN value (POR = 100) - Effectuate the multiplier and divider 

    // Set PLL
    // @Parameters : 1
    WriteCmd(Com_SetPLLStart);
    WriteData(0x01);             // Use reference clock as system clock & Enable PLL
    wait_us(100);                // Wait 100us to let the PLL stable
    WriteCmd(Com_SetPLLStart);             // Set PLL
    WriteData(0x03);             // Use PLL output as system clock & Enable PLL
    wait_us(100);

    // Software Reset ---------------------------------------------------------
    WriteCmd(Com_Reset);
    wait_ms(100);

    // Set LSHIFT Frequency ---------------------------------------------------
    // @Parameters : 3
    WriteCmd(Com_SetPixelClock);             // Set LSHIFT Frequency
    WriteData(0x01);             // LCDC_FPR[19:16] : The highest 4 bits for the pixel clock frequency settings
    WriteData(0x70);             // LCDC_FPR[15:8]  : The higher byte for the pixel clock frequency settings
    WriteData(0xa2);             // LCDC_FPR[7:0]   : The low byte for the pixel clock frequency settings
    wait_ms(1);

    // Set Horizontal Period ---------------------
    // Set LCD Mode
    // @Parameters : 7
    WriteCmd(Com_SetLCDMode);
    /*
    writeData(0x00);             // A[5..0] TFT
    //writeData(0x10);
    writeData(0x00);             // B[7..5]   : Hsync+Vsync +DE mode & TFT mode
    //writeData(0x80);
    writeData((HDP>>8)&0xFF);    // HPS[10:8] : Set the horizontal panel size (POR = 010)
    writeData(HDP&0xFF);         // HPS[7:0]  : Set the horizontal panel size (POR = 01111111)
    writeData((VDP>>8)&0xFF);    // VPS[10:8] : Set the vertical panel size (POR = 001)
    writeData(VDP&0xFF);         // VPS[7:0]  : Set the vertical panel size (POR = 11011111)
    writeData(0x00);             // G[5..0]   : Even line RGB sequence & Odd line RGB sequence
    */
    WriteData(0x0c);                // set 18-bit for 7" panel TY700TFT800480
    WriteData(0x00);                // set TTL mode
    WriteData((DISP_HOR_RESOLUTION - 1) >> 8); //Set panel size
    WriteData(DISP_HOR_RESOLUTION - 1);
    WriteData((DISP_VER_RESOLUTION - 1) >> 8);
    WriteData(DISP_VER_RESOLUTION - 1);
    WriteData(0x00);

    // Set Horizontal Period --------------------------------------------------
    // @Parameters : 8
    WriteCmd(Com_SetHoriPeriod);
    /*
    writeData((HT>>8)&0xFF);     // HT[10:8]   : High byte of horizontal total period (display + non-display) in pixel clock
    writeData(HT&0xFF);          // HT[7:0]    : Low byte of the horizontal total period (display + non-display) in pixel clock
    writeData((HPS>>8)&0xFF);    // HPS[10:8]  : High byte of the non-display period between the start of the horizontal sync (LLINE) signal
    writeData(HPS&0xFF);         // HPS[7:0]   : Low byte of the non-display period between the start of the horizontal sync (LLINE) signal
    writeData(HPW&0xFF);         // HPW[6:0]   : Set the horizontal sync pulse width (LLINE) in pixel clock
    writeData((LPS>>8)&0xFF);    // LPS[10:8]  : Set the horizontal sync pulse (LLINE) start location in pixel clock
    writeData(LPS&0xFF);         // LPS[7:0]   : Set the horizontal sync pulse width (LLINE) in start.
    writeData(0x00);             // LPSPP[1:0] : Set the horizontal sync pulse subpixel start position
    */
    #define HT (DISP_HOR_RESOLUTION + DISP_HOR_PULSE_WIDTH + DISP_HOR_BACK_PORCH + DISP_HOR_FRONT_PORCH)
    WriteData((HT - 1) >> 8);   
    WriteData(HT - 1);
    #define HPS (DISP_HOR_PULSE_WIDTH + DISP_HOR_BACK_PORCH)
    WriteData((HPS - 1) >> 8);
    WriteData(HPS - 1);
    WriteData(DISP_HOR_PULSE_WIDTH - 1);
    WriteData(0x00);
    WriteData(0x00);
    WriteData(0x00);

    // Set Vertical Period ----------------------------------------------------
    // @Parameters : 7
    WriteCmd(Com_SetVertPeriod);
    /*
    writeData((VT>>8)&0xFF);     // VT[10:8]  : High byte of the vertical total (display + non-display) period in lines
    writeData(VT&0xFF);          // VT[7:0]   : Low byte of the vertical total (display + non-display) period in lines
    writeData((VPS>>8)&0xFF);    // VPS[10:8] : High byte the non-display period in lines between the start of the frame and the first display data in line
    writeData(VPS&0xFF);         // VPS[7:0]  : The non-display period in lines between the start of the frame and the first display data in line
    writeData(VPW&0xFF);         // VPW[6:0]  : Set the vertical sync pulse width (LFRAME) in lines
    writeData((FPS>>8)&0xFF);    // FPS[10:8] : High byte of the vertical sync pulse (LFRAME) start location in lines
    writeData(FPS&0xFF);         // FPS[7:0]  : Low byte of the vertical sync pulse (LFRAME) start location in lines
    */
    #define VT (DISP_VER_PULSE_WIDTH + DISP_VER_BACK_PORCH + DISP_VER_FRONT_PORCH + DISP_VER_RESOLUTION)
    WriteData((VT - 1) >> 8);
    WriteData(VT - 1);
    #define VSP (DISP_VER_PULSE_WIDTH + DISP_VER_BACK_PORCH)
    WriteData((VSP - 1) >> 8);
    WriteData(VSP - 1);
    WriteData(DISP_VER_PULSE_WIDTH - 1);
    WriteData(0x00);
    WriteData(0x00);

    // Set GPIO Value ---------------------------------------------------------
    // @Parameters : 1
    WriteCmd(Com_SetGPIOValue);
    WriteData(0x0f);             // A[3..0] : GPIO[2:0] Output 1
    
    // Set GPIO Configuration
    // @Parameters : 2
    WriteCmd(Com_SetGPIOConf);
    WriteData(0x07);             // A[7..0] : GPIO3 = Input, GPIO[2:0] = Output
    WriteData(0x01);             // B[0] : GPIO0 Normal
    
    //Set pixel format, i.e. the bpp
    //writeCommand(Com_SetPixelFormat);
    //writeData(0x55);                // set 16bpp

    // Set Address Mode -------------------------------------------------------
    // @Parameters : 1
    //writeCommand(0x36);             // Set Rotation
    //writeData(0x2a);                // A[7..0] : Set the read order from host processor to frame buffer by A[7:5] and A[3] and 
                                                       // from frame buffer to the display panel by A[2:0] and A[4].
                                                       // A[7] : Page address order
    
    // Set Pixel Data Interface -----------------------------------------------
    // @Parameters : 1
    WriteCmd(Com_SetPixelInterface);             // A[2:0] : Pixel Data Interface Format
    WriteData(0x03);             // 16-bit (565 format)
    wait_us(100);
    
    /*writeCommand(Com_SetTearOff);*/
    wait_ms(1);
    WriteCmd(Com_SetGPIOConf);
    WriteData(0x0f);    //GPIO is controlled by host GPIO[3:0]=output   GPIO[0]=1  LCD ON  GPIO[0]=1  LCD OFF 
    WriteData(0x01);    //GPIO0 normal

    WriteCmd(Com_SetGPIOValue);
    WriteData(0x01);    //GPIO[0] out 1 --- LCD display on/off control PIN
    
    // enter_partial_mode
    //writeCommand(0x12);             // Part of the display area is used for image display
    // set_display_on
    WriteCmd(Com_SetDisplayOn);             // Show the image on the display device

    //writeCommand(0x2C);
}

void SSD1963::SetXY( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2 )
{
    //if ( _orientation == PORTRAIT || _orientation == PORTRAIT_REV )
    //{
        WriteCmd(Com_SetColumnAddress);
        WriteData( x1>>8 );
        WriteData( x1 );
        WriteData( x2>>8 );
        WriteData( x2 );
        WriteCmd( Com_SetPageAddress);
        WriteData( y1>>8 );
        WriteData( y1 );
        WriteData( y2>>8 );
        WriteData( y2 );
    /*}
    else
    {
        WriteCmd( 0x2A);
        WriteData( y1>>8 );
        WriteData( y1 );
        WriteData( y2>>8 );
        WriteData( y2 );
        WriteCmd( 0x2B);
        WriteData( x1>>8 );
        WriteData( x1 );
        WriteData( x2>>8 );
        WriteData( x2 );
        WriteCmd( 0x2B);
    }*/
    WriteCmd(Com_WriteMemory);
}

void SSD1963::SetPixelColor( unsigned int color, colordepth_t mode )
{
    unsigned char r, g, b;
    unsigned short clr;
    if ( _colorDepth == RGB16 )
    {
        switch ( mode )
        {
            case RGB16:
                WriteData( color & 0xFFFF );
                break;
            case RGB18:
                r = ( color >> 10 ) & 0xF8;
                g = ( color >> 4 ) & 0xFC;
                b = ( color >> 1 ) & 0x1F;
                clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | b );
                WriteData( clr );
                break;
            case RGB24:
                r = ( color >> 16 ) & 0xF8;
                g = ( color >> 8 ) & 0xFC;
                b = color & 0xF8;
                clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | ( b >> 3 ) );
                WriteData( clr );
                break;
        }
    }
    else if ( _colorDepth == RGB18 )
    {
        switch ( mode )
        {
            case RGB16:
                r = ( ( color >> 8 ) & 0xF8 ) | ( ( color & 0x8000 ) >> 13 );
                g = ( color >> 3 ) & 0xFC;
                b = ( ( color << 3 ) & 0xFC ) | ( ( color >> 3 ) & 0x01 );
                WriteData( ( r << 8 ) | g );
                WriteData( b );
                break;
            case RGB18:
                b = ( color << 2 ) & 0xFC;
                g = ( color >> 4 ) & 0xFC;
                r = ( color >> 10 ) & 0xFC;
                WriteData( ( r << 8 ) | g );
                WriteData( b );
                break;
            case RGB24:
                r = ( color >> 16 ) & 0xFC;
                g = ( color >> 8 ) & 0xFC;
                b = color & 0xFC;
                WriteData( ( r << 8 ) | g );
                WriteData( b );
                break;
        }
    }
}

// - Color RGB R5 G6 B5 -------------------------------------------------------
uint16_t SSD1963::Color565(uint8_t r, uint8_t g, uint8_t b) {
  uint16_t c;
  c = r >> 3;
  c <<= 6;
  c |= g >> 2;
  c <<= 5;
  c |= b >> 3;
  return c;
}