skydarc meneldoll / Mbed 2 deprecated IQS572_HelloWorld

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IQS5xx.cpp Source File

IQS5xx.cpp

00001 /* IQS572.cpp
00002  * Tested with mbed board: LPC1768
00003  * Author: skydarc
00004  * skydarc@gmail.com
00005  */
00006  
00007 #include "mbed.h"
00008 #include "IQS5xx.h"
00009 #include <new>
00010 
00011 
00012 IQS5xx::IQS5xx (PinName sda, PinName scl, PinName rdy) : i2c_(*reinterpret_cast<I2C*>(i2cRaw)), _readyPin(rdy) {
00013     
00014     // Placement new to avoid additional heap memory allocation.
00015     new(i2cRaw) I2C(sda, scl);
00016     
00017     //_readyPin.input();
00018 }
00019 
00020 //*****************************************************************************
00021 //
00022 //! Acknowledge the reset flag
00023 //!
00024 //! This function simply sets the ACK_RESET bit found in the SYSTEM_CONTROL_0 
00025 //! register.  By setting this bit the SHOW_RESET flag is cleared in the 
00026 //! SYSTEM_INFO_0 register.  During normal operation, the SHOW_RESET bit can be 
00027 //! monitored and if it becomes set, then an unexpected reset has occurred.  
00028 //! If any device configuration is needed, it must then be repeated.
00029 //!
00030 //! \param None
00031 //!
00032 //! \return None
00033 //
00034 //*****************************************************************************
00035 void IQS5xx::AcknowledgeReset(void) {
00036     static  uint8_t System_ctrl_0 = ACK_RESET;  
00037 
00038     I2C_Write(SystemControl0_adr, &System_ctrl_0, 1);
00039 }
00040 
00041 void IQS5xx::checkVersion(void) {
00042   
00043     uint8_t ui8DataBuffer[15];  // defaut size : 6
00044     //
00045     // Dont wait for RDY here, since the device could be in EventMode, and then
00046     // there will be no communication window to complete this.  Rather do a 
00047     // forced communication, where clock stretching will be done on the IQS5xx
00048     // until an appropriate time to complete the i2c.
00049     //
00050     I2C_Read(ProductNumber_adr, &ui8DataBuffer[0] ,6);
00051   
00052     printf("Product %d ", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); 
00053     printf("Project %d ", (ui8DataBuffer[2]<<8) + ui8DataBuffer[3]);
00054     printf("Version %d.%d\n", ui8DataBuffer[4], ui8DataBuffer[5]);
00055     
00056     ////////////////////////
00057     // check other address :
00058     ////////////////////////
00059     
00060     // System Config 1
00061     ui8DataBuffer[0] = 3; 
00062     I2C_Write(SystemConfig1_adr, &ui8DataBuffer[0] ,1);
00063     I2C_Read(SystemConfig1_adr, &ui8DataBuffer[0] ,1);
00064     printf("System Config : %d\n", ui8DataBuffer[0]); 
00065       
00066     // swipe initial distance
00067     ui8DataBuffer[1] = 150; ui8DataBuffer[0] = 0; 
00068     I2C_Write(SwipeInitDistance_adr, &ui8DataBuffer[0] ,2);
00069     I2C_Read(SwipeInitDistance_adr, &ui8DataBuffer[0] ,2);
00070     printf("Swp init dist. : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); 
00071     
00072     // X resolution
00073     ui8DataBuffer[1] = 0; ui8DataBuffer[0] = 8; 
00074     I2C_Write(XResolution_adr, &ui8DataBuffer[0] ,2);
00075     I2C_Read(XResolution_adr, &ui8DataBuffer[0] ,2);
00076     printf("X resolution : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); 
00077     
00078     // Yresolution
00079     ui8DataBuffer[1] = 0; ui8DataBuffer[0] = 8; 
00080     I2C_Write(YResolution_adr, &ui8DataBuffer[0] ,2);
00081     I2C_Read(YResolution_adr, &ui8DataBuffer[0] ,2);
00082     printf("Y resolution : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]);
00083     
00084     // Rx mapping
00085     I2C_Read(RxMapping_adr, &ui8DataBuffer[0] ,10);
00086     printf("mapping Rx :"); 
00087     printf(" %d,", ui8DataBuffer[0]);
00088     printf(" %d,", ui8DataBuffer[1]);
00089     printf(" %d,", ui8DataBuffer[2]);
00090     printf(" %d,", ui8DataBuffer[3]);
00091     printf(" %d,", ui8DataBuffer[4]);
00092     printf(" %d,", ui8DataBuffer[5]);
00093     printf(" %d,", ui8DataBuffer[6]);
00094     printf(" %d\n", ui8DataBuffer[7]);
00095     
00096     // Tx mapping
00097     I2C_Read(TxMapping_adr, &ui8DataBuffer[0] ,10);
00098     printf("mapping Tx :"); 
00099     printf(" %d,", ui8DataBuffer[0]);
00100     printf(" %d,", ui8DataBuffer[1]);
00101     printf(" %d,", ui8DataBuffer[2]);
00102     printf(" %d,", ui8DataBuffer[3]);
00103     printf(" %d,", ui8DataBuffer[4]);
00104     printf(" %d,", ui8DataBuffer[5]);
00105     printf(" %d,", ui8DataBuffer[6]);
00106     printf(" %d\n", ui8DataBuffer[7]);
00107     
00108     // total chanel Rx
00109     ui8DataBuffer[0] = 3; 
00110     I2C_Write(TotalRx_adr, &ui8DataBuffer[0] ,1);
00111     I2C_Read(TotalRx_adr, &ui8DataBuffer[0] ,1);
00112     printf("nombre cannaux Rx : %d\n", ui8DataBuffer[0]); 
00113 
00114     // total chanel Tx
00115     ui8DataBuffer[0] = 4; 
00116     I2C_Write(TotalTx_adr, &ui8DataBuffer[0] ,1);
00117     I2C_Read(TotalTx_adr, &ui8DataBuffer[0] ,1);
00118     printf("nombre cannaux Tx : %d\n", ui8DataBuffer[0]);  
00119 }
00120 
00121 //*****************************************************************************
00122 //
00123 //! Display a snap state change
00124 //!                            
00125 //! If the state of any snap output has changed, then this function can be used
00126 //! to display which Rx/Tx channel has changed status.  
00127 //!                                  
00128 //! \param None
00129 //!                                           
00130 //! \return None
00131 //                                                      
00132 //*****************************************************************************
00133 void IQS5xx::DisplaySnap(void)
00134 {
00135     uint8_t     ui8Tx, ui8Rx;
00136     uint16_t    ui16ToggledBits;
00137     
00138     for(ui8Tx = 0; ui8Tx < 15; ui8Tx++)
00139     {
00140         ui16ToggledBits = ui16PrevSnap[ui8Tx] ^ ui16SnapStatus[ui8Tx];
00141 
00142         for(ui8Rx = 0; ui8Rx < 10; ui8Rx++)
00143         {
00144             if(BitIsSet(ui16ToggledBits, ui8Rx))
00145             {
00146                 if(BitIsSet(ui16SnapStatus[ui8Tx], ui8Rx))
00147                 {
00148                     printf("Snap set on Rx:");
00149                 }
00150                 else
00151                 {
00152                     printf("Snap released on Rx:");
00153                 }
00154                 printf(" %d / Tx: %d  channel    \n", ui8Rx, ui8Tx);
00155             }
00156         }
00157     }
00158 }
00159 
00160 //*****************************************************************************
00161 //
00162 //! Process the data received
00163 //!                            
00164 //! This function sorts the read bytes from the IQS5xx and prints relevant data 
00165 //! on serial port. 
00166 //! REL_X[n]: Relative X Position of the finger n; n is from (1 to 5)
00167 //! REL_Y[n]: Relative X Position of the finger n; n is from (1 to 5)
00168 //! ABS_X[n]: Absolute X Position of the finger n; n is from (1 to 5)
00169 //! ABS_Y[n]: Absolute Y Position of the finger n; n is from (1 to 5)
00170 //! ui16TouchStrength[n]   : Touch strength of finger n; n is from (1 to 5)
00171 //! ui8Area[n]   : Touch area of finger n; this is number of channels under touch 
00172 //! for a particular finger; 
00173 //! Where 'n' is from (1 to 5)
00174 //!                                  
00175 //! \param None
00176 //!                                           
00177 //! \return None
00178 //                                                      
00179 //*****************************************************************************
00180 void IQS5xx::Process_XY(void) 
00181 { 
00182     uint8_t     i; 
00183     static uint8_t ui8FirstTouch = 0;
00184     uint8_t     ui8NoOfFingers;
00185     uint8_t     ui8SystemFlags[2];
00186     int16_t     i16RelX[6];
00187     int16_t     i16RelY[6];
00188     uint16_t    ui16AbsX[6];
00189     uint16_t    ui16AbsY[6];
00190     uint16_t    ui16TouchStrength[6];
00191     uint8_t     ui8Area[6];
00192  
00193     ui8SystemFlags[0] = Data_Buff[2];
00194     ui8SystemFlags[1] = Data_Buff[3];
00195     ui8NoOfFingers = Data_Buff[4];
00196     //
00197     // Re-initialize the device if unexpected RESET detected
00198     //
00199     if((ui8SystemFlags[0] & SHOW_RESET) != 0)
00200     {
00201         printf("RESET DETECTED\n");
00202         AcknowledgeReset(); 
00203         return;
00204     }
00205 
00206     if((ui8SystemFlags[1] & SNAP_TOGGLE) != 0)
00207     {
00208         // A snap state has changed, thus indicate which channel
00209         //
00210         DisplaySnap();
00211         return;
00212     }
00213 
00214     if((Data_Buff[0]) == SINGLE_TAP) 
00215     {       
00216         printf("Single Tap  \n"); 
00217     }
00218     else if((Data_Buff[1]) == TWO_FINGER_TAP)   
00219     {
00220         printf("2 Finger Tap\n"); 
00221     }       
00222 
00223     if(ui8NoOfFingers != 0) 
00224     {
00225         if (!(ui8FirstTouch)) 
00226         {
00227             printf("Gestures:    \n");
00228             //printf(" RelX: ");
00229             //printf("RelY: ");
00230             //printf("Fig: ");
00231             //printf("X1:  "); printf("Y1:  "); printf("TS1: "); printf("TA1: ");
00232             //printf("X2:  "); printf("Y2:  "); printf("TS2: "); printf("TA2:\n");
00233             //printf("X3:  "); printf("Y3:  "); printf("TS3: "); printf("TA3: ");
00234             //printf("X4:  "); printf("Y4:  "); printf("TS4: "); printf("TA4: ");
00235             //printf("X5:  "); printf("Y5:  "); printf("TS5: "); printf("TA5: \n");
00236             ui8FirstTouch = 1;
00237         }
00238 
00239         switch (Data_Buff[0])
00240         {
00241             case SINGLE_TAP     :   printf("Single Tap  \n"); 
00242                                     break;
00243             case TAP_AND_HOLD   :   printf("Tap & Hold  \n"); 
00244                                     break;
00245             case SWIPE_X_NEG    :   printf("Swipe X-    \n"); 
00246                                     break;
00247             case SWIPE_X_POS    :   printf("Swipe X+    \n"); 
00248                                     break;
00249             case SWIPE_Y_POS    :   printf("Swipe Y+    \n"); 
00250                                     break;
00251             case SWIPE_Y_NEG    :   printf("Swipe Y-    \n"); 
00252                                     break;
00253         }
00254 
00255         switch (Data_Buff[1])
00256         {
00257             case TWO_FINGER_TAP :   printf("2 Finger Tap\n"); 
00258                                     break;
00259             case SCROLL         :   printf("Scroll      \n"); 
00260                                     break;
00261             case ZOOM           :   printf("Zoom        \n"); 
00262                                     break;
00263         }
00264         if((Data_Buff[0] | Data_Buff[1]) == 0) 
00265         {
00266             //printf("            ");
00267         }
00268 
00269         /*i16RelX[1] = ((Data_Buff[5] << 8) | (Data_Buff[6]));
00270         i16RelY[1] = ((Data_Buff[7] << 8) | (Data_Buff[8]));
00271         
00272         Print_signed(i16RelX[1]);
00273         Print_signed(i16RelY[1]);
00274         Print_unsigned(ui8NoOfFingers);    
00275 
00276         for (i = 0; i < 2; i++)
00277         {
00278             ui16AbsX[i+1] = ((Data_Buff[(7*i)+9] << 8) | (Data_Buff[(7*i)+10])); //9-16-23-30-37//10-17-24-31-38
00279             ui16AbsY[i+1] = ((Data_Buff[(7*i)+11] << 8) | (Data_Buff[(7*i)+12])); //11-18-25-32-39//12-19-26-33-40
00280             ui16TouchStrength[i+1] = ((Data_Buff[(7*i)+13] << 8) | (Data_Buff[(7*i)+14])); //13-20-27-34-11/14-21-28-35-42
00281             ui8Area[i+1] = (Data_Buff[7*i+15]); //15-22-29-36-43
00282             
00283             Print_unsigned(ui16AbsX[i+1]);
00284             Print_unsigned(ui16AbsY[i+1]);
00285             Print_unsigned(ui16TouchStrength[i+1]);
00286             Print_unsigned(ui8Area[i+1]);
00287         }
00288         printf("");*/
00289     } 
00290     else 
00291     {
00292         ui8FirstTouch = 0;
00293     }
00294 }
00295 
00296 //*****************************************************************************
00297 //
00298 //! Terminate communication window
00299 //!                            
00300 //! The IQS5xx B000 does not close the communication window on the reception of 
00301 //! the STOP bit; therefore this function sends the END COMMUNICATION WINDOW 
00302 //! COMMAND (Please see datasheet for more information). RDY will go low after 
00303 //! receiving any write to 0xEEEE followed by a STOP. 
00304 //!                                  
00305 //! \param None
00306 //!                                           
00307 //! \return None
00308 //                                                      
00309 //*****************************************************************************
00310 void IQS5xx::Close_Comms() 
00311 {
00312   uint8_t ui8DataBuffer[1];
00313   
00314   I2C_Write(END_WINDOW, &ui8DataBuffer[0], 1);
00315 }
00316 
00317 //*****************************************************************************
00318 //
00319 //! I2C write function
00320 //!
00321 //! This function writes the provided data to the address specified.  If  
00322 //! anything in the write process is not successful, then it will be repeated
00323 //! up till four more times.  If still not successful, it will write an error
00324 //! message on the serial terminal.
00325 //!
00326 //! \param ui16RegisterAddress is the 16-bit memory map address on the IQS5xx
00327 //! \param pData is a pointer to the first byte of a block of data to write
00328 //! \param ui8NoOfBytes indicates how many bytes of data to write
00329 //!
00330 //! \return Boolean indicating success/fail of write attempt
00331 //
00332 //*****************************************************************************
00333 uint8_t IQS5xx::I2C_Write(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) {
00334     
00335     uint8_t ui8Retry = 4;
00336     
00337     ui8Success = I2C_Write2(ui16RegisterAddress, pData, ui8NoOfBytes);
00338     
00339     //
00340     // If comms was not successful, retry 4 more times
00341     //
00342     while((!ui8Success) && (ui8Retry != 0))
00343     {
00344         wait_ms(5);
00345         ui8Success = I2C_Write2(ui16RegisterAddress, pData, ui8NoOfBytes);
00346         ui8Retry--;
00347     }
00348     
00349     if(ui8Success) return(true);
00350     else {
00351         printf("Comms write error\n");
00352         return(false);
00353     }
00354 }
00355 
00356 //*****************************************************************************
00357 //
00358 //! I2C read function
00359 //!
00360 //! This function reads data from the address specified and stores this data
00361 //! in the area provided by the pointer.  If anything in the read process is 
00362 //! not successful, then it will be repeated up till four more times.  
00363 //! If still not successful, it will write an error message on the serial 
00364 //! terminal.
00365 //!
00366 //! \param ui16RegisterAddress is the 16-bit memory map address on the IQS5xx
00367 //! \param pData is a pointer to where the read data must be stored
00368 //! \param ui8NoOfBytes indicates how many bytes of data to read
00369 //!
00370 //! \return Boolean indicating success/fail of read attempt
00371 //
00372 //*****************************************************************************
00373 uint8_t IQS5xx::I2C_Read(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) {
00374     
00375     uint8_t ui8Retry = 4;
00376     
00377     ui8Success = I2C_Read2(ui16RegisterAddress, pData, ui8NoOfBytes);
00378     
00379     //
00380     // If comms was not successful, retry 4 more times
00381     //
00382     while((!ui8Success) && (ui8Retry != 0)) {
00383         wait_ms(5);
00384         ui8Success = I2C_Read2(ui16RegisterAddress, pData, ui8NoOfBytes);
00385         ui8Retry--;
00386     }
00387     
00388     if(ui8Success) return(true);
00389     else {
00390         printf("Comms read error\n");
00391         return(false);
00392     }
00393 }
00394 
00395 uint8_t IQS5xx::I2C_Write2(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes)
00396 {
00397     uint8_t i;
00398     
00399     i2c_.start();
00400 
00401     if(i2c_.write(IQS5xx_ADDR<<1) == false) return(false);
00402     
00403     if(i2c_.write((uint8_t)(ui16RegisterAddress>>8)) == false) return(false);
00404     if(i2c_.write((uint8_t)ui16RegisterAddress) == false) return(false);
00405     
00406     for(i = 0; i < ui8NoOfBytes; i++) {       
00407         if(i2c_.write(*pData) == false) return(false);
00408         pData++;
00409     }
00410 
00411     i2c_.stop();
00412     
00413     return(true);
00414 }
00415 
00416 uint8_t IQS5xx::I2C_Read2(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) {
00417     
00418     uint8_t i;
00419     
00420     if(ui8NoOfBytes == 0) ui8NoOfBytes++;
00421     
00422     i2c_.start();
00423     
00424     if(i2c_.write(IQS5xx_ADDR<<1) == false) return(false);
00425     
00426     if(i2c_.write((uint8_t)(ui16RegisterAddress>>8)) == false) return(false);
00427     if(i2c_.write((uint8_t)ui16RegisterAddress) == false) return(false);
00428     
00429     i2c_.start();
00430     
00431     if(i2c_.write((IQS5xx_ADDR<<1) + 0x01) == false) return(false);
00432     
00433     for(i = 0; i < ui8NoOfBytes; i++)
00434     {
00435         if(i == (ui8NoOfBytes - 1)) {
00436             *pData = i2c_.read(0);
00437         }
00438         else {
00439             *pData = i2c_.read(1);
00440         }
00441         pData++;
00442     }
00443     
00444     i2c_.stop();
00445     
00446     return(true);
00447 }
00448 
00449 //*****************************************************************************
00450 //
00451 //! Print a signed value on serial display
00452 //!                            
00453 //! Print the signed integer on the serial port with adjusted tabs 
00454 //! on serial port for easy column reading. 
00455 //!                                  
00456 //! \param None
00457 //!                                           
00458 //! \return None
00459 //                                                      
00460 //*****************************************************************************
00461 void IQS5xx::Print_signed(int16_t i16Num)
00462 {
00463     if(i16Num < (-99))
00464     {
00465         printf(" ");
00466     }
00467     else if(i16Num < (-9))
00468     {
00469         printf("  ");
00470     }
00471     else if(i16Num < 0)
00472     {
00473         printf("   ");
00474     }
00475     else if(i16Num < 10)
00476     {
00477         printf("    ");
00478     }
00479     else if(i16Num < 100)
00480     {
00481         printf("   ");
00482     }
00483     else if(i16Num < 1000)
00484     {
00485         printf("  ");
00486     }
00487     printf("%d", i16Num);
00488 }
00489 
00490 //*****************************************************************************
00491 //
00492 //! Print an unsigned value on serial display
00493 //!                            
00494 //! Print the unsigned integer on the serial port with adjusted tabs 
00495 //! on serial port for easy column reading. 
00496 //!                                  
00497 //! \param None
00498 //!                                           
00499 //! \return None
00500 //                                                      
00501 //*****************************************************************************
00502 void IQS5xx::Print_unsigned(uint16_t ui16Num)
00503 {
00504     if(ui16Num < 10)
00505     {
00506         printf("    ");
00507     }
00508     else if(ui16Num < 100)
00509     {
00510         printf("   ");
00511     }
00512     else if(ui16Num < 1000)
00513     {
00514         printf("  ");
00515     }
00516     else if(ui16Num < 10000)
00517     {
00518         printf(" ");
00519     }
00520 
00521     if(ui16Num > 10000)
00522     {
00523         printf("  xxx");
00524     }
00525     else
00526     {
00527         printf("%d", ui16Num);
00528     }
00529 }