![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Uses the APDS_9960 Digital Proximity, Ambient Light, RGB and Gesture Sensor library to play detected gesture sounds on a speaker from the SDcard
Dependencies: mbed SDFileSystem wave_player
Diff: glibr.cpp
- Revision:
- 9:286d00d9db80
- Parent:
- 8:6fa15d4e31fb
- Child:
- 10:e8adab2fb829
diff -r 6fa15d4e31fb -r 286d00d9db80 glibr.cpp --- a/glibr.cpp Fri Mar 06 21:50:03 2015 +0000 +++ b/glibr.cpp Fri Mar 06 22:59:40 2015 +0000 @@ -22,10 +22,8 @@ } - uint8_t glibr::ginit(){ + bool glibr::ginit(){ uint8_t id; - - // if( !wireReadDataByte(APDS9960_ID, id) ) { id=I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ID); @@ -121,45 +119,44 @@ return false; } - + return true; - return id; } -#if 0 - /* Gesture config register dump */ - uint8_t reg; - uint8_t val; - - for(reg = 0x80; reg <= 0xAF; reg++) { - if( (reg != 0x82) && \ - (reg != 0x8A) && \ - (reg != 0x91) && \ - (reg != 0xA8) && \ - (reg != 0xAC) && \ - (reg != 0xAD) ) - { - val= I2CreadByte(APDS9960_I2C_ADDR, reg); - if(val==ERROR){ - printf("ERROR"); - } - /* - print(reg, HEX); - print(": 0x"); - println(val, HEX);*/ - } - } - - for(reg = 0xE4; reg <= 0xE7; reg++) { - val= I2CreadByte(APDS9960_I2C_ADDR, reg); - /* Serial.print(reg, HEX); - Serial.print(": 0x"); - Serial.println(val, HEX);*/ - } -#endif +//#if 0 +// /* Gesture config register dump */ +// uint8_t reg; +// uint8_t val; +// +// for(reg = 0x80; reg <= 0xAF; reg++) { +// if( (reg != 0x82) && \ +// (reg != 0x8A) && \ +// (reg != 0x91) && \ +// (reg != 0xA8) && \ +// (reg != 0xAC) && \ +// (reg != 0xAD) ) +// { +// val= I2CreadByte(APDS9960_I2C_ADDR, reg); +// if(val==ERROR){ +// printf("ERROR"); +// } +// /* +// print(reg, HEX); +// print(": 0x"); +// println(val, HEX);*/ +// } +// } +// +// for(reg = 0xE4; reg <= 0xE7; reg++) { +// val= I2CreadByte(APDS9960_I2C_ADDR, reg); +// /* Serial.print(reg, HEX); +// Serial.print(": 0x"); +// Serial.println(val, HEX);*/ +// } +//#endif // return true; -//} + @@ -421,7 +418,11 @@ uint8_t fifo_level = 0; // uint8_t bytes_expected= 0; int check; - uint8_t fifo_data[128]; + //char fifo_data[128]; + char fifo_data[128]; + char *fptr; + fptr= fifo_data; + uint8_t gstatus; int motion; int i; @@ -462,7 +463,7 @@ if( fifo_level > 0) { check = I2CReadDataBlock(APDS9960_I2C_ADDR,APDS9960_GFIFO_U, - (uint8_t*)fifo_data, + fptr, (fifo_level * 4) ); if( check == -1 ) { @@ -530,6 +531,7 @@ return motion; } } + // delete fptr; } /** * Turn the APDS-9960 on @@ -1009,6 +1011,12 @@ return val; } + /** + * @brief Sets the lower threshold for proximity detection + * + * @param[in] threshold the lower proximity threshold + * @return True if operation successful. False otherwise. + */ bool glibr::setProxIntLowThresh(uint8_t threshold) { if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT, threshold) ) { @@ -1018,6 +1026,30 @@ return true; } +/** + * @brief Returns the high threshold for proximity detection + * + * @return high threshold + */ +uint8_t glibr::getProxIntHighThresh() +{ + uint8_t val; + + /* Read value from PIHT register */ + val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PILT); + if( val==ERROR ) { + val = 0; + } + + return val; +} + +/** + * @brief Sets the high threshold for proximity detection + * + * @param[in] threshold the high proximity threshold + * @return True if operation successful. False otherwise. + */ bool glibr::setProxIntHighThresh(uint8_t threshold) { @@ -1028,19 +1060,57 @@ return true; } + /** + * @brief Returns LED drive strength for proximity and ALS + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @return the value of the LED drive strength. 0xFF on failure. + */ +uint8_t glibr::getLEDDrive() +{ + uint8_t val; + + /* Read value from CONTROL register */ + val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL); + if( val == ERROR ){//!wireReadDataByte(APDS9960_CONTROL, val) ) { + return ERROR; + } + + /* Shift and mask out LED drive bits */ + val = (val >> 6) & 0x03;//0b00000011; + + return val; +} + /** + * @brief Sets the LED drive strength for proximity and ALS + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @param[in] drive the value (0-3) for the LED drive strength + * @return True if operation successful. False otherwise. + */ bool glibr::setLEDDrive(uint8_t drive) { uint8_t val; /* Read value from CONTROL register */ - val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL); if(val==ERROR){ return false; } /* Set bits in register to given value */ + //drive &= 0b00000011 drive &= 0x03; drive = drive << 6; //val &= 0b00111111; @@ -1055,8 +1125,45 @@ return true; } +/** + * @brief Returns receiver gain for proximity detection + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @return the value of the proximity gain. 0xFF on failure. + */ +uint8_t glibr::getProximityGain() +{ + uint8_t val; + + /* Read value from CONTROL register */ + val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) { + return ERROR; + } + + /* Shift and mask out PDRIVE bits */ + val = (val >> 2) & 0x03;//0b00000011; + + return val; +} - +/** + * @brief Sets the receiver gain for proximity detection + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @param[in] drive the value (0-3) for the gain + * @return True if operation successful. False otherwise. + */ bool glibr::setProximityGain(uint8_t drive) { uint8_t val; @@ -1072,6 +1179,7 @@ //drive &= 0b00000011; drive &=0x03; drive = drive << 2; + //val &= 0b11110011 val &= 0xF3; val |= drive; @@ -1082,9 +1190,47 @@ return true; } +/** + * @brief Returns receiver gain for the ambient light sensor (ALS) + * + * Value Gain + * 0 1x + * 1 4x + * 2 16x + * 3 64x + * + * @return the value of the ALS gain. 0xFF on failure. + */ +uint8_t glibr::getAmbientLightGain() +{ + uint8_t val; + + /* Read value from CONTROL register */ + val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) { + return ERROR; + } + + /* Shift and mask out ADRIVE bits */ + val &= 0x03;//0b00000011; + + return val; +} +/** + * @brief Sets the receiver gain for the ambient light sensor (ALS) + * + * Value Gain + * 0 1x + * 1 4x + * 2 16x + * 3 64x + * + * @param[in] drive the value (0-3) for the gain + * @return True if operation successful. False otherwise. + */ bool glibr::setAmbientLightGain(uint8_t drive){ -{ + uint8_t val; /* Read value from CONTROL register */ @@ -1098,6 +1244,7 @@ //drive &= 0b00000011; drive &=0x03; drive = drive << 2; + //val &=0b11111100 val &= 0xF3; val |= drive; @@ -1108,7 +1255,500 @@ return true; } +/** + * @brief Get the current LED boost value + * + * Value Boost Current + * 0 100% + * 1 150% + * 2 200% + * 3 300% + * + * @return The LED boost value. 0xFF on failure. + */ +uint8_t glibr::getLEDBoost() { + uint8_t val; + + /* Read value from CONFIG2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) { + return ERROR; + } + + /* Shift and mask out LED_BOOST bits */ + val = (val >> 4) & 0x03;//0b00000011; + + return val; +} +/** + * @brief Sets the LED current boost value + * + * Value Boost Current + * 0 100% + * 1 150% + * 2 200% + * 3 300% + * + * @param[in] drive the value (0-3) for current boost (100-300%) + * @return True if operation successful. False otherwise. + */ +bool glibr::setLEDBoost(uint8_t boost) +{ + uint8_t val; + + /* Read value from CONFIG2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) { + return false; + } + + /* Set bits in register to given value */ + boost &= 0x03;//0b00000011; + boost = boost << 4; + val &= 0xCF;//0b11001111; + val |= boost; + + /* Write register value back into CONFIG2 register */ + + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG2, val)){//!wireWriteDataByte(APDS9960_CONFIG2, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets proximity gain compensation enable + * + * @return 1 if compensation is enabled. 0 if not. 0xFF on error. + */ +uint8_t glibr::getProxGainCompEnable() +{ + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) { + return ERROR; + } + + /* Shift and mask out PCMP bits */ + val = (val >> 5) & 0x01;//0b00000001; + + return val; +} + +/** + * @brief Sets the proximity gain compensation enable + * + * @param[in] enable 1 to enable compensation. 0 to disable compensation. + * @return True if operation successful. False otherwise. + */ + bool glibr::setProxGainCompEnable(uint8_t enable) +{ + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) { + return false; + } + + /* Set bits in register to given value */ + enable &= 0x01;//0b00000001; + enable = enable << 5; + val &= 0xCF;//0b11011111; + val |= enable; + + /* Write register value back into CONFIG3 register */ + + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG3, val)){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the current mask for enabled/disabled proximity photodiodes + * + * 1 = disabled, 0 = enabled + * Bit Photodiode + * 3 UP + * 2 DOWN + * 1 LEFT + * 0 RIGHT + * + * @return Current proximity mask for photodiodes. 0xFF on error. + */ +uint8_t glibr::getProxPhotoMask() +{ + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) { + return ERROR; + } + + /* Mask out photodiode enable mask bits */ + val &= 0x0F;//0b00001111; + + return val; +} + +/** + * @brief Sets the mask for enabling/disabling proximity photodiodes + * + * 1 = disabled, 0 = enabled + * Bit Photodiode + * 3 UP + * 2 DOWN + * 1 LEFT + * 0 RIGHT + * + * @param[in] mask 4-bit mask value + * @return True if operation successful. False otherwise. + */ +bool glibr::setProxPhotoMask(uint8_t mask) +{ + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) { + return false; + } + + /* Set bits in register to given value */ + mask &= 0x0F;//0b00001111; + val &= 0xF0;//0b11110000; + val |= mask; + + /* Write register value back into CONFIG3 register */ + I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val); + if( val == ERROR){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the entry proximity threshold for gesture sensing + * + * @return Current entry proximity threshold. + */ +uint8_t glibr::getGestureEnterThresh() +{ + uint8_t val; + + /* Read value from GPENTH register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GPENTH); + if( val == ERROR){//!wireReadDataByte(APDS9960_GPENTH, val) ) { + val = 0; + } + + return val; +} + +/** + * @brief Sets the entry proximity threshold for gesture sensing + * + * @param[in] threshold proximity value needed to start gesture mode + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureEnterThresh(uint8_t threshold) +{ + + if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GPENTH, threshold)){;//!wireWriteDataByte(APDS9960_GPENTH, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the exit proximity threshold for gesture sensing + * + * @return Current exit proximity threshold. + */ +uint8_t glibr::getGestureExitThresh() +{ + uint8_t val; + + /* Read value from GEXTH register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GEXTH); + if( val == ERROR){//!wireReadDataByte(APDS9960_GEXTH, val) ) { + val = 0; + } + + return val; +} + +/** + * @brief Sets the exit proximity threshold for gesture sensing + * + * @param[in] threshold proximity value needed to end gesture mode + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureExitThresh(uint8_t threshold) +{ + if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GEXTH, threshold)){//!wireWriteDataByte(APDS9960_GEXTH, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the gain of the photodiode during gesture mode + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @return the current photodiode gain. 0xFF on error. + */ +uint8_t glibr::getGestureGain() +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return ERROR; + } + + /* Shift and mask out GGAIN bits */ + val = (val >> 5) & 0x03;//0b00000011; + + return val; +} + +/** + * @brief Sets the gain of the photodiode during gesture mode + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @param[in] gain the value for the photodiode gain + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureGain(uint8_t gain) +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return false; + } + + /* Set bits in register to given value */ + gain &= 0x03;//0b00000011; + gain = gain << 5; + val &= 0x9F;//0b10011111; + val |= gain; + + /* Write register value back into GCONF2 register */ + if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the drive current of the LED during gesture mode + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @return the LED drive current value. 0xFF on error. + */ +uint8_t glibr::getGestureLEDDrive() +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return ERROR; + } + + /* Shift and mask out GLDRIVE bits */ + val = (val >> 3) & 0x03;//0b00000011; + + return val; +} + +/** + * @brief Sets the LED drive current during gesture mode + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @param[in] drive the value for the LED drive current + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureLEDDrive(uint8_t drive) +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return false; + } + + /* Set bits in register to given value */ + drive &= 0x03;//0b00000011; + drive = drive << 3; + val &= 0xE7;//0b11100111; + val |= drive; + + /* Write register value back into GCONF2 register */ + if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the time in low power mode between gesture detections + * + * Value Wait time + * 0 0 ms + * 1 2.8 ms + * 2 5.6 ms + * 3 8.4 ms + * 4 14.0 ms + * 5 22.4 ms + * 6 30.8 ms + * 7 39.2 ms + * + * @return the current wait time between gestures. 0xFF on error. + */ +uint8_t glibr::getGestureWaitTime() +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return ERROR; + } + + /* Mask out GWTIME bits */ + val &= 0x07;//0b00000111; + + return val; +} + +/* +* +* +* +*LEFT OFF HERE AT 3:47PM ON 3/6/15 +* +* +* +* +*/ + + +/** + * @brief Sets the time in low power mode between gesture detections + * + * Value Wait time + * 0 0 ms + * 1 2.8 ms + * 2 5.6 ms + * 3 8.4 ms + * 4 14.0 ms + * 5 22.4 ms + * 6 30.8 ms + * 7 39.2 ms + * + * @param[in] the value for the wait time + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureWaitTime(uint8_t time) +{ + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) { + return false; + } + /* if( !wireReadDataByte(APDS9960_GCONF2, val) ) { + return false; + } */ + + /* Set bits in register to given value */ + time &= 0x07;//0b00000111; + val &= 0xF8;//0b11111000; + val |= time; + + /* Write register value back into GCONF2 register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF2,val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) { + return false; + } + /*if( !wireWriteDataByte(APDS9960_GCONF2, val) ) { + return false; + }*/ + return true; +} + +/** + * @brief Gets the low threshold for ambient light interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + * @return True if operation successful. False otherwise. + */ +bool glibr::getLightIntLowThreshold(uint16_t &threshold) +{ + uint8_t val_byte; + threshold = 0; + + /* Read value from ambient light low threshold, low byte register */ + val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTL); + if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTL, val_byte) ) { + return false; + } + threshold = val_byte; + + /* Read value from ambient light low threshold, high byte register */ + val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTH); + if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTH, val_byte) ) { + return false; + } + threshold = threshold + ((uint16_t)val_byte << 8); + + return true; +} + +/** + * @brief Sets the low threshold for ambient light interrupts + * + * @param[in] threshold low threshold value for interrupt to trigger + * @return True if operation successful. False otherwise. + */ bool glibr::setLightIntLowThreshold(uint16_t threshold) { uint8_t val_low; @@ -1119,12 +1759,375 @@ val_high = (threshold & 0xFF00) >> 8; /* Write low byte */ - if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTL, val_low) ) { + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTL,val_low)){//!wireWriteDataByte(APDS9960_AILTL, val_low) ) { + return false; + } + + /* Write high byte */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTH,val_high)){//!wireWriteDataByte(APDS9960_AILTH, val_high) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the high threshold for ambient light interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + * @return True if operation successful. False otherwise. + */ +bool glibr::getLightIntHighThreshold(uint16_t &threshold) +{ + uint8_t val_byte; + threshold = 0; + + /* Read value from ambient light high threshold, low byte register */ + val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTL); + if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTL, val_byte) ) { + return false; + } + threshold = val_byte; + + /* Read value from ambient light high threshold, high byte register */ + val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTH); + if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTH, val_byte) ) { + return false; + } + threshold = threshold + ((uint16_t)val_byte << 8); + + return true; +} + +/** + * @brief Sets the high threshold for ambient light interrupts + * + * @param[in] threshold high threshold value for interrupt to trigger + * @return True if operation successful. False otherwise. + */ +bool glibr::setLightIntHighThreshold(uint16_t threshold) +{ + uint8_t val_low; + uint8_t val_high; + + /* Break 16-bit threshold into 2 8-bit values */ + val_low = threshold & 0x00FF; + val_high = (threshold & 0xFF00) >> 8; + + /* Write low byte */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTL,val_low)){//!wireWriteDataByte(APDS9960_AIHTL, val_low) ) { return false; } /* Write high byte */ - if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTH, val_high) ) { + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTH,val_high)){//!wireWriteDataByte(APDS9960_AIHTH, val_high) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the low threshold for proximity interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + * @return True if operation successful. False otherwise. + */ +bool glibr::getProximityIntLowThreshold(uint8_t &threshold) +{ + threshold = 0; + + /* Read value from proximity low threshold register */ + threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PILT); + if( threshold == ERROR){//!wireReadDataByte(APDS9960_PILT, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Sets the low threshold for proximity interrupts + * + * @param[in] threshold low threshold value for interrupt to trigger + * @return True if operation successful. False otherwise. + */ +bool glibr::setProximityIntLowThreshold(uint8_t threshold) +{ + + /* Write threshold value to register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT,threshold)){//!wireWriteDataByte(APDS9960_PILT, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Gets the high threshold for proximity interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + * @return True if operation successful. False otherwise. + */ +bool glibr::getProximityIntHighThreshold(uint8_t &threshold) +{ + threshold = 0; + + /* Read value from proximity low threshold register */ + threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PIHT); + if( threshold == ERROR){//!wireReadDataByte(APDS9960_PIHT, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Sets the high threshold for proximity interrupts + * + * @param[in] threshold high threshold value for interrupt to trigger + * @return True if operation successful. False otherwise. + */ +bool glibr::setProximityIntHighThreshold(uint8_t threshold) +{ + + /* Write threshold value to register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PIHT,threshold)){//!wireWriteDataByte(APDS9960_PIHT, threshold) ) { + return false; + } + + return true; +} + +/** + * @brief Gets if ambient light interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t glibr::getAmbientLightIntEnable() +{ + uint8_t val; + + /* Read value from ENABLE register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE); + if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) { + return ERROR; + } + + /* Shift and mask out AIEN bit */ + val = (val >> 4) & 0x01;//0b00000001; + + return val; +} + +/** + * @brief Turns ambient light interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + * @return True if operation successful. False otherwise. + */ +bool glibr::setAmbientLightIntEnable(uint8_t enable) +{ + uint8_t val; + + /* Read value from ENABLE register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE); + if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) { + return false; + } + + /* Set bits in register to given value */ + enable &= 0x01;//0b00000001; + enable = enable << 4; + val &= 0xEF;//0b11101111; + val |= enable; + + /* Write register value back into ENABLE register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets if proximity interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t glibr::getProximityIntEnable() +{ + uint8_t val; + + /* Read value from ENABLE register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE); + if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) { + return ERROR; + } + + /* Shift and mask out PIEN bit */ + val = (val >> 5) & 0x01;//0b00000001; + + return val; +} + +/** + * @brief Turns proximity interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + * @return True if operation successful. False otherwise. + */ +bool glibr::setProximityIntEnable(uint8_t enable) +{ + uint8_t val; + + /* Read value from ENABLE register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE); + if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) { + return false; + } + + /* Set bits in register to given value */ + enable &= 0x01;//0b00000001; + enable = enable << 5; + val &= 0xDF;//0b11011111; + val |= enable; + + /* Write register value back into ENABLE register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) { + return false; + } + + return true; +} + +/** + * @brief Gets if gesture interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t glibr::getGestureIntEnable() +{ + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) { + return ERROR; + } + + /* Shift and mask out GIEN bit */ + val = (val >> 1) & 0x01;//0b00000001; + + return val; +} + +/** + * @brief Turns gesture-related interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureIntEnable(uint8_t enable) +{ + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) { + return false; + } + + /* Set bits in register to given value */ + enable &= 0x01;//0b00000001; + enable = enable << 1; + val &= 0xFD;//0b11111101; + val |= enable; + + /* Write register value back into GCONF4 register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) { + return false; + } + + return true; +} + +/** + * @brief Clears the ambient light interrupt + * + * @return True if operation completed successfully. False otherwise. + */ +bool glibr::clearAmbientLightInt() +{ + uint8_t throwaway; + throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AICLEAR); + if( throwaway == ERROR){//!wireReadDataByte(APDS9960_AICLEAR, throwaway) ) { + return false; + } + + return true; +} + +/** + * @brief Clears the proximity interrupt + * + * @return True if operation completed successfully. False otherwise. + */ +bool glibr::clearProximityInt() +{ + uint8_t throwaway; + throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PICLEAR); + if( throwaway == ERROR){//!wireReadDataByte(APDS9960_PICLEAR, throwaway) ) { + return false; + } + + return true; +} + +/** + * @brief Tells if the gesture state machine is currently running + * + * @return 1 if gesture state machine is running, 0 if not. 0xFF on error. + */ +uint8_t glibr::getGestureMode() +{ + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) { + return ERROR; + } + + /* Mask out GMODE bit */ + val &= 0x01;//0b00000001; + + return val; +} + +/** + * @brief Tells the state machine to either enter or exit gesture state machine + * + * @param[in] mode 1 to enter gesture state machine, 0 to exit. + * @return True if operation successful. False otherwise. + */ +bool glibr::setGestureMode(uint8_t mode) +{ + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4); + if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) { + return false; + } + + /* Set bits in register to given value */ + mode &= 0x01;//0b00000001; + val &= 0xFE;//0b11111110; + val |= mode; + + /* Write register value back into GCONF4 register */ + if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) { return false; } @@ -1157,27 +2160,27 @@ } -/** - * @brief Reads a block (array) of bytes from the I2C device and register - * - * @param[in] reg the register to read from - * @param[out] val pointer to the beginning of the data - * @param[in] len number of bytes to read - * @return Number of bytes read. -1 on read error. - */ -int glibr::I2CReadDataBlock(char address, char subAddress, uint8_t *val, unsigned int len) + +// * @brief Reads a block (array) of bytes from the I2C device and register +// * +// * @param[in] reg the register to read from +// * @param[out] val pointer to the beginning of the data +// * @param[in] len number of bytes to read +// * @return Number of bytes read. -1 on read error. +// */ +int glibr::I2CReadDataBlock(char address, char subAddress, char *data, unsigned int len) { // unsigned char i = 0; /* Indicate which register we want to read from */ - if(i2c.write(address<<1, subAddress, 1, true)){ + if(i2c.write(address<<1, &subAddress, 1, true)){ return -1; //7 bit //not acked } /* Read block data */ - if(i2c.read(address<<1, &val, len)){ + if(i2c.read(address<<1, data, len)){ return -1; }