int Si1147_MeasureUVAndObjectPresent(I2C_TypeDef *i2c, uint8_t addr, uint16_t *uvIndex, int *objectDetect) { uint16_t data; int retval = 0; int gestureMode; *objectDetect = 0; si114x_handle->addr = addr; si114x_handle->i2c = i2c; Si1147_GetInterruptOutputEnable(i2c,addr,&gestureMode); if ( !gestureMode ) /* Force only if not already running swipe detection. */ { Si114xPsAlsForce(si114x_handle); while ((Si114xReadFromRegister(si114x_handle, REG_IRQ_STATUS) & 1) == 0) ; /*wait for measurement data */ } data = Si114xReadFromRegister(si114x_handle, REG_AUX_DATA0); /*read sample data from si114x */ data |= Si114xReadFromRegister(si114x_handle, REG_AUX_DATA1) << 8; /*round to nearest*/ *uvIndex = data + 50; *uvIndex /= 100; if ( !gestureMode ) /* Check for object only if not already running swipe detection. */ { data = Si114xReadFromRegister(si114x_handle, REG_PS1_DATA0); /*read sample data from si114x */ data |= Si114xReadFromRegister(si114x_handle, REG_PS1_DATA1) << 8; if (data > PS_HOVER_THRESHOLD) { *objectDetect = 1; } } /*clear irq*/ Si114xWriteToRegister(si114x_handle, REG_IRQ_STATUS, 0xff); return retval; }
/**************************************************************************//** * @brief * Get the enable status of the Si1147 interrupt pin * @param[in] i2c * The I2C peripheral to use (not used). * @param[in] addr * The I2C address of the sensor. * @param[out] enable * Will be set to 1 if the interrupt output pin is enabled * or set to 0 if disabled. * @return * Returns 0. *****************************************************************************/ int Si1147_GetInterruptOutputEnable(I2C_TypeDef *i2c, uint8_t addr, int *enable) { int retval = 0; si114x_handle->addr = addr; si114x_handle->i2c = i2c; *enable = Si114xReadFromRegister(si114x_handle, REG_INT_CFG); return retval; }
/**************************************************************************//** * @brief * Detects whether Si1147 is on the i2c bus * @param[in] i2c * The I2C peripheral to use (not used). * @param[in] addr * The I2C address of the sensor. * @return * Returns 1 on success. Otherwise returns 0. *****************************************************************************/ int Si1147_Detect_Device(I2C_TypeDef *i2c, uint8_t addr) { uint8_t data; si114x_handle->addr = addr; si114x_handle->i2c = i2c; data = Si114xReadFromRegister(si114x_handle, 0); if (data == SI1147_DEVICE_ID) { return 1; } return 0; }
/**************************************************************************//** * @brief * Reads new measurement data and processes a new sample. This function * should be called every time an interrupt for a new sample is received. * @param[in] i2c * The I2C peripheral to use (not used). * @param[in] addr * The I2C address of the sensor. * @param[in] timestamp * The timestamp for when the sample interrupt was received. * @return * Returns the type of gesture detected (as defined by gesture_t). *****************************************************************************/ gesture_t Si1147_NewSample(I2C_TypeDef *i2c, uint8_t addr, uint32_t timestamp) { Si114x_Sample_TypeDef sample; si114x_handle->addr = addr; si114x_handle->i2c = i2c; sample.timestamp = timestamp; /*read sample data from si114x */ readPSData(si114x_handle, &sample); /*clear irq*/ Si114xWriteToRegister(si114x_handle, REG_IRQ_STATUS, Si114xReadFromRegister(si114x_handle, REG_IRQ_STATUS)); /*look for gestures */ return ProcessSi1147Samples(&sample); }
/**************************************************************************//** * @brief * Reads the UV index measurement data from the * Si114x. * @param[out] uvIndex * The UV index read from the sensor * @return * Returns 0. *****************************************************************************/ int Si114x_MeasureUVIndex(u16 *uvIndex) { u16 data; volatile u8 regval; int retval = 0; Si114xPsAlsForce(si114x_handle); regval = Si114xReadFromRegister(si114x_handle, REG_AUX_DATA0); /*read sample data from si114x */ data = regval; regval = Si114xReadFromRegister(si114x_handle, REG_AUX_DATA1); data |= regval << 8; //check for saturation after the forced measurement and clear it if found //otherwise the next si114x cmd will not be performed. Also this must be //done after reading the AUX_DATA register regval = Si114xReadFromRegister(si114x_handle, REG_RESPONSE); while((regval & 0x80) != 0) //response == 0x8x means saturation occured { // Send the NOP Command to clear the error...we cannot use Si114xNop() // because it first checks if REG_RESPONSE < 0 and if so it does not // perform the cmd. Since we have a saturation REG_RESPONSE will be <0 Si114xWriteToRegister(si114x_handle, REG_COMMAND, 0x00); regval = Si114xReadFromRegister(si114x_handle, REG_RESPONSE); } /*round to nearest*/ *uvIndex = data + 50; *uvIndex /= 100; /*clear irq*/ if(*uvIndex > 10) *uvIndex = data + 50; Si114xWriteToRegister(si114x_handle, REG_IRQ_STATUS, 0xff); return retval; }
/**************************************************************************//** * @brief * Reads the PS measurement data from the Si1147. * @param[in] si114x_handle * Contains i2c peripheral information. See definition of si114x_i2c_t. * @param[out] sample * The sample data read from the sensor. *****************************************************************************/ static void readPSData(HANDLE si114x_handle, Si114x_Sample_TypeDef *sample) { /*read sample data from si114x */ sample->ps1 = Si114xReadFromRegister(si114x_handle, REG_PS1_DATA0); sample->ps1 |= Si114xReadFromRegister(si114x_handle, REG_PS1_DATA1) << 8; sample->ps2 = Si114xReadFromRegister(si114x_handle, REG_PS2_DATA0); sample->ps2 |= Si114xReadFromRegister(si114x_handle, REG_PS2_DATA1) << 8; sample->ps3 = Si114xReadFromRegister(si114x_handle, REG_PS3_DATA0); sample->ps3 |= Si114xReadFromRegister(si114x_handle, REG_PS3_DATA1) << 8; }