//INT035_Touch_lib_XC32.c


#include "INT035_Touch_lib_XC32.h"




#define DISP_ORIENTATION        0
#define DISP_HOR_RESOLUTION		320
#define DISP_VER_RESOLUTION		240


int cTouched;	//タッチ検出で '1'
short ys_xRaw,ys_yRaw;	// x coordinate,  y coordinate
int touch_delay_Clock = 200000000;   //200MHz

void touch_delay_us(volatile unsigned int usec)        //1usec delay
{
        volatile  int count;

        count = (int)(touch_delay_Clock/20000000)*usec;


        do      //actual survey:  at  200MH (Clock=200000000)
        {       //delay_us(1000):1000.4usec  delay_us(100):100.6usec  delay_us(10):10.5usec  delay_us(1):1.5usec
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

                count--;
        }while(count != 0);


}

void touch_delay_ms(volatile unsigned int msec)        //1msec delay
{
        volatile unsigned int i;         //actual survey: at200MH (Clock=200000000)//delay_ms(1): 1.0006msec   delay_ms(100):100.04msec

        for(i=0; i<msec; i++)
        touch_delay_us(1000);
}


void ys_TouchHardwareInit(void)  //Initialize
{
    InitBitBangedIO();	//Initialize : TP_SCK,TP_SI,TP_SO pin
    TPIRQConfig();	//TP_TIRQ pin Mode set

    //Note: The following configuration is intended for the
    //Displaytech Ltd. INT035TFT, INT043BTFT, INT057ATFT, and INT070ATFT

    //General configuration
    ys_TPWriteCommand(0x01,0x67);  //DOUT bus holder enabled, IRQ pullup,
                                //edge interrupt, 128us edge time
    //Measurement resolution
    ys_TPWriteCommand(0x02,0x00);  //Defaults
    //Measurement averaging
    ys_TPWriteCommand(0x03,0xA0);  //8 samples X and Y
    //ADC Samplint Time
    ys_TPWriteCommand(0x04,0x50);  //32us X, 8us Y
    //Panel timing configuration
    ys_TPWriteCommand(0x05,0x20);  //X,Y 50us
    //Delayed conversion
    ys_TPWriteCommand(0x06,0x20);  //X,Y 50us
    //Touch detect pullup timing
    ys_TPWriteCommand(0x07,0x77);  //Rough 500us, fine 800us
    //Autonomous mode timing
    ys_TPWriteCommand(0x08,0x00);  //Defaults
    //Aperture configuration
    ys_TPWriteCommand(0x09,0x00);  //Defaults (unused)
    //AUX measurement configuration
    ys_TPWriteCommand(0x0A,0x00);  //Defaults (unused)
    //Operating mode configuration
    ys_TPWriteCommand(0x0B,0x04);  //X,Y position averaging
}


//-----------------------------------------------------------------
void ys_TPWriteCommand(unsigned char cmd, unsigned char dat) //command Write
{
    TPCSLow();                          //CS = 0 
    ys_TPWriteByte((cmd<<1)|0x00);      // Set b0 = 0 --> write mode sent 
    ys_TPWriteByte(dat);                //Write the data
    TPCSHigh();                         //CS = 1
}


//------------------------------------------------------------------
void ys_TPWriteByte(unsigned char value) //1 byte write
{
    unsigned char mask = 0x80;       //Writing mask

    while(mask)
    {
        TPSCLLow();         //Trigger the clock
        if(mask & value)    //Write the bit
            TPMOSIHigh();
        else
            TPMOSILow();

		touch_delay_us(10);		//10usec  wait  //Wait for the device to read
        TPSCLHigh();        //Reset the clock

                
		touch_delay_us(10);		//10usec  wait
        mask >>= 1;         //Increment the mask
    }

    TPSCLLow();             //Make sure the clock is low
}

//------------------------------------------------------------------------
unsigned char ys_TPReadByte(void)    //1 byte read
{
    unsigned char mask = 0x80;           //Read mask
    unsigned char value = 0x00;          //Read value

    while(mask)
    {
        TPSCLLow();             //Set the clock low
 
		touch_delay_us(10);			//10usec wait   //Wait for the device to set the bit
        if(TPMISORead())        //Set the value
            value |= mask;
        TPSCLHigh();            //Set the clock high

		touch_delay_us(10);			//10usec wait
        mask >>= 1;             //Increment the mask
    }
    TPSCLLow();                 //Reset the clock

    return value;
}



//------------------------------------------------------------------------
unsigned char ys_TPReadCommand(unsigned char cmd)    //command read
{
    unsigned char dat;                       //Read data

    TPCSLow();                          //CS = 0
    ys_TPWriteByte((cmd<<1)|0x01);      //b0 = 1  --> read mode sent
    dat = ys_TPReadByte();              //Read the data
    TPCSHigh();                         //Reset the CS

    return dat;
}





#define MAX_JUMP (10*4096/DISP_HOR_RESOLUTION) //Noise rejection threshold

//---------------------------------------------------------------------------
short ys_TouchDetectPosition(void)	//touch position detect
{

    unsigned char dat;                                  
                             
    unsigned short x, y;                        //Read x and y values
    static short lastX=0, lastY=0;              //For noise rejection

    dat = ys_TPReadCommand(0x00);               //Read the status

    if(dat & 0x02)                              //Touch present?
    {
        TPCSLow();                              //Command a conversion (x,y)
        ys_TPWriteByte(0xE0);
        TPCSHigh();

		touch_delay_ms(2);
        TPCSLow();                              //Read the positions
        ys_TPWriteByte(0xA5);
        x = ys_TPReadByte()<<8;
        x |= ys_TPReadByte();
        y = ys_TPReadByte()<<8;
        y |= ys_TPReadByte();
        x >>= 4;
        y >>= 4;
        TPCSHigh();

         //Error checking
        if((lastX != -1 && lastY != -1) &&
           (abs((short)x - lastX) > MAX_JUMP ||
           abs((4096 - (short)y) - lastY) > MAX_JUMP))
       //abs((short)y - lastY) > MAX_JUMP))
        {
            ys_xRaw = -1;
            ys_yRaw = -1;
        }
        else
        {
            ys_xRaw = (short)x;
            ys_yRaw = (short)y;
            ys_yRaw = 4096 - ys_yRaw;
        }
        
        
    }
    else
    {
        ys_xRaw = -1;
        ys_yRaw = -1;
    }

    lastX = ys_xRaw;
    lastY = ys_yRaw;

    return 0;




}


//---------------------------------------------------------------------------
short ys_TouchGetX(void)
{
    if(ys_xRaw == -1)              //-1 indicates no touch present
        return -1;
    else                        //Scale the xRaw value from 12-bits
#if (DISP_ORIENTATION == 0)
      return (short)(DISP_HOR_RESOLUTION*ys_xRaw/4096);
#elif (DISP_ORIENTATION == 90)
        return (short)(DISP_VER_RESOLUTION*ys_xRaw/4096);
#endif
}

//------------------------------------------------------------------------------
short ys_TouchGetRawX(void)
{
    return (short)ys_xRaw;
}


//-------------------------------------------------------------------------------
short ys_TouchGetY(void)
{
    if(ys_yRaw == -1)              //-1 indicates no touch
        return -1;
    else
#if (DISP_ORIENTATION == 0)     //Scale the raw value from 12-bits
#ifdef TOUCH_INVERT_Y           //Invert the Y value
        return (shortT)(DISP_VER_RESOLUTION*(4096-ys_yRaw)/4096);
#else
        return (short)(DISP_VER_RESOLUTION*(ys_yRaw)/4096);
#endif
#elif (DISP_ORIENTATION == 90)
        return (short)(DISP_HOR_RESOLUTION*(4096-ys_yRaw)/4096);
#endif
}



//------------------------------------------------
short ys_TouchGetRawY(void)
{
    return (short)ys_yRaw;
}



int INT035_TouchDetect(void)    //タッチがINT035の液晶画面上に発生した場合
{
    int adcX,adcY;  //現在座標x,y
 
    ys_TouchDetectPosition();	//Position detedted
    adcX = ys_TouchGetX();
    adcY = ys_TouchGetY(); 
    
    if((adcX == -1) || (adcY == -1))cTouched = 0;   //タッチがINT035の液晶画面上に発生した場合
    else cTouched = 1;
    
    return cTouched;
}  

