/* LCD_DRV_FSMC.c
8bit LCD s5230 from FSMC 
*/
#ifndef _LCD_DRV_FSMC
#define _LCD_DRV_FSMC

#define LCD_RES_L 	GPIOD->BSRRH = GPIO_BSRR_BS_3	//reset pin = 0
#define LCD_RES_H 	GPIOD->BSRRL = GPIO_BSRR_BS_3	//reset pin = 1

#define LCD_COM (*((volatile uint8_t *) 0x60000000)) // RS = 0
#define LCD_DAT (*((volatile uint8_t *) 0x60010000)) // RS = 1
	
#define lcd_send_cmd(cmd) {LCD_COM = cmd;}
#define lcd_send_data(data) {LCD_DAT = data;}

#define BL_EN  GPIOA->BSRRL = GPIO_BSRR_BS_15		//backlight on
#define BL_DIS GPIOA->BSRRH = GPIO_BSRR_BS_15

#define DISP_W       240
#define DISP_H       400

unsigned int LCD_ORT=1; //LCD ORIENTATION

#define POWCTL                        0xF3
#define VCMCTL                        0xF4
#define SRCCTL                        0xF5
#define SLPOUT                        0x11
#define TEON                          0x35
#define MADCTL                        0x36
#define COLMOD                        0x3A
#define DISCTL                        0xF2
#define IFCTL                         0xF6
#define GATECTL                       0xFD
#define WRDISBV                       0x51
#define WRCABCMB                      0x5E
#define MIECTL1                       0xCA
#define BCMODE                        0xCB
#define MIECTL2                       0xCC
#define MIECTL3                       0xCD
#define RPGAMCTL                      0xF7
#define RNGAMCTL                      0xF8
#define GPGAMCTL                      0xF9
#define GNGAMCTL                      0xFA
#define BPGAMCTL                      0xFB
#define BNGAMCTL                      0xFC
#define CASET                         0x2A
#define PASET                         0x2B
#define RAMWR                         0x2C
#define WRCTRLD                       0x53
#define WRCABC                        0x55
#define DISPON                        0x29
#define DISPOFF                       0x28
#define SLPIN                         0x10
#define RDDIDIF                       0x04                // 4 parameters
#define RDID1                         0xDA                // 2 parameters
#define RDID2                         0xDB                // 2 parameters
#define RDID3                         0xDC                // 2 parameters





struct setting_table
{
  unsigned char command;
  unsigned char parameters;
  unsigned char parameter[15];
  unsigned int wait;
}  
power_on_setting_table[] = {
        {   POWCTL,  7, { 0x80, 0x00, 0x00, 0x0B, 0x33, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },
        {   VCMCTL,  5, { 0x6E, 0x6E, 0x7F, 0x7F, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },
        {   SRCCTL,  5, { 0x12, 0x00, 0x03, 0xF0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },
        {   SLPOUT,  0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 120 },
        {   MADCTL,  1, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {   COLMOD,  1, { 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  30 },        
        {   DISCTL, 11, { 0x14, 0x14, 0x03, 0x03, 0x04, 0x03, 0x04, 0x10, 0x04, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  GATECTL,  2, { 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  WRDISBV,  1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 }, //BRIGHTNESS        
        { WRCABCMB,  1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  MIECTL1,  3, { 0x80, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {   BCMODE,  1, { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  MIECTL2,  3, { 0x20, 0x01, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  MIECTL3,  2, { 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        { RPGAMCTL, 15, { 0x00, 0x23, 0x15, 0x15, 0x1C, 0x19, 0x18, 0x1E, 0x24, 0x25, 0x25, 0x20, 0x10, 0x22, 0x21 },   0 },        
        { RNGAMCTL, 15, { 0x19, 0x00, 0x15, 0x15, 0x1C, 0x1F, 0x1E, 0x24, 0x1E, 0x1F, 0x25, 0x20, 0x10, 0x22, 0x21 },   0 },        
        { GPGAMCTL, 15, { 0x06, 0x23, 0x14, 0x14, 0x1D, 0x1A, 0x19, 0x1F, 0x24, 0x26, 0x30, 0x1E, 0x1E, 0x22, 0x21 },   0 },        
        { GNGAMCTL, 15, { 0x19, 0x06, 0x14, 0x14, 0x1D, 0x20, 0x1F, 0x25, 0x1E, 0x20, 0x30, 0x1E, 0x1E, 0x22, 0x21 },   0 },        
        { BPGAMCTL, 15, { 0x2C, 0x23, 0x20, 0x20, 0x23, 0x2F, 0x30, 0x39, 0x09, 0x09, 0x18, 0x13, 0x13, 0x22, 0x21 },   0 },        
        { BNGAMCTL, 15, { 0x19, 0x2C, 0x20, 0x20, 0x23, 0x35, 0x36, 0x3F, 0x03, 0x03, 0x18, 0x13, 0x13, 0x22, 0x21 },   0 },        
        {    CASET,  4, { 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {    PASET,  4, { 0x00, 0x00, 0x01, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {    RAMWR,  0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {  WRCTRLD,  1, { 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {   WRCABC,  1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   0 },        
        {   DISPON,  0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  50 },        
};


volatile void wait(unsigned long i)
{
        while(i--);
}

void lcd_init(void)
{   
	LCD_RES_L; 					// HW Reset
	wait(120000);
	LCD_RES_H;
	lcd_send_cmd(0x01);        // SW Reset
    lcd_send_cmd(0x11);
    lcd_send_cmd(0x29);
}

u8 lcd_read_data(void)
{	volatile u8 temp;
	temp =  *(__IO uint8_t*) (0x60010000);;
	return temp;
};
void lcd_setting_table_write(struct setting_table *table)
{
    unsigned long i;
        lcd_send_cmd(table->command);
    if ((table->parameters) > 0)
    {
        for ( i=0; i<(table->parameters); i++)
        {
             lcd_send_data(table->parameter[i]);
        }
    }
    if ((table->wait) > 0) wait(table->wait);
}

void lcd_power_on(unsigned char LCD_ORT)
{
    unsigned long i;
	  //LCD_RD_H;
	for (i=0; i<(int)(sizeof(power_on_setting_table)/sizeof(struct setting_table)) ; i++)
    {
         lcd_setting_table_write(&power_on_setting_table[i]);
    };
    if (LCD_ORT) 
    {
      lcd_send_cmd(0x36);
      lcd_send_data(0x2C);
    }
    else
    {
      lcd_send_cmd(0x36);
      lcd_send_data(0x28);
    };
}
#endif
