#ifndef __LCD_H
#define __LCD_H


#include "Common.h"


//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供學習使用，未經作者許可，不得用於其它任何用途
//ALIENTEK戰艦STM32開發板
//2.4寸/2.8寸/3.5寸/4.3寸 TFT液晶驅動	  
//支持驅動IC型號包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/
//                  SPFD5408/SSD1289/1505/B505/C505/NT35310/NT35510等
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//修改日期:2014/7/10
//版本：V2.6
//版權所有，盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//V1.2修改說明
//支持了SPFD5408的驅動,另外把液晶ID直接打印成HEX格式.方便查看LCD驅動IC.
//V1.3
//加入了快速IO的支持
//修改了背光控制的極性（適用於V1.8及以後的開發板版本）
//對於1.8版本之前(不包括1.8)的液晶模塊,請修改LCD_Init函數的LCD_LED=1;為LCD_LED=1;
//V1.4
//修改了LCD_ShowChar函數，使用畫點功能畫字符。
//加入了橫豎屏顯示的支持
//V1.5 20110730
//1,修改了B505液晶讀顏色有誤的bug.
//2,修改了快速IO及橫豎屏的設置方式.
//V1.6 20111116
//1,加入對LGDP4535液晶的驅動支持
//V1.7 20120713
//1,增加LCD_RD_DATA函數
//2,增加對ILI9341的支持
//3,增加ILI9325的獨立驅動代碼
//4,增加LCD_Scan_Dir函數(慎重使用)
//6,另外修改了部分原來的函數,以適應9341的操作
//V1.8 20120905
//1,加入LCD重要參數設置結構體lcddev
//2,加入LCD_Display_Dir函數,支持在線橫豎屏切換
//V1.9 20120911
//1,新增RM68042驅動（ID:6804），但是6804不支持橫屏顯示！！原因：改變掃描方式，
//導致6804坐標設置失效，試過很多方法都不行，暫時無解。
//V2.0 20120924
//在不硬件覆位的情況下,ILI9341的ID讀取會被誤讀成9300,修改LCD_Init,將無法識別
//的情況（讀到ID為9300/非法ID）,強制指定驅動IC為ILI9341，執行9341的初始化。
//V2.1 20120930
//修正ILI9325讀顏色的bug。
//V2.2 20121007
//修正LCD_Scan_Dir的bug。
//V2.3 20130120
//新增6804支持橫屏顯示
//V2.4 20131120
//1,新增NT35310（ID:5310）驅動器的支持
//2,新增LCD_Set_Window函數,用於設置窗口,對快速填充,比較有用,但是該函數在橫屏時,不支持6804.
//V2.5 20140211
//1,新增NT35510（ID:5510）驅動器的支持
//V2.6 20140710
//1,修正LCD_Scan_Dir橫屏時設置的掃描方式顯示不全的bug.
//////////////////////////////////////////////////////////////////////////////////



//LCD重要參數集
//typedef struct  
//{
//    __IO uint16_t    width;         //LCD 寬度
//    __IO uint16_t    height;        //LCD 高度
//    __IO uint16_t    id;            //LCD ID
//    __IO uint8_t     dir;           //橫屏還是豎屏控制：0，豎屏；1，橫屏。
//    __IO uint16_t    wramcmd;       //開始寫gram指令
//    __IO uint16_t    setxcmd;       //設置x坐標指令
//    __IO uint16_t    setycmd;       //設置y坐標指令
//}_lcd_dev;


////LCD參數
//extern _lcd_dev lcddev;   //管理LCD重要參數

////LCD的畫筆顏色和背景色
//extern uint16_t  POINT_COLOR;//默認紅色
//extern uint16_t  BACK_COLOR; //背景顏色.默認為白色

typedef struct __Display_HandleTypeDef{
    void(* Reset)(uint16_t Times);
    void(* BackLight)(uint16_t Duty);       // Duty OFF 0x0000, ON 0xFFFF.

    void(* SelectReg)(uint16_t Register);
    void(* WriteData)(uint16_t Value);
    void(* WriteData8)(uint8_t Value);

    uint16_t(* ReadData)(void);

    void(* WriteRegister)(uint16_t Register, uint16_t Value); 

    //uint16_t(* ReadData)(void);
    //uint16_t(* ReadData8)(void);

    void(* DataReverse)(FunctionalState State);

    __IO uint32_t   State;          //

    __IO uint32_t   HWIF    :1;     // Haedware Interface 0:Parallel, 1:Serial 
    __IO uint32_t   DataRevers :1;  // Data Reverse : 0 Enable, 1 Disable.
    __IO uint32_t   Direct  :1;     // 橫屏還是豎屏控制：0，豎屏；1，橫屏。
    __IO uint32_t   __Reserved:29;  // Reserved bit
    
    __IO uint16_t   ID;             // LCD ID
    __IO uint16_t   Width;          // LCD 寬度
    __IO uint16_t   Height;         // LCD 高度
    __IO uint16_t   SetXcmd;        // 設置x坐標指令
    __IO uint16_t   SetYcmd;        // 設置y坐標指令
    __IO uint16_t   GRAMcmd;        // 開始寫GRAM指令
    __IO uint16_t   PointColor;
    __IO uint16_t   BackColor;
}Display_HandleTypeDef;



extern uint16_t GrayBar_1[];


////////////////////////////////////////////////////////////////////
//-----------------LCD端口定義---------------- 
#define LCD_LED PCout(10)               //LCD背光 

#define __LCD_BackLight_On()    GPIOE->SC.B[1] = PX_SC_SET8_mask_b1
#define __LCD_BackLight_Off()   GPIOE->SC.B[3] = PX_SC_CLR8_mask_b3

#define __LCD_Reset_ENABLE()    GPIOB->SC.B[1] = PX_SC_SET4_mask_b1
#define __LCD_Reset_DISABLE()   GPIOB->SC.B[3] = PX_SC_CLR4_mask_b3

#if !defined(MG0404)
  #define __LCD_BACKLIGHT_ON()    GPIOE->SC.B[1] = PX_SC_SET9_mask_b1
  #define __LCD_BACKLIGHT_OFF()   GPIOE->SC.B[3] = PX_SC_CLR9_mask_b3
#endif

#define __LCD_CS_SET()                                                      //片選端口
#define __LCD_CS_CLR()                                                      //片選端口

#define __LCD_RS_SET()    GPIOC->SC.W = PX_SC_SET7_mask_w                   //數據/命令
#define __LCD_RS_CLR()    GPIOC->SC.W = PX_SC_CLR7_mask_w                   //數據/命令

#define __LCD_WR_SET()                                                      //寫數據
#define __LCD_WR_CLR()                                                      //寫數據

#define __LCD_RD_SET()                                                      //讀數據
#define __LCD_RD_CLR()                                                      //讀數據

//PB0~15,作為數據線
#define __DATAOUT(x) *(volatile uint16_t *)0x60000000 = (x)                  //數據輸出
#define __DATAIN()   *(volatile uint16_t *)0x60000000                        //數據輸入

//-------------------------------------
#define __I80_LCD_RESET_ENABLE()    GPIOB->SC.B[2] = PX_SC_CLR4_mask_b2
#define __I80_LCD_RESET_DISABLE()   GPIOB->SC.B[0] = PX_SC_SET4_mask_b0

#if defined(MG0404)
  #define __I80_LCD_BACKLIGHT_ON()    GPIOE->SC.B[1] = PX_SC_SET8_mask_b1
  #define __I80_LCD_BACKLIGHT_OFF()   GPIOE->SC.B[3] = PX_SC_CLR8_mask_b3
#else
  #define __I80_LCD_BACKLIGHT_ON()    GPIOE->SC.B[1] = PX_SC_SET9_mask_b1
  #define __I80_LCD_BACKLIGHT_OFF()   GPIOE->SC.B[3] = PX_SC_CLR9_mask_b3
#endif

#define __I80_LCD_CS_SET()                                                  //片選端口
#define __I80_LCD_CS_CLR()                                                  //片選端口

#define __I80_LCD_RS_SET()    GPIOC->SC.W = PX_SC_SET7_mask_w               //數據/命令
#define __I80_LCD_RS_CLR()    GPIOC->SC.W = PX_SC_CLR7_mask_w               //數據/命令

#define __I80_LCD_WR_SET()                                                  //寫數據
#define __I80_LCD_WR_CLR()                                                  //寫數據

#define __I80_LCD_RD_SET()                                                  //讀數據
#define __I80_LCD_RD_CLR()                                                  //讀數據

//PB0~15,作為數據線
#define __I80_LCD_DATAOUT(x) *(uint16_t *)0x60000000 = (x)                  //數據輸出
#define __I80_LCD_DATAIN()   *(uint16_t *)0x60000000                        //數據輸入

//-------------------------------------
#define __SPI_LCD_RESET_ENABLE()    GPIOB->SC.B[2] = PX_SC_CLR4_mask_b2
#define __SPI_LCD_RESET_DISABLE()   GPIOB->SC.B[0] = PX_SC_SET4_mask_b0

#define __SPI_LCD_BACKLIGHT_ON()    GPIOE->SC.B[1] = PX_SC_SET9_mask_b1
#define __SPI_LCD_BACKLIGHT_OFF()   GPIOE->SC.B[3] = PX_SC_CLR9_mask_b3

#define __SPI_LCD_CS_SET()                                                  //片選端口
#define __SPI_LCD_CS_CLR()                                                  //片選端口

#define __SPI_LCD_RS_DAT()          GPIOC->SC.W = PX_SC_SET7_mask_w     
#define __SPI_LCD_RS_CMD()          GPIOC->SC.W = PX_SC_CLR7_mask_w     

#define __SPI_LCD_WR_SET()                                                  //寫數據
#define __SPI_LCD_WR_CLR()                                                  //寫數據

#define __SPI_LCD_RD_SET()                                                  //讀數據
#define __SPI_LCD_RD_CLR()                                                  //讀數據

//////////////////////////////////////////////////////////////////////
//掃描方向定義
#define L2R_U2D  0 //從左到右,從上到下
#define L2R_D2U  1 //從左到右,從下到上
#define R2L_U2D  2 //從右到左,從上到下
#define R2L_D2U  3 //從右到左,從下到上

#define U2D_L2R  4 //從上到下,從左到右
#define U2D_R2L  5 //從上到下,從右到左
#define D2U_L2R  6 //從下到上,從左到右
#define D2U_R2L  7 //從下到上,從右到左

#define DFT_SCAN_DIR  L2R_U2D  //默認的掃描方向

//掃描方向定義
#define L2R_U2D  0 //從左到右,從上到下
#define L2R_D2U  1 //從左到右,從下到上
#define R2L_U2D  2 //從右到左,從上到下
#define R2L_D2U  3 //從右到左,從下到上

#define U2D_L2R  4 //從上到下,從左到右
#define U2D_R2L  5 //從上到下,從右到左
#define D2U_L2R  6 //從下到上,從左到右
#define D2U_R2L  7 //從下到上,從右到左

#define DFT_SCAN_DIR  L2R_U2D  //默認的掃描方向

//畫筆顏色
#define WHITE               0xFFFF
#define BLACK               0x0000

#define BLUE                0x001F  
#define BRED                0XF81F
#define GRED                0XFFE0
#define GBLUE               0X07FF
#define RED                 0xF800
#define MAGENTA             0xF81F
#define YELLOW              0xFFE0
#define GREEN               0x07E0
#define CYAN                0x7FFF
#define BROWN               0XBC40  //棕色
#define BRRED               0XFC07  //棕紅色
#define GRAY                0X8430  //灰色
//GUI顏色

#define DARKBLUE            0X01CF  //深藍色
#define LIGHTBLUE           0X7D7C  //淺藍色
#define GRAYBLUE            0X5458  //灰藍色
//以上三色為PANEL的顏色 
 
#define LIGHTGREEN          0X841F //淺綠色
#define LGRAY               0XC618 //淺灰色(PANNEL),窗體背景色

#define LGRAYBLUE           0XA651 //淺灰藍色(中間層顏色)
#define LBBLUE              0X2B12 //淺棕藍色(選擇條目的反色)

void SPI_LCD_Reset(uint16_t Time);
void SPI_LCD_BackLight(uint16_t Duty);
void SPI_LCD_DataReverse(FunctionalState State);
void SPI_LCD_SelectRegister(uint16_t Register);
void SPI_LCD_WriteRegister(uint16_t Register, uint16_t Value);
uint16_t SPI_LCD_ReadRegister(uint16_t Register);
void SPI_LCD_WriteData(uint16_t Data);
void SPI_LCD_WriteData8(uint8_t Data);
uint16_t SPI_LCD_ReadData(void);

void I80_LCD_Reset(uint16_t Duty);
void I80_LCD_BackLight(uint16_t Duty);
void I80_LCD_DataReverse(FunctionalState State);
void I80_LCD_SelectRegister(uint16_t Register);
void I80_LCD_WriteRegister(uint16_t Register, uint16_t Value);
uint16_t I80_LCD_ReadRegister(uint16_t Register);
void I80_LCD_WriteData(uint16_t Data);
void I80_LCD_WriteData8(uint8_t Data);
uint16_t I80_LCD_ReadData(void);

void LCD_Scan_Dir(Display_HandleTypeDef *DispX, uint8_t dir);                                                                                            //設置屏掃描方向
void LCD_Display_Dir(Display_HandleTypeDef *DispX, uint8_t dir);                                                                                         //設置屏幕顯示方向
void LCD_Init(Display_HandleTypeDef *DISPLAYx);                                                                                                          //初始化
void LCD_Init2(Display_HandleTypeDef *DISPLAYx);                                                                                                         //初始化

void LCD_Set_Window(Display_HandleTypeDef *DispX, uint16_t sx,uint16_t sy, uint16_t width, uint16_t height);                                             //設置窗口

void LCD_DisplayOn(Display_HandleTypeDef *DispX);                                                                                                        //開顯示
void LCD_DisplayOff(Display_HandleTypeDef *DispX);                                                                                                       //關顯示

void LCD_Clear(Display_HandleTypeDef *DispX, uint16_t Color);                                                                                            //清屏
void LCD_Clear2(Display_HandleTypeDef *DispX, uint16_t sx, uint16_t sy, uint16_t width, uint16_t height, uint16_t color);                                
void LCD_SetCursor(Display_HandleTypeDef *DispX, uint16_t Xpos, uint16_t Ypos);                                                                          //設置光標
void LCD_DrawPoint(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint16_t Color);                                                                //畫點
uint16_t LCD_ReadPoint(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y);                                                                            //讀點
void LCD_Fill(Display_HandleTypeDef *DispX, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color);                                         //填充單色
void LCD_Color_Fill(Display_HandleTypeDef *DispX, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, __I uint16_t *color);                              //填充指定顏色

void LCD_Draw_Circle(Display_HandleTypeDef *DispX, uint16_t x0, uint16_t y0, uint8_t r, uint16_t Color);                                                 //畫圓
void LCD_DrawLine(Display_HandleTypeDef *DispX, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);                                     //畫線
void LCD_DrawRectangle(Display_HandleTypeDef *DispX, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);                                //畫矩形
void LCD_ShowChar(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint8_t num, uint8_t size, uint8_t mode, uint16_t Color);                        //顯示一個字符
void LCD_ShowCharX(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint8_t num, uint8_t size, uint16_t Color, uint16_t BackColor);
void LCD_ShowNum(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint16_t Color);                         //顯示一個數字
void LCD_ShowxNum(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint16_t Color);          //顯示 數字
void LCD_ShowString(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Color, uint8_t size, uint8_t *p);    //顯示一個字符串,12/16字體
void LCD_ShowStringX(Display_HandleTypeDef *DispX, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Color, uint16_t BackColor, uint8_t size, __I uint8_t *p);

void LCD_ButtonUp(Display_HandleTypeDef *DispX, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);
void LCD_ButtonDown(Display_HandleTypeDef *DispX, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t Color);

// void LCD_WriteReg(uint16_t LCD_Reg, uint16_t LCD_RegValue);
//uint16_t LCD_ReadReg(uint16_t LCD_Reg);
//void LCD_WriteRAM_Prepare(void);
//void LCD_WriteRAM(uint16_t RGB_Code);

//寫數據函數
//#define LCD_WR_iData LCD_WR_DATA
//#define LCD_WR_iData(data){\
//    __LCD_CS_CLR();\
//    __LCD_RS_SET();\
//    __DATAOUT(data);\
//    __LCD_WR_CLR();\
//    __LCD_WR_SET();\
//    __LCD_CS_SET();\
//} 

//9320/9325 LCD寄存器  
#define R0             0x00
#define R1             0x01
#define R2             0x02
#define R3             0x03
#define R4             0x04
#define R5             0x05
#define R6             0x06
#define R7             0x07
#define R8             0x08
#define R9             0x09
#define R10            0x0A
#define R12            0x0C
#define R13            0x0D
#define R14            0x0E
#define R15            0x0F
#define R16            0x10
#define R17            0x11
#define R18            0x12
#define R19            0x13
#define R20            0x14
#define R21            0x15
#define R22            0x16
#define R23            0x17
#define R24            0x18
#define R25            0x19
#define R26            0x1A
#define R27            0x1B
#define R28            0x1C
#define R29            0x1D
#define R30            0x1E
#define R31            0x1F
#define R32            0x20
#define R33            0x21
#define R34            0x22
#define R36            0x24
#define R37            0x25
#define R40            0x28
#define R41            0x29
#define R43            0x2B
#define R45            0x2D
#define R48            0x30
#define R49            0x31
#define R50            0x32
#define R51            0x33
#define R52            0x34
#define R53            0x35
#define R54            0x36
#define R55            0x37
#define R56            0x38
#define R57            0x39
#define R59            0x3B
#define R60            0x3C
#define R61            0x3D
#define R62            0x3E
#define R63            0x3F
#define R64            0x40
#define R65            0x41
#define R66            0x42
#define R67            0x43
#define R68            0x44
#define R69            0x45
#define R70            0x46
#define R71            0x47
#define R72            0x48
#define R73            0x49
#define R74            0x4A
#define R75            0x4B
#define R76            0x4C
#define R77            0x4D
#define R78            0x4E
#define R79            0x4F
#define R80            0x50
#define R81            0x51
#define R82            0x52
#define R83            0x53
#define R96            0x60
#define R97            0x61
#define R106           0x6A
#define R118           0x76
#define R128           0x80
#define R129           0x81
#define R130           0x82
#define R131           0x83
#define R132           0x84
#define R133           0x85
#define R134           0x86
#define R135           0x87
#define R136           0x88
#define R137           0x89
#define R139           0x8B
#define R140           0x8C
#define R141           0x8D
#define R143           0x8F
#define R144           0x90
#define R145           0x91
#define R146           0x92
#define R147           0x93
#define R148           0x94
#define R149           0x95
#define R150           0x96
#define R151           0x97
#define R152           0x98
#define R153           0x99
#define R154           0x9A
#define R157           0x9D
#define R192           0xC0
#define R193           0xC1
#define R229           0xE5
#endif


