CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Microchip AR1021 Touch screen I2C driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Markdem



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

Microchip AR1021 Touch screen I2C driver
PostPosted: Sat Mar 02, 2013 12:38 am     Reply with quote

Hi all,

Here is a driver for the Microchip AR1021 controller. It will only work in I2C mode and no calibration function has been written. Most of the time the touch screen is glued onto the LCD anyway so I did not waste my time.

If anyone sees anything that can be improved, please yell out.

Driver:
Code:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////      Driver for AR1021                                                                                    ///////////
///////       Usage:                                                                                 ///////////                                                                              
///////             AR1021_GetPos(int16 xpos, int16 ypos)                                                    ///////////
///////               Where xpos and ypos are varibals to store touch data, returns 1 for pen down and 0 for pen up      ///////////
///////               Should only be called on AR1021 interupt                                             ///////////                                           
///////                                                                                          ///////////
///////            AR1021_Send_Command(int cmd)                                                         ///////////
///////               Where cmd is the command to send. Note this should only be used on commands that dont need          ///////////
///////               to send data. If using GET_VERSION, returned data will be in AR1021_data[4].                  ///////////
///////               Will return 0 if successful, 1 if invalid data was recived and 2 if timed out.                  ///////////
///////                                                                                          ///////////
///////            AR1021_Read_Register(int reg)                                                         ///////////
///////               Where reg is register to read.Actual register data will be in AR1021_data[2].                  ///////////
///////               Will return 0 if successful, 1 if invalid data was recived and 2 if timed out.                  ///////////
///////                                                                                          ///////////
///////            AR1021_Set_Register(int reg, int data)                                                   ///////////
///////               Where reg is register to set and data will be data to send.                                 ///////////
///////               Will return 0 if successful, 1 if invalid data was recived and 2 if timed out.                  ///////////
///////                                                                                          ///////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define AR1021_Address                  0x9A
#define AR1021_INT_PIN                  PIN_B1

//AR1021 Commands
#define GET_VERSION                   0x10   
#define ENABLE_TOUCH                   0x12    
#define DISABLE_TOUCH                  0x13    
#define CALIBRATE_MODE                  0x14    
#define REGISTER_READ                    0x20    
#define REGISTER_WRITE                  0x21    
#define REGISTER_START_ADDRESS_REQUEST      0x22    
#define REGISTERS_WRITE_TO_EEPROM         0x23    
#define EEPROM_READ                     0x28    
#define EEPROM_WRITE                  0x29    
#define EEPROM_WRITE_TO_REGISTERS         0x2B

//AR1021 config register offsets
#define TouchThreshold                   0x02
#define SensitivityFilter                0x03
#define SamplingFast                   0x04
#define SamplingSlow                   0x05
#define AccuracyFilterFast                0x06
#define AccuracyFilterSlow                0x07
#define SpeedThreshold                   0x08
#define SleepDelay                      0x0A
#define PenUpDelay                      0x0B
#define TouchMode                      0x0C
#define TouchOptions                   0x0D
#define CalibrationInset                0x0E
#define PenStateReportDelay             0x0F

#define AR1021_TIMEOUT                  100               //how many ms to wait for responce
#define AR1021_RETRY                  5               //how many times to retry sending command

int AR1021_data[8];

int1 AR1021_GetPos(int16 &AR1021_xpos, int16 &AR1021_ypos)
   {
      int x_msb, x_lsb, y_msb, y_lsb, temp;
      int1 pen;

      i2c_start();
         i2c_write(AR1021_Address + 1);                                      //send read address   
         temp = i2c_read(1);    
         x_lsb = i2c_read(1);
         x_msb = i2c_read(1);
         y_lsb = i2c_read(1);
         y_msb = i2c_read(0);
      i2c_stop();   

      AR1021_xpos = make16(x_msb, x_lsb);
      AR1021_ypos = make16(y_msb, y_lsb);

      pen = bit_test(temp, 0);                                          //get pen state bit

      //////////////////////DEBUG//////////////////////////
      //   GLCD_rect(0,20,319,35, YES, BLACK);
      //   sprintf(lcd_data,"X=%lu Y=%lu PEN=%u",touch_xpos, touch_ypos, pen);
      //   glcd_text(0,20,lcd_data,GREEN,BLACK);
      ////////////////////////////////////////////////////////////

      return pen;
   }

int AR1021_XFER(int send_lenght)
   {
      int header, length, i;
      int16 timeout;
      int exit_code, retry_count = 0;
      int1 done = 0;
      int RX_buffer[8];

      while(!done)
         {
            timeout = 0;

              i2c_start();
               i2c_write(AR1021_Address);                                     //send write address
               i2c_write(0x00);
               i2c_write(0x55);                                          //header
               i2c_write(send_lenght);                                     //message lenght

            for(i=0;i<send_lenght;i++)
               {
                     i2c_write(AR1021_data[i]);                                //command
               }      
   
            delay_us(60);                                             //delay from datasheet
               i2c_stop();
      
            while(!input(AR1021_INT_PIN))                                 //wait untill AR1021 pulls interupt pin high
               {
                  delay_us(10);
                  timeout++;
      
                  if(timeout > AR1021_TIMEOUT)
                     {
                        break;
                     }
               }         

            if(timeout < AR1021_TIMEOUT)
               {
                  i2c_start();
                     i2c_write(AR1021_Address + 1);                          //send read address   
                     header = i2c_read(1);                                  //always should be 0x55   (header)      
                     length = i2c_read(1);                                  //data length
               
                  for(i=0;i<length-1;i++)                                 //we need to send a NACK on the last read.
                     {
                        RX_buffer[i] = i2c_read(1);                      //returned data, read into diffrent buffer incase we need to retry.
                     }

                  RX_buffer[i] = i2c_read(0);                               //last returned data byte
                  i2c_stop();

                  if(RX_buffer[0] == 0x00)                                 //check to see if the status byte is 0
                     {
                        for(i=0;i<length;i++)                           //if data is OK, copy into buffer
                           {
                              AR1021_data[i] = RX_buffer[i];
                           }
                        exit_code = 0;                                 //OK
                        done = 1;
                     }
                  else
                     {
                        exit_code = 1;                                 //Invalid return
                        retry_count++;
                        delay_ms(50);                                 //delay before retry
                     }
               }
            else
               {
                  exit_code = 2;                                       //Timeout
                  retry_count++;
                  delay_ms(50);                                       //delay before retry
               }

            if(retry_count >= AR1021_RETRY)                                 //check to see if we have exceded the retry count
               {
                  done = 1;                                          //do not retry
               }   
         }
      return exit_code;
   }


int AR1021_Send_Command(int cmd)
   {
      int ret_data;

      AR1021_data[0] = cmd;                                             //set command to send
      ret_data = AR1021_XFER(1);                                          //send command

      return ret_data;
   }


int AR1021_Read_Register(int reg)
   {
      int reg_address = 0;
      int ret_data;

      AR1021_Send_Command(DISABLE_TOUCH);                                    //disable touch reporting while we send commands
      delay_ms(100);                                                   //delay before sending command

      AR1021_data[0] = 0x22;                                             //get start address
      ret_data = AR1021_XFER(1);                                          //send command

      reg_address = AR1021_data[2] + reg;                                    //work out the address of the register we want

      AR1021_data[0] = 0x20;                                             //read command
      AR1021_data[1] = 0x00;                                             //register high address, allways 0x00   
      AR1021_data[2] = reg_address;                                       //register low address
      AR1021_data[3] = 0x01;                                             //number of register to read, always 1 here
      AR1021_XFER(4);                                                   //send command

      AR1021_Send_Command(ENABLE_TOUCH);                                    //re-enable touch reporting

      return ret_data;
   }



int AR1021_Set_Register(int reg, int data)
   {
      int reg_address = 0;
      int ret_data;

      AR1021_Send_Command(DISABLE_TOUCH);                                    //disable touch reporting while we send commands

      AR1021_data[0] = 0x22;                                             //get start address
      AR1021_XFER(1);                                                   //send command
   
      reg_address = AR1021_data[2] + reg;                                    //work out the address of the register we want

      AR1021_data[0] = 0x21;                                             //write command
      AR1021_data[1] = 0x00;                                             //register high address, allways 0x00   
      AR1021_data[2] = reg_address;                                       //register low address
      AR1021_data[3] = 0x01;                                             //number of register to write too, always 1 here
      AR1021_data[4] = data;                                             //data to set register   
      reg_address = AR1021_XFER(5);                                       //send command

      AR1021_Send_Command(ENABLE_TOUCH);                                    //re-enable touch reporting

      return ret_data;
   }


Example:
Code:

#include <18F67k22.h>
#fuses HSH, PLLEN, NOWDT, NODEBUG, NOMCLR, PUT
#use delay(clock=64M)

#use i2c(master, I2C2)

char LCD_Data[90];

int ver, reg1, reg2;
int16 xpos, ypos;
int1 pen;

#include "SSD2119.c"
#include "CGraphics.c"
#include "AR1021.c"

void main()
   {
      GLCD_init();
      output_high(LCD_BL_ENABLE);

      AR1021_Send_Command(GET_VERSION);
      ver = AR1021_data[4];

      sprintf(lcd_data,"Version = %u",ver);
      glcd_text(0,0,lcd_data,GREEN,BLACK);

      AR1021_Read_Register(PenUpDelay);
      reg1 = AR1021_data[2];

      AR1021_Set_Register(PenUpDelay, 0x49);      

      AR1021_Read_Register(PenUpDelay);
      reg2 = AR1021_data[2];

      sprintf(lcd_data,"Reg1=%X Reg2=%X",reg1, reg2);
      glcd_text(0,30,lcd_data,GREEN,BLACK);


      while(1)
         {      
            if(input_state(AR1021_INT_PIN))                                       //check to see if the screen has been touched.
               {
                  pen = AR1021_GetPos(xpos, ypos);

                  GLCD_rect(0,60,319,80, YES, BLACK);
                  sprintf(lcd_data,"X=%lu Y=%lu PEN=%u",xpos, ypos, pen);
                  glcd_text(0,60,lcd_data,GREEN,BLACK);
               }
            delay_ms(100);
         }




(No idea what happen to the indents)

Thanks

Mark
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group