![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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.
Diff: IQS5xx/IQS5xx.cpp
- Revision:
- 0:4907da2299a4
- Child:
- 2:bd4b620316aa
diff -r 000000000000 -r 4907da2299a4 IQS5xx/IQS5xx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IQS5xx/IQS5xx.cpp Wed Jan 01 12:51:18 2020 +0000 @@ -0,0 +1,507 @@ +/* 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 : + //////////////////////// + + // swipe initial distance + ui8DataBuffer[1] = 180; 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]); + + // 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 + I2C_Read(TotalRx_adr, &ui8DataBuffer[0] ,1); + printf("nombre cannaux Rx : %d\n", ui8DataBuffer[0]); + + // total chanel Tx + 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"); + 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); + } +} \ No newline at end of file