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

Revision:
9:286d00d9db80
Parent:
8:6fa15d4e31fb
Child:
10:e8adab2fb829
--- 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;
     }