this is a first compilation of a library for IQS5xx. For now, it work with the iqs572ev02 devellopment board. The code is inspired with the sample code provide by Azotech. I have some issu with the interrupt pin RDY, which seem to be high even I don't touch de board.
IQS5xx/IQS5xx.cpp
- Committer:
- skydarc
- Date:
- 2020-01-01
- Revision:
- 2:bd4b620316aa
- Parent:
- 0:4907da2299a4
File content as of revision 2:bd4b620316aa:
/* IQS572.cpp * Tested with mbed board: LPC1768 * Author: skydarc * skydarc@gmail.com */ #include "mbed.h" #include "IQS5xx.h" #include <new> IQS5xx::IQS5xx(PinName sda, PinName scl, PinName rdy) : i2c_(*reinterpret_cast<I2C*>(i2cRaw)), _readyPin(rdy) { // Placement new to avoid additional heap memory allocation. new(i2cRaw) I2C(sda, scl); //_readyPin.input(); } //***************************************************************************** // //! Acknowledge the reset flag //! //! This function simply sets the ACK_RESET bit found in the SYSTEM_CONTROL_0 //! register. By setting this bit the SHOW_RESET flag is cleared in the //! SYSTEM_INFO_0 register. During normal operation, the SHOW_RESET bit can be //! monitored and if it becomes set, then an unexpected reset has occurred. //! If any device configuration is needed, it must then be repeated. //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::AcknowledgeReset(void) { static uint8_t System_ctrl_0 = ACK_RESET; I2C_Write(SystemControl0_adr, &System_ctrl_0, 1); } void IQS5xx::checkVersion(void) { uint8_t ui8DataBuffer[15]; // defaut size : 6 // // Dont wait for RDY here, since the device could be in EventMode, and then // there will be no communication window to complete this. Rather do a // forced communication, where clock stretching will be done on the IQS5xx // until an appropriate time to complete the i2c. // I2C_Read(ProductNumber_adr, &ui8DataBuffer[0] ,6); printf("Product %d ", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); printf("Project %d ", (ui8DataBuffer[2]<<8) + ui8DataBuffer[3]); printf("Version %d.%d\n", ui8DataBuffer[4], ui8DataBuffer[5]); //////////////////////// // check other address : //////////////////////// // System Config 1 ui8DataBuffer[0] = 3; I2C_Write(SystemConfig1_adr, &ui8DataBuffer[0] ,1); I2C_Read(SystemConfig1_adr, &ui8DataBuffer[0] ,1); printf("System Config : %d\n", ui8DataBuffer[0]); // swipe initial distance ui8DataBuffer[1] = 150; ui8DataBuffer[0] = 0; I2C_Write(SwipeInitDistance_adr, &ui8DataBuffer[0] ,2); I2C_Read(SwipeInitDistance_adr, &ui8DataBuffer[0] ,2); printf("Swp init dist. : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); // X resolution ui8DataBuffer[1] = 0; ui8DataBuffer[0] = 8; I2C_Write(XResolution_adr, &ui8DataBuffer[0] ,2); I2C_Read(XResolution_adr, &ui8DataBuffer[0] ,2); printf("X resolution : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); // Yresolution ui8DataBuffer[1] = 0; ui8DataBuffer[0] = 8; I2C_Write(YResolution_adr, &ui8DataBuffer[0] ,2); I2C_Read(YResolution_adr, &ui8DataBuffer[0] ,2); printf("Y resolution : %d\n", (ui8DataBuffer[0]<<8) + ui8DataBuffer[1]); // Rx mapping I2C_Read(RxMapping_adr, &ui8DataBuffer[0] ,10); printf("mapping Rx :"); printf(" %d,", ui8DataBuffer[0]); printf(" %d,", ui8DataBuffer[1]); printf(" %d,", ui8DataBuffer[2]); printf(" %d,", ui8DataBuffer[3]); printf(" %d,", ui8DataBuffer[4]); printf(" %d,", ui8DataBuffer[5]); printf(" %d,", ui8DataBuffer[6]); printf(" %d\n", ui8DataBuffer[7]); // Tx mapping I2C_Read(TxMapping_adr, &ui8DataBuffer[0] ,10); printf("mapping Tx :"); printf(" %d,", ui8DataBuffer[0]); printf(" %d,", ui8DataBuffer[1]); printf(" %d,", ui8DataBuffer[2]); printf(" %d,", ui8DataBuffer[3]); printf(" %d,", ui8DataBuffer[4]); printf(" %d,", ui8DataBuffer[5]); printf(" %d,", ui8DataBuffer[6]); printf(" %d\n", ui8DataBuffer[7]); // total chanel Rx ui8DataBuffer[0] = 3; I2C_Write(TotalRx_adr, &ui8DataBuffer[0] ,1); I2C_Read(TotalRx_adr, &ui8DataBuffer[0] ,1); printf("nombre cannaux Rx : %d\n", ui8DataBuffer[0]); // total chanel Tx ui8DataBuffer[0] = 4; I2C_Write(TotalTx_adr, &ui8DataBuffer[0] ,1); I2C_Read(TotalTx_adr, &ui8DataBuffer[0] ,1); printf("nombre cannaux Tx : %d\n", ui8DataBuffer[0]); } //***************************************************************************** // //! Display a snap state change //! //! If the state of any snap output has changed, then this function can be used //! to display which Rx/Tx channel has changed status. //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::DisplaySnap(void) { uint8_t ui8Tx, ui8Rx; uint16_t ui16ToggledBits; for(ui8Tx = 0; ui8Tx < 15; ui8Tx++) { ui16ToggledBits = ui16PrevSnap[ui8Tx] ^ ui16SnapStatus[ui8Tx]; for(ui8Rx = 0; ui8Rx < 10; ui8Rx++) { if(BitIsSet(ui16ToggledBits, ui8Rx)) { if(BitIsSet(ui16SnapStatus[ui8Tx], ui8Rx)) { printf("Snap set on Rx:"); } else { printf("Snap released on Rx:"); } printf(" %d / Tx: %d channel \n", ui8Rx, ui8Tx); } } } } //***************************************************************************** // //! Process the data received //! //! This function sorts the read bytes from the IQS5xx and prints relevant data //! on serial port. //! REL_X[n]: Relative X Position of the finger n; n is from (1 to 5) //! REL_Y[n]: Relative X Position of the finger n; n is from (1 to 5) //! ABS_X[n]: Absolute X Position of the finger n; n is from (1 to 5) //! ABS_Y[n]: Absolute Y Position of the finger n; n is from (1 to 5) //! ui16TouchStrength[n] : Touch strength of finger n; n is from (1 to 5) //! ui8Area[n] : Touch area of finger n; this is number of channels under touch //! for a particular finger; //! Where 'n' is from (1 to 5) //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::Process_XY(void) { uint8_t i; static uint8_t ui8FirstTouch = 0; uint8_t ui8NoOfFingers; uint8_t ui8SystemFlags[2]; int16_t i16RelX[6]; int16_t i16RelY[6]; uint16_t ui16AbsX[6]; uint16_t ui16AbsY[6]; uint16_t ui16TouchStrength[6]; uint8_t ui8Area[6]; ui8SystemFlags[0] = Data_Buff[2]; ui8SystemFlags[1] = Data_Buff[3]; ui8NoOfFingers = Data_Buff[4]; // // Re-initialize the device if unexpected RESET detected // if((ui8SystemFlags[0] & SHOW_RESET) != 0) { printf("RESET DETECTED\n"); AcknowledgeReset(); return; } if((ui8SystemFlags[1] & SNAP_TOGGLE) != 0) { // A snap state has changed, thus indicate which channel // DisplaySnap(); return; } if((Data_Buff[0]) == SINGLE_TAP) { printf("Single Tap \n"); } else if((Data_Buff[1]) == TWO_FINGER_TAP) { printf("2 Finger Tap\n"); } if(ui8NoOfFingers != 0) { if (!(ui8FirstTouch)) { printf("Gestures: \n"); //printf(" RelX: "); //printf("RelY: "); //printf("Fig: "); //printf("X1: "); printf("Y1: "); printf("TS1: "); printf("TA1: "); //printf("X2: "); printf("Y2: "); printf("TS2: "); printf("TA2:\n"); //printf("X3: "); printf("Y3: "); printf("TS3: "); printf("TA3: "); //printf("X4: "); printf("Y4: "); printf("TS4: "); printf("TA4: "); //printf("X5: "); printf("Y5: "); printf("TS5: "); printf("TA5: \n"); ui8FirstTouch = 1; } switch (Data_Buff[0]) { case SINGLE_TAP : printf("Single Tap \n"); break; case TAP_AND_HOLD : printf("Tap & Hold \n"); break; case SWIPE_X_NEG : printf("Swipe X- \n"); break; case SWIPE_X_POS : printf("Swipe X+ \n"); break; case SWIPE_Y_POS : printf("Swipe Y+ \n"); break; case SWIPE_Y_NEG : printf("Swipe Y- \n"); break; } switch (Data_Buff[1]) { case TWO_FINGER_TAP : printf("2 Finger Tap\n"); break; case SCROLL : printf("Scroll \n"); break; case ZOOM : printf("Zoom \n"); break; } if((Data_Buff[0] | Data_Buff[1]) == 0) { //printf(" "); } /*i16RelX[1] = ((Data_Buff[5] << 8) | (Data_Buff[6])); i16RelY[1] = ((Data_Buff[7] << 8) | (Data_Buff[8])); Print_signed(i16RelX[1]); Print_signed(i16RelY[1]); Print_unsigned(ui8NoOfFingers); for (i = 0; i < 2; i++) { ui16AbsX[i+1] = ((Data_Buff[(7*i)+9] << 8) | (Data_Buff[(7*i)+10])); //9-16-23-30-37//10-17-24-31-38 ui16AbsY[i+1] = ((Data_Buff[(7*i)+11] << 8) | (Data_Buff[(7*i)+12])); //11-18-25-32-39//12-19-26-33-40 ui16TouchStrength[i+1] = ((Data_Buff[(7*i)+13] << 8) | (Data_Buff[(7*i)+14])); //13-20-27-34-11/14-21-28-35-42 ui8Area[i+1] = (Data_Buff[7*i+15]); //15-22-29-36-43 Print_unsigned(ui16AbsX[i+1]); Print_unsigned(ui16AbsY[i+1]); Print_unsigned(ui16TouchStrength[i+1]); Print_unsigned(ui8Area[i+1]); } printf("");*/ } else { ui8FirstTouch = 0; } } //***************************************************************************** // //! Terminate communication window //! //! The IQS5xx B000 does not close the communication window on the reception of //! the STOP bit; therefore this function sends the END COMMUNICATION WINDOW //! COMMAND (Please see datasheet for more information). RDY will go low after //! receiving any write to 0xEEEE followed by a STOP. //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::Close_Comms() { uint8_t ui8DataBuffer[1]; I2C_Write(END_WINDOW, &ui8DataBuffer[0], 1); } //***************************************************************************** // //! I2C write function //! //! This function writes the provided data to the address specified. If //! anything in the write process is not successful, then it will be repeated //! up till four more times. If still not successful, it will write an error //! message on the serial terminal. //! //! \param ui16RegisterAddress is the 16-bit memory map address on the IQS5xx //! \param pData is a pointer to the first byte of a block of data to write //! \param ui8NoOfBytes indicates how many bytes of data to write //! //! \return Boolean indicating success/fail of write attempt // //***************************************************************************** uint8_t IQS5xx::I2C_Write(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) { uint8_t ui8Retry = 4; ui8Success = I2C_Write2(ui16RegisterAddress, pData, ui8NoOfBytes); // // If comms was not successful, retry 4 more times // while((!ui8Success) && (ui8Retry != 0)) { wait_ms(5); ui8Success = I2C_Write2(ui16RegisterAddress, pData, ui8NoOfBytes); ui8Retry--; } if(ui8Success) return(true); else { printf("Comms write error\n"); return(false); } } //***************************************************************************** // //! I2C read function //! //! This function reads data from the address specified and stores this data //! in the area provided by the pointer. If anything in the read process is //! not successful, then it will be repeated up till four more times. //! If still not successful, it will write an error message on the serial //! terminal. //! //! \param ui16RegisterAddress is the 16-bit memory map address on the IQS5xx //! \param pData is a pointer to where the read data must be stored //! \param ui8NoOfBytes indicates how many bytes of data to read //! //! \return Boolean indicating success/fail of read attempt // //***************************************************************************** uint8_t IQS5xx::I2C_Read(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) { uint8_t ui8Retry = 4; ui8Success = I2C_Read2(ui16RegisterAddress, pData, ui8NoOfBytes); // // If comms was not successful, retry 4 more times // while((!ui8Success) && (ui8Retry != 0)) { wait_ms(5); ui8Success = I2C_Read2(ui16RegisterAddress, pData, ui8NoOfBytes); ui8Retry--; } if(ui8Success) return(true); else { printf("Comms read error\n"); return(false); } } uint8_t IQS5xx::I2C_Write2(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) { uint8_t i; i2c_.start(); if(i2c_.write(IQS5xx_ADDR<<1) == false) return(false); if(i2c_.write((uint8_t)(ui16RegisterAddress>>8)) == false) return(false); if(i2c_.write((uint8_t)ui16RegisterAddress) == false) return(false); for(i = 0; i < ui8NoOfBytes; i++) { if(i2c_.write(*pData) == false) return(false); pData++; } i2c_.stop(); return(true); } uint8_t IQS5xx::I2C_Read2(uint16_t ui16RegisterAddress, uint8_t *pData, uint8_t ui8NoOfBytes) { uint8_t i; if(ui8NoOfBytes == 0) ui8NoOfBytes++; i2c_.start(); if(i2c_.write(IQS5xx_ADDR<<1) == false) return(false); if(i2c_.write((uint8_t)(ui16RegisterAddress>>8)) == false) return(false); if(i2c_.write((uint8_t)ui16RegisterAddress) == false) return(false); i2c_.start(); if(i2c_.write((IQS5xx_ADDR<<1) + 0x01) == false) return(false); for(i = 0; i < ui8NoOfBytes; i++) { if(i == (ui8NoOfBytes - 1)) { *pData = i2c_.read(0); } else { *pData = i2c_.read(1); } pData++; } i2c_.stop(); return(true); } //***************************************************************************** // //! Print a signed value on serial display //! //! Print the signed integer on the serial port with adjusted tabs //! on serial port for easy column reading. //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::Print_signed(int16_t i16Num) { if(i16Num < (-99)) { printf(" "); } else if(i16Num < (-9)) { printf(" "); } else if(i16Num < 0) { printf(" "); } else if(i16Num < 10) { printf(" "); } else if(i16Num < 100) { printf(" "); } else if(i16Num < 1000) { printf(" "); } printf("%d", i16Num); } //***************************************************************************** // //! Print an unsigned value on serial display //! //! Print the unsigned integer on the serial port with adjusted tabs //! on serial port for easy column reading. //! //! \param None //! //! \return None // //***************************************************************************** void IQS5xx::Print_unsigned(uint16_t ui16Num) { if(ui16Num < 10) { printf(" "); } else if(ui16Num < 100) { printf(" "); } else if(ui16Num < 1000) { printf(" "); } else if(ui16Num < 10000) { printf(" "); } if(ui16Num > 10000) { printf(" xxx"); } else { printf("%d", ui16Num); } }