/*****************************************************************************
* Program for writing to Newhaven Display NHD-2.8-240320AF-CSXP-FCTP with ST7789S controller.
* This code is written for the Arduino Due (AT91SAM3X8E) in 8080 Mode 8-Bit Parallel Interface
* 
* Newhaven Display invests time and resources providing this open source code,
* Please support Newhaven Display by purchasing products from Newhaven Display!
*
* Copyright: M Arce (c) 2020, Newhaven Display International
*
* This code is provided as an example only and without any warranty by Newhaven Display. 
* Newhaven Display accepts no responsibility for any issues resulting from its use. 
* The developer of the final application incorporating any parts of this 
* sample code is responsible for ensuring its safe and correct operation
* and for any consequences resulting from its use.
* See the GNU General Public License for more details. 
*****************************************************************************/
/**************************************************************************** 
 *  This program has four options for the user to interact with.The user can 
 *  select a "previous", "next", "home" button and sketch.
------------------------------------------------------------------------------
Arduino        TFT Display                                                   |
------------------------------------------------------------------------------
  GND           1   GND   - Ground                                           |                                                     
                2-6 NC    - No Connect                                       |
  2.8V          7   VDD   - Supply Voltage for LCD (2.8v)                    |
  2.8V          8   I0VDD - Supply Voltage for Logic (Tie to Vdd)            |
                9   NC    - No Connect                                       |
  GND           10  CS    - Active LOW Chip Select signal(can tie to GND)    |
  10            11  RS    - D/C Data =1 , Command =0                         |
  11            12  WR    - Active LOW Write signal                          |
  12            13  RD    - Active LOW Read signal                           |                                         
                14-21     - No Connect                                       |                   
  2             22  DB0                                                      |                                                                  
  3             23  DB1                                                      |                                                                  
  4             24  DB2                                                      |                                                                
  5             25  DB3                                                      |                                                                  
  6             26  DB4                                                      |                                                                  
  7             27  DB5                                                      |                                                                  
  8             28  DB6                                                      |                                                                  
  9             29  DB7                                                      |                                                                                                                              
  3.3V          30 RES                                                       |
  3.3V          31 IM0 = 1 HIGH for 8080-II                                  |
                32 No Connect                                                |
  GND           33 Ground                                                    |
  GND           34 LED-K1 Backlight Cathode                                  |
  GND           35 LED-K2 Backlight Cathode                                  |
  GND           36 LED-K3 Backlight Cathode                                  |
  GND           37 LED-K4 Backlight Cathode                                  |
  3.1V          38 LED-A  Backlight Anode(100mA@ 3.1V)                       |
  GND           39 Ground                                                    |
                40 No Connect                                                |
------------------------------------------------------------------------------


Capacitive Touch Panel:                                                      
------------------------------------------------------------------------------
Arduino         TFT Touch Panel                                              |
------------------------------------------------------------------------------
3.3 V            1 Vdd    - Suppply Voltage for Logic (3.3v)                 |
GND              2 Vss    - Ground                                           |
21               3 SCL    - Serial I2C Clock(Requires pull-up resistor)      |
20               4 SDA    - Serial I2C Data (Requires pull-up resistor)      |
13               5 /INT   - Interrupt signal from touch panel module to host | 
3.3 V            6 /RESET - Active LOW Reset signal                          |
------------------------------------------------------------------------------

 
SD Card Reader:                                                             
------------------------------------------------------------------------------
Arduino         SD Card Reader                                               |
------------------------------------------------------------------------------
GND              GND                                                         |
3.3v             3.3V                                                        |
22               CS                                                          |
51               MOSI                                                        |
52               SCK                                                         |
51               MISO                                                        |
GND              GND                                                         |
------------------------------------------------------------------------------ 
******************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

/*TFT*/
#define RS 10      /*RS signal connected to Arduino digital pin 10*/
#define WR 11      /*WR signal connected to Arduino digital pin 11*/
#define RD 12      /*RD signal connected to Arduino digital pin 12*/

/*CTP*/
#define INT 13     /* INT signal is connected to digital pin 15 on the Arduino DUE*/
const char slave = 0x38;/*slave address of 0x70 shifted over 1 bit*/
long int  read1, read2, read3, read4;
long int x_c,y_c;  

/*SD Card*/
#define MOSI 51    /* SPI-4*/
#define MISO 50    /* SPI-1*/
#define SCK 52     /* SPI-3*/
const int ChipSelect = 22;
int image_value=0;                      
File myFile;

void setup(){          /*Initialization*/
  Wire.begin();        /*Begin Arduino I2C library*/
  Init_Ports();        /*Initialize Ports*/
  Init_CTP();          /*Initialize CTP */
  Init_LCD();          /*Initialize TFT*/
  Init_SD_Card();      /*Initialize the SC Card*/
  SD_Card_Image(5);    /*Show home screen*/
}
void loop(){           /*Update screen based on read input*/
  while((digitalRead(INT)) == LOW){ /*Detect a touch from CT*/
      Read_CTP_XY();                /*read x and y values from CTP*/  
      Update_TFT(x_c,y_c);          /*Update screen based on input*/    
    }    
}
void comm_out(unsigned char c){   /*Send Command*/      
  digitalWrite(RS, LOW);
  for(int i=7;i>=0;i--){
      if(bitRead(c,i)==0 ){
        digitalWrite(i+2,LOW);
      }
      else {
        digitalWrite(i+2,HIGH);
      } 
  } 
  digitalWrite(WR, LOW);
  digitalWrite(WR, HIGH);
}
void data_out(unsigned char d){   /*Send Data*/      
  digitalWrite(RS, HIGH);
  for(int i=7;i>=0;i--){
      if(bitRead(d,i)==0 ){
        digitalWrite(i+2,LOW);
      }
      else {
        digitalWrite(i+2,HIGH);
      } 
  } 
  digitalWrite(WR, LOW);
  digitalWrite(WR, HIGH);
}
void Init_Ports(){     /*Initialize Ports*/                     
  pinMode(INT,INPUT);  /*Arduino Digital Pin 13, Interrupt CTP pin*/
  pinMode(RS,OUTPUT);  /*Arduino Digital Pin 10*/
  pinMode(WR,OUTPUT);  /*Arduino Digital Pin 11*/
  pinMode(RD,OUTPUT);  /*Arduino Digital Pin 12*/
  pinMode(2, OUTPUT);  /*TFT DB0*/
  pinMode(3, OUTPUT);  /*TFT DB1*/
  pinMode(4, OUTPUT);  /*TFT DB2*/
  pinMode(5, OUTPUT);  /*TFT DB3*/
  pinMode(6, OUTPUT);  /*TFT DB4*/
  pinMode(7, OUTPUT);  /*TFT DB5*/
  pinMode(8, OUTPUT);  /*TFT DB6*/
  pinMode(9, OUTPUT);  /*TFT DB7*/
}    
void Init_CTP(){       /*Initialize CTP */                    
  digitalWrite(INT, HIGH);
  delay(100);
} 
void Init_LCD(){       /*Initialize TFT*/                    
  digitalWrite(RD, HIGH);
  digitalWrite(WR, LOW);
  
  comm_out(0x28);  /*display off*/
  comm_out(0x11);  /*exit SLEEP mode*/
  delay(100);
  
  comm_out(0x36);  /*MADCTL: memory data access control*/
  data_out(0x10);  /*refresh from bottom to top. */
  
  comm_out(0x3A);  /*COLMOD: Interface Pixel format  *** 65K-colors in 16bit/pixel(5-6-5)...*/ 
  data_out(0x55);  /*format when using 16-bit interface to allow 1-byte per pixel*/
  
  comm_out(0xB2);  /*PORCTRK: Porch setting*/
  data_out(0x0C);
  data_out(0x0C);
  data_out(0x00);
  data_out(0x33);
  data_out(0x33);
  
  comm_out(0xB7);  /*GCTRL: Gate Control*/
  data_out(0x35);
  
  comm_out(0xBB);  /*VCOMS: VCOM setting*/
  data_out(0x2B);
 
  comm_out(0xC0);  /*LCMCTRL: LCM Control*/
  data_out(0x2C);
  
  comm_out(0xC2);  /*VDVVRHEN: VDV and VRH Command Enable*/
  data_out(0x01);
  data_out(0xFF);
  
  comm_out(0xC3);  /*VRHS: VRH Set*/
  data_out(0x11);
  
  comm_out(0xC4);  /*VDVS: VDV Set*/
  data_out(0x20);
  
  comm_out(0xC6);  /*FRCTRL2: Frame Rate control in normal mode*/
  data_out(0x0F);
  
  comm_out(0xD0);  /*PWCTRL1: Power Control 1*/
  data_out(0xA4);
  data_out(0xA1);
  
  comm_out(0xE0);  /*PVGAMCTRL: Positive Voltage Gamma control  */
  data_out(0xD0);
  data_out(0x00);
  data_out(0x05);
  data_out(0x0E);
  data_out(0x15);
  data_out(0x0D);
  data_out(0x37);
  data_out(0x43);
  data_out(0x47);
  data_out(0x09);
  data_out(0x15);
  data_out(0x12);
  data_out(0x16);
  data_out(0x19);
  
  comm_out(0xE1);  /*NVGAMCTRL: Negative Voltage Gamma control  */
  data_out(0xD0);
  data_out(0x00);
  data_out(0x05);
  data_out(0x0D);
  data_out(0x0C);
  data_out(0x06);
  data_out(0x2D);
  data_out(0x44);
  data_out(0x40);
  data_out(0x0E);
  data_out(0x1C);
  data_out(0x18);
  data_out(0x16);
  data_out(0x19);
  
  comm_out(0x2A);  /*X address set*/
  data_out(0x00);
  data_out(0x00);
  data_out(0x00);
  data_out(0xEF);

  comm_out(0x2B);  /*Y address set*/
  data_out(0x00);
  data_out(0x00);
  data_out(0x01);
  data_out(0x3F);
  delay(10);
  comm_out(0x21); 
  comm_out(0x29);  /*display ON   0 high  1*/
  delay(10);  
}
void Init_SD_Card(){   /*Initialize the SC Card*/                    
  SD.begin(ChipSelect);
}
void SD_Card_Image(unsigned char image){       /*The images used are in a textfile*/
  unsigned char dummy;
  unsigned int incr =0;
  switch (image){
    case 1: 
      image_value=1;
      myFile = SD.open("i1.txt");
      break;
    case 2:
      image_value=2;
      myFile =SD.open("i2.txt");
      break;
    case 3:
      image_value=3;
      myFile =SD.open("i3.txt");
      break;      
    case 4:
      image_value=4;
      myFile =SD.open("sketch.txt");
      break;  
    case 5: 
      image_value=5;
      myFile =SD.open("menu.txt");
      break;                           
  }
comm_out(0x2A);  /*X address set*/
 data_out(0x00);
 data_out(0x00);
 data_out(0x00);
 data_out(0xEF);
comm_out(0x2B);  /*Y address set*/
 data_out(0x00);
 data_out(0x00);
 data_out(0x01);
 data_out(0x3F);      
comm_out(0x2C);  /*command to begin writing to frame memory     */
 byte  data_in1,data_in2,data_in,data_out_value;
 uint8_t data_send;
 char data_conv[1]={0};
 int i;  
 int track ;
while (myFile.available()){ /*convert the input char data to integers*/
      dummy = myFile.read(); 
      dummy = myFile.read(); 
      data_in1 = myFile.read(); 
      data_in2 = myFile.read(); 
      data_in=data_in1;
      if(data_in >=48 && data_in<=57){    /*if values are in range of 0-9 values*/
          data_in1 = data_in-48;
          track=1;
        }
        if(data_in <=102 && data_in>=97){ /*if values are in range of a-f*/
          data_in1 = data_in - 87; 
          track=1;
        }
         if( data_in ==32/*Space*/ || data_in==44 /*comma*/ || data_in == 120 /*x*/){
          dummy =data_in;
          track=0;
          data_in1 =0;
          data_in2 =0;
         }      
      data_in=data_in2;
      if(data_in >=48 && data_in<=57){   /*if values are in range of 0-9 values*/
          data_in2 = data_in-48;
          track=1;
        }
        if(data_in <=102 && data_in>=97){/*if values are in range of a-f*/
          data_in2 = data_in - 87; 
          track=1;
        }
         if( data_in ==32/*Space*/ || data_in==44 /*comma*/ || data_in == 120 /*x*/){/*skip dummy data*/
          dummy =data_in;
          track=0;
          data_in1 =0;
          data_in2 =0;
         }              
      dummy = myFile.read(); 
      dummy = myFile.read();  
           
      data_out_value = data_in1<<4 | data_in2;  
      data_out(data_out_value);
    }
    myFile.close();   
}
void Read_CTP_XY(){ /*Function that reads 5 registers in a row, starting from specified register*/
  Wire.beginTransmission(0x38);
  Wire.write(0x03);
  Wire.endTransmission();
  Wire.requestFrom(0x38, 4);
  while(Wire.available())
  {
    read1 = Wire.read();
    read2 = Wire.read();
    read3 = Wire.read();
    read4 = Wire.read();    
    x_c= read2;
    if(read3==0){
       y_c = read4; 
    }
    else
       y_c = read4+256;
  }
}
void Update_TFT (long int px, long int py){    /*This function updates the TFT screen*/
/*Sketchpad screen, touch screen boundries for "next","back", & "home" buttons,
  if no button is pressed proceed to draw*/
   if((px<40) && (py<25) &&image_value==4){/*clear button pressed*/
    SD_Card_Image(4);  /*show image for sketching*/  
   } 
   else if( (px>214) && (py>75) && (py<106) && (image_value==4)){ /*back button pressed*/
     SD_Card_Image(image_value-1);/*if back butotn is pressed,go to previous image*/
   }
   else if( (px>214) && (py>117) && (py<148) && (image_value==4)){/*home button pressed*/
    SD_Card_Image(5);/*if home button is pressed, go home*/
   }
   else if( (px>214) && (py>166) && (py<194) && (image_value==4)){/*next button pressed*/
     SD_Card_Image(image_value+1);/*if the next button is pressed, go to get image(in this case "home")*/
   }
   else if(image_value==4){  /*if none of the buttons are selected then Draw*/
     Pixel_Sampling(px,py);  /*draw pixel*/
   }
   
/*Menu screen, touch screen boundries for each selection*/
   else if( (px>22)  && (py>56)  && (px<105)  && (py<176) && (image_value==5)){
     SD_Card_Image(1);
   }
   else if( (px>131) && (py>56)  && (px<211)  && (py<176) && (image_value==5)){
     SD_Card_Image(2);
   }
   else if( (px>7)   && (py>210) && (px<107)  && (py<306) && (image_value==5)){
     SD_Card_Image(3);
   }
   else if( (px>123) && (py>210) && (px<233)  && (py<306) && (image_value==5)){
     SD_Card_Image(4);
   }

/*If in the menu screen, the "next","back", & "home" button will not work*/
   else if( (px>214) && (py>75)  && (py<106) && (image_value<4)){
     SD_Card_Image(image_value-1); /*go to previous image top arrow*/
   }
   else if( (px>214) && (py>117) && (py<148) && (image_value<4)){
    SD_Card_Image(5);              /*go home*/
   }
   else if( (px>214) && (py>166) && (py<194) && (image_value<4)){
     SD_Card_Image(image_value+1); /*go to next image bottom arrow*/
   }
}
void Pixel_Sampling(long int px, long int py){ /*Turn pixel at location px,py to black*/
                            /*Set the column and row for the pixel that will be drawn*/
    comm_out(0x2a);         /*Set x column */
    data_out(0x00);
    data_out(px);
    data_out(0x00);
    data_out(0xef);
    
    comm_out(0x2b);         /*Set y row*/
    if(py>255)
        data_out(0x01); 
    else
      data_out(0x00);
    data_out(py);
    data_out(0x01);
    data_out(0x3f);
    comm_out(0x2C);         /*command to begin writing to frame memory*/
       
    data_out(0x00);         /*Write Black Pixel to TFT*/
    data_out(0x00);         /*Write Black Pixel to TFT*/
}
