#include "system.h"
#include "i2c.h"
#include "tsc2013.h"

#include "uart.h"

uint16 tsc2013_touch_status;

extern volatile uint16_t g_touch_detected;

extern tsc2013_data_set data_set;

static void tsc2013_i2c_init(void);
static void tsc2013_reset(void);
static void tsc2013_interrupt_init(void);
static void tsc2013_write_config_values(void);

static void tsc2013_i2c_read_multi_byte(uint8 *data, uint8 length);
static void tsc2013_i2c_write_byte(uint8 value);
static void tsc2013_i2c_write_register(uint8 reg_address, uint16 value);

static void swap(uint8_t *high_byte, uint8_t *low_byte);

void tsc2013_init(void)
{
  tsc2013_i2c_init();
   
  tsc2013_reset();
  
  __enable_interrupt();
    
  tsc2013_write_config_values();
 
  //Control Byte ID : 1
  //          C3:C0 : 0 
  //            RM  : 0  (10 Bit)
  //          SWRST : 0
  //            STS : 0
  //tsc2013_i2c_write_byte(0x80);   //Scan X,Y,Z

  //Control Byte ID : 1
  //          C3:C0 : 0 
  //            RM  : 1  (12 Bit)
  //          SWRST : 0
  //            STS : 0  
  tsc2013_i2c_write_byte(0x84);   //Scan X,Y,Z

  tsc2013_interrupt_init();  
}

void tsc2013_i2c_init(void)
{
  i2c0_init();
}

void tsc2013_interrupt_init(void)
{
  P2SEL &= (~TSC_IRQ);
    
  P2IE = TSC_IRQ;                              // P2.7 interrupt enabled
  P2IES |= TSC_IRQ;                            // P2.7 Hi/lo edge
  P2IFG &= ~TSC_IRQ;                           // P2.7 IFG cleared
}

// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void tsc2013_isr(void)
{
  if (P2IFG & TSC_IRQ)  
  {
    g_touch_detected = 1;
    P2IFG &= ~TSC_IRQ;                        // P2.7 IFG cleared
  }
}

void tsc2013_reset(void)
{
  unsigned char i;
  
  P3DIR |= TSC_RST;         // Set TSC_RST to output direction 
  //P3SEL &= (~TSC_RST);   
  
  P3OUT &= ~TSC_RST;        //Set RESET Pin Low
  for (i=0; i < 100; i++);
  
  P3OUT |= TSC_RST;         //Set RESET Pin High after a short delay
}

void tsc2013_read_touch_status(void)
{   
  tsc2013_register reg;
    
  tsc2013_i2c_write_byte(REG_STATUS_RD);
  tsc2013_i2c_read_multi_byte((uint8 *)&reg.value, 2);
  swap(&reg.bytes.high_byte,&reg.bytes.low_byte);  
  
  tsc2013_touch_status = reg.value;
}

void tsc2013_i2c_write_byte(uint8 value)
{
  i2c0_write_byte(value);
}

void tsc2013_i2c_write_register(uint8 reg_address, uint16 value)
{
  i2c0_write_register(reg_address, value);
}

void tsc2013_i2c_read_multi_byte(uint8 *data, uint8 length)
{  
  i2c0_read_multi_byte(data, length);
}

void tsc2013_read_touch_data(void)
{    
  uint8_t i ;
  
  tsc2013_i2c_write_byte(REG_X1_RD);
  
  tsc2013_i2c_read_multi_byte(data_set.buffer, 16);
  
  for (i = 0; i < 8; i++)
  {
     swap(&data_set.buffer[i * 2],&data_set.buffer[i * 2 + 1]);
  }
}

void swap(uint8_t *high_byte, uint8_t *low_byte)
{
  uint8_t temp;
  
  temp = *high_byte;
  *high_byte = *low_byte;
  *low_byte = temp;
}

void tsc2013_write_config_values(void)
{
  tsc2013_register reg;
  uint16_t value;
  
  value = CFR0_PSM_1 |    
              CFR0_STS_0 |   //Normal Operation
              CFR0_RESOLUTION_12_BIT | 
              CFR0_CONVERSION_CLOCK_4MHz | 
              //CFR0_PANEL_VOLTAGE_STABILIZATION_TIME_2 |   //500us
              CFR0_PANEL_VOLTAGE_STABILIZATION_TIME_3 |   //5ms
              CFR0_PRECHARGE_TIME_4 |                     //1.044ms
              CFR0_SENSE_TIME_3 |                         //608us
              CFR0_DTW_DISABLED |
              CFR0_LSM_DISABLED; 
  tsc2013_i2c_write_register(REG_CFR0_WR, value);
  
  //tsc2013_i2c_write_byte(REG_CFR0_RD);
  //tsc2013_i2c_read_multi_byte((uint8 *)&reg.value, 2);
  //swap(&reg.bytes.high_byte,&reg.bytes.low_byte);
   
  value = CFR1_BTD_0;
  tsc2013_i2c_write_register(REG_CFR1_WR, value);
  
  tsc2013_i2c_write_byte(REG_CFR1_RD);
  tsc2013_i2c_read_multi_byte((uint8 *)&reg.value, 2);
  swap(&reg.bytes.high_byte,&reg.bytes.low_byte);

#if (ENABLE_DEBUG_UART) 
  if (reg.value != value)
  {
    uart0_printf("read-%x,expect-%x\n\r",reg.value,value);
  }
#endif
  
  value = CFR2_PINTS_2 |  ///DAV
              //CFR2_M_1 |     //M = 3
              //CFR2_W_0 |     //W = 1
              CFR2_M_3 |     //M
              CFR2_W_2 |     //W
              CFR2_MAVE_X_ENABLED |
              CFR2_MAVE_Y_ENABLED |
              CFR2_MAVE_Z_ENABLED |
              CFR2_MAVE_AUX_DISABLED;
  tsc2013_i2c_write_register(REG_CFR2_WR, value);
  
  tsc2013_i2c_write_byte(REG_CFR2_RD);
  tsc2013_i2c_read_multi_byte((uint8 *)&reg.value, 2);
  swap(&reg.bytes.high_byte,&reg.bytes.low_byte); 

#if (ENABLE_DEBUG_UART)  
  if (reg.value != value)
  {
    uart0_printf("read-%x,expect-%x\n\r",reg.value,value);
  }
#endif
}
