SSD1963 Initial code & test fill screen.

Dependencies:   mbed

SSD1963/SSD1963.cpp

Committer:
techstep
Date:
2014-04-18
Revision:
0:2714fcd95190

File content as of revision 0:2714fcd95190:

/*****************************************************************************
 * 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"
//#include "tFontLCD.c"
//#include "stm32f4xx.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() {
    init();
}
/*
uint16_t SSD1963::width(void) {
  return _width;
}
uint16_t SSD1963::height(void) {
  return _height;
}
*/
void SSD1963::init(void) {
    
    /* GPIOC Periph clock enable */
    //RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN); // For F401RE
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    //RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
    //RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    
    /* Configure PC[0..7] in input/output mode  */
    GPIOC->MODER |= (GPIO_MODER_MODER0_0  | GPIO_MODER_MODER1_0  | GPIO_MODER_MODER2_0  | GPIO_MODER_MODER3_0  |
                     GPIO_MODER_MODER4_0  | GPIO_MODER_MODER5_0  | GPIO_MODER_MODER6_0  | GPIO_MODER_MODER7_0);
    /* Configure PA[8..15] in input/output mode  */
    GPIOC->MODER |= (GPIO_MODER_MODER8_0  | GPIO_MODER_MODER9_0  | GPIO_MODER_MODER10_0 | GPIO_MODER_MODER11_0 |
                     GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0);
    /* Configure PB[0:1:2:6:7] in input/output mode  */
    GPIOB->MODER |= (GPIO_MODER_MODER0_0  | GPIO_MODER_MODER1_0  | GPIO_MODER_MODER2_0  |
                     GPIO_MODER_MODER6_0  | GPIO_MODER_MODER7_0);

    // Ensure push pull mode selected--default
    GPIOC->OTYPER &= ~(GPIO_OTYPER_OT_0  | GPIO_OTYPER_OT_1  | GPIO_OTYPER_OT_2  | GPIO_OTYPER_OT_3  |
                       GPIO_OTYPER_OT_4  | GPIO_OTYPER_OT_5  | GPIO_OTYPER_OT_6  | GPIO_OTYPER_OT_7);
    GPIOC->OTYPER &= ~(GPIO_OTYPER_OT_8  | GPIO_OTYPER_OT_9  | GPIO_OTYPER_OT_10 | GPIO_OTYPER_OT_11 |
                       GPIO_OTYPER_OT_12 | GPIO_OTYPER_OT_13 | GPIO_OTYPER_OT_14 | GPIO_OTYPER_OT_15);
    GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_0  | GPIO_OTYPER_OT_1  | GPIO_OTYPER_OT_2  |
                       GPIO_OTYPER_OT_6  | GPIO_OTYPER_OT_7);

    //Ensure maximum speed setting (even though it is unnecessary)
    GPIOC->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR0  | GPIO_OSPEEDER_OSPEEDR1  | GPIO_OSPEEDER_OSPEEDR2  | GPIO_OSPEEDER_OSPEEDR3  |
                       GPIO_OSPEEDER_OSPEEDR4  | GPIO_OSPEEDER_OSPEEDR5  | GPIO_OSPEEDER_OSPEEDR6  | GPIO_OSPEEDER_OSPEEDR7);
    GPIOC->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR8  | GPIO_OSPEEDER_OSPEEDR9  | GPIO_OSPEEDER_OSPEEDR10 | GPIO_OSPEEDER_OSPEEDR11 |
                       GPIO_OSPEEDER_OSPEEDR12 | GPIO_OSPEEDER_OSPEEDR13 | GPIO_OSPEEDER_OSPEEDR14 | GPIO_OSPEEDER_OSPEEDR15);
    GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR0  | GPIO_OSPEEDER_OSPEEDR1  | GPIO_OSPEEDER_OSPEEDR2  |
                       GPIO_OSPEEDER_OSPEEDR6  | GPIO_OSPEEDER_OSPEEDR7);

    //Ensure all pull up pull down resistors are disabled
    //GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR0  | GPIO_PUPDR_PUPDR1  | GPIO_PUPDR_PUPDR2  | GPIO_PUPDR_PUPDR3  |
    //                  GPIO_PUPDR_PUPDR4  | GPIO_PUPDR_PUPDR5  | GPIO_PUPDR_PUPDR6  | GPIO_PUPDR_PUPDR7);
    // Pull UP
    //GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR0_0  | GPIO_PUPDR_PUPDR1_0  | GPIO_PUPDR_PUPDR2_0  | GPIO_PUPDR_PUPDR3_0  |
    //                  GPIO_PUPDR_PUPDR4_0  | GPIO_PUPDR_PUPDR5_0  | GPIO_PUPDR_PUPDR6_0  | GPIO_PUPDR_PUPDR7_0);
    // Pull Down
    GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR0_1  | GPIO_PUPDR_PUPDR1_1  | GPIO_PUPDR_PUPDR2_1  | GPIO_PUPDR_PUPDR3_1  |
                      GPIO_PUPDR_PUPDR4_1  | GPIO_PUPDR_PUPDR5_1  | GPIO_PUPDR_PUPDR6_1  | GPIO_PUPDR_PUPDR7_1);
                      
    //GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR8  | GPIO_PUPDR_PUPDR9  | GPIO_PUPDR_PUPDR10 | GPIO_PUPDR_PUPDR11 |
    //                  GPIO_PUPDR_PUPDR12 | GPIO_PUPDR_PUPDR13 | GPIO_PUPDR_PUPDR14 | GPIO_PUPDR_PUPDR15);
    GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR8_1  | GPIO_PUPDR_PUPDR9_1  | GPIO_PUPDR_PUPDR10_1 | GPIO_PUPDR_PUPDR11_1 |
                      GPIO_PUPDR_PUPDR12_1 | GPIO_PUPDR_PUPDR13_1 | GPIO_PUPDR_PUPDR14_1 | GPIO_PUPDR_PUPDR15_1);
    GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR0  | GPIO_PUPDR_PUPDR1  | GPIO_PUPDR_PUPDR2  |
                      GPIO_PUPDR_PUPDR6  | GPIO_PUPDR_PUPDR7);

    wait_ms(100);
  //rotation  = 0;
  //cursor_y  = cursor_x = 0;
  //textsize  = 1;
  //textcolor = 0xFFFF;
  //_width    = TFTWIDTH;
  //_height   = TFTHEIGHT;
  //wrap      = true;
}

void SSD1963::writeData(uint16_t data) {
    CS_LOW; RS_HIGH; RD_HIGH; WR_HIGH;
    //GPIOA->ODR = (data&0xFF00);
    //GPIOC->ODR = (data&0x00FF);
    GPIOC->ODR = (data&0xFFFF);
    WR_STROBE;
    CS_HIGH;
}

void SSD1963::writeCommand(uint16_t cmd) {
    CS_LOW; RS_LOW; RD_HIGH; WR_HIGH;
    //GPIOA->ODR = (cmd&0xFF00);
    //GPIOC->ODR = (cmd&0x00FF);
    GPIOC->ODR = (cmd&0xFFFF);
    WR_STROBE;
    RS_HIGH;
    CS_HIGH;
}

uint16_t SSD1963::readData(void) {
    uint16_t data = 0x0000;
    CS_LOW; RS_HIGH; RD_LOW; WR_HIGH;
    wait_us(10);
    //data = (GPIOA->IDR&0xFF00 | GPIOC->IDR&0x00FF);
    data = (GPIOC->IDR&0xFFFF);
    RD_HIGH;
    CS_HIGH;
    return data;
}

void SSD1963::writeRegister(uint16_t addr, uint16_t data) {
    writeCommand(addr);
    writeData(data);
}

void SSD1963::reset(void) {
    //CS_LOW;
    RST_HIGH;  wait_ms(2);
    RST_LOW;   wait_ms(2);
    RST_HIGH;  wait_ms(4);
    
    CS_HIGH;
    RS_HIGH;
    RD_HIGH;
    WR_HIGH;
}

void SSD1963::begin() {

    reset();
    wait_ms(10);
    // Set PLL MN -------------------------------------------------------------
    // @Parameters : 3
    writeCommand(0xE2);
    writeData(0x23);             // N[7:0] : Multiplier (N) of PLL. (POR = 00101101) b00100011
    writeData(0x02);             // M[3:0] : Divider (M) of PLL. (POR = 0011)
    writeData(0x04);             // C[2] : Effectuate MN value (POR = 100) - Effectuate the multiplier and divider value
    //writeData(0x54);
    
    // Set PLL
    // @Parameters : 1
    writeCommand(0xE0);
    writeData(0x01);             // Use reference clock as system clock & Enable PLL
    wait_us(100);                  // Wait 100us to let the PLL stable
    writeCommand(0xE0);             // Set PLL
    writeData(0x03);             // Use PLL output as system clock & Enable PLL
    wait_us(100); 

    // Software Reset ---------------------------------------------------------
    writeCommand(0x01);
    wait_us(100);   

    // Set LSHIFT Frequency ---------------------------------------------------
    // @Parameters : 3
    writeCommand(0xE6);             // Set LSHIFT Frequency
    writeData(0x03);             // LCDC_FPR[19:16] : The highest 4 bits for the pixel clock frequency settings
    writeData(0xFF);             // LCDC_FPR[15:8]  : The higher byte for the pixel clock frequency settings
    writeData(0xFF);             // LCDC_FPR[7:0]   : The low byte for the pixel clock frequency settings

    // Set LCD Mode
    // @Parameters : 7
    writeCommand(0xB0);
    /*
    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(0x10);                // set 18-bit for 7" panel TY700TFT800480
    writeData(0x80);                // 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
    writeCommand(0xB4);
    /*
    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
    writeCommand(0xB6);
    /*
    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
    writeCommand(0xBA);
    writeData(0x05);             // A[3..0] : GPIO[2:0] Output 1
    
    // Set GPIO Configuration
    // @Parameters : 2
    writeCommand(0xB8);
    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(0x3A);
    writeData(0x55);                // set 16bpp

    // Set Address Mode -------------------------------------------------------
    // @Parameters : 1
    //writeCommand(0x36);             // Set Rotation
    //writeData(0x00);             // 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
    writeCommand(0xF0);             // A[2:0] : Pixel Data Interface Format
    writeData(0x03);             // 16-bit (565 format)
    wait_us(100);
    
    // enter_partial_mode
    //writeCommand(0x12);             // Part of the display area is used for image display
    // set_display_on
    writeCommand(0x29);             // Show the image on the display device
    
    //writeCommand(0x2C);
}

void SSD1963::fillScreen(uint16_t color){
    
    uint16_t start_x = 0;
    uint16_t end_x   = 799;
    uint16_t start_y = 0;
    uint16_t end_y   = 479;
    
    writeCommand(0x2A);
    //nCS_LOW;
    writeData(start_x>>8);
    writeData(start_x);
    writeData(end_x>>8);
    writeData(end_x);
    //nCS_HIGH;
    writeCommand(0x2B);
    //nCS_LOW;
    writeData(start_y>>8);
    writeData(start_y);
    writeData(end_y>>8);
    writeData(end_y);
    //nCS_HIGH;
    
    writeCommand(0x2C);

    uint16_t i,j;
    for(i=0;i<800;i++){
        for (j=0;j<480;j++){
            writeData(color);
        }
    }
}

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