涂 桂旺 / APDS_9960

Fork of APDS_9960 by Krishan Bhagat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers glibr.cpp Source File

glibr.cpp

00001 #include "glibr.h"
00002 #include "mbed.h"
00003 
00004 
00005 
00006 
00007 glibr::glibr(PinName sda, PinName scl):i2c(sda, scl){
00008           gesture_ud_delta_ = 0;
00009     gesture_lr_delta_ = 0;
00010     
00011     gesture_ud_count_ = 0;
00012     gesture_lr_count_ = 0;
00013     
00014     gesture_near_count_ = 0;
00015     gesture_far_count_ = 0;
00016     
00017     gesture_state_ = 0;
00018     gesture_motion_ = DIR_NONE;
00019 }    
00020    
00021 glibr::~glibr(){
00022        
00023 } 
00024 
00025  bool  glibr::ginit(){
00026     uint8_t id;
00027         
00028      id=I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ID);
00029     
00030     if( (!(id == APDS9960_ID_1 || id == APDS9960_ID_2 || id == APDS9960_ID_3))||id==ERROR) {
00031          return false;
00032     }
00033     
00034     if(!setMode(ALL, Off)) {
00035         return false;
00036     }
00037     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ATIME, DEFAULT_ATIME)){
00038         return false;
00039     }
00040     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_WTIME, DEFAULT_WTIME)){
00041         return false;
00042     }
00043     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PPULSE, DEFAULT_PROX_PPULSE)){
00044         return false;
00045     }
00046     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR)){
00047         return false;
00048     }
00049     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL)){
00050         return false;
00051     }
00052     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG1, DEFAULT_CONFIG1)){
00053         return false;
00054     }
00055     
00056     if( !setLEDDrive(DEFAULT_LDRIVE) ) {
00057         return false;
00058     }
00059     
00060     if( !setProximityGain(DEFAULT_PGAIN) ) {
00061         return false;
00062     }
00063     if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
00064         return false;
00065     }
00066     if( !setProxIntLowThresh(DEFAULT_PILT) ) {
00067         return false;
00068     }
00069     if( !setProxIntHighThresh(DEFAULT_PIHT) ) {
00070         return false;
00071     }
00072     if( !setLightIntLowThreshold(DEFAULT_AILT) ) {
00073         return false;
00074     }
00075     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG2, DEFAULT_CONFIG2) ) {
00076         return false;
00077     }
00078     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG3, DEFAULT_CONFIG3) ) {
00079         return false;
00080     }
00081     
00082     if( !setGestureEnterThresh(DEFAULT_GPENTH) ) {
00083         return false;
00084     }
00085     if( !setGestureExitThresh(DEFAULT_GEXTH) ) {
00086         return false;
00087     }
00088     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF1, DEFAULT_GCONF1) ) {
00089         return false;
00090     }
00091     if( !setGestureGain(DEFAULT_GGAIN) ) {
00092         return false;
00093     }
00094     if( !setGestureLEDDrive(DEFAULT_GLDRIVE) ) {
00095         return false;
00096     }
00097     if( !setGestureWaitTime(DEFAULT_GWTIME) ) {
00098         return false;
00099     }
00100     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) {
00101         return false;
00102     }
00103     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) {
00104         return false;
00105     }
00106     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) {
00107         return false;
00108     }
00109     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) {
00110         return false;
00111     }
00112     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GPULSE, DEFAULT_GPULSE) ) {
00113         return false;
00114     }
00115     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF3, DEFAULT_GCONF3) ) {
00116         return false;
00117     }
00118     if( !setGestureIntEnable(DEFAULT_GIEN) ) {
00119         return false;
00120     }
00121     
00122     return true;
00123     
00124 }
00125 
00126 //#if 0
00127 //    /* Gesture config register dump */
00128 //    uint8_t reg;
00129 //    uint8_t val;
00130 //  
00131 //    for(reg = 0x80; reg <= 0xAF; reg++) {
00132 //        if( (reg != 0x82) && \
00133 //            (reg != 0x8A) && \
00134 //            (reg != 0x91) && \
00135 //            (reg != 0xA8) && \
00136 //            (reg != 0xAC) && \
00137 //            (reg != 0xAD) )
00138 //        {
00139 //         val= I2CreadByte(APDS9960_I2C_ADDR, reg);
00140 //          if(val==ERROR){
00141 //              printf("ERROR");
00142 //          }
00143 //            /*
00144 //            print(reg, HEX);
00145 //            print(": 0x");
00146 //            println(val, HEX);*/
00147 //        }
00148 //    }
00149 //
00150 //    for(reg = 0xE4; reg <= 0xE7; reg++) {
00151 //        val= I2CreadByte(APDS9960_I2C_ADDR, reg);
00152 //     /*   Serial.print(reg, HEX);
00153 //        Serial.print(": 0x");
00154 //        Serial.println(val, HEX);*/
00155 //    }
00156 //#endif 
00157 
00158   //  return true;
00159  
00160 
00161 
00162 
00163 /**
00164  * @brief Enables or disables a feature in the APDS-9960
00165  *
00166  * @param[in] mode which feature to enable
00167  * @param[in] enable On (1) or Off (0)
00168  * @return True if operation success. False otherwise.
00169  */
00170 bool glibr::setMode(uint8_t mode, uint8_t enable)
00171 {
00172     uint8_t reg_val;
00173 
00174     /* Read current ENABLE register */
00175     reg_val = getMode();
00176     if( reg_val == ERROR ) {
00177         return false;
00178     }
00179     
00180     /* Change bit(s) in ENABLE register */
00181     enable = enable & 0x01;
00182     if( mode >= 0 && mode <= 6 ) {
00183         if (enable) {
00184             reg_val |= (1 << mode);
00185         } else {
00186             reg_val &= ~(1 << mode);
00187         }
00188     } else if( mode == ALL ) {
00189         if (enable) {
00190             reg_val = 0x7F;
00191         } else {
00192             reg_val = 0x00;
00193         }
00194     }
00195     
00196     /* Write value back to ENABLE register */     
00197     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE, reg_val)){
00198         return false;
00199     }
00200    
00201 
00202         
00203     return true;
00204 }
00205 
00206 uint8_t glibr::getMode()
00207 {
00208     uint8_t val;
00209     val= I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
00210     if(val==ERROR){
00211         return ERROR;
00212     }
00213     return val;
00214 }
00215 
00216 
00217 
00218 bool glibr::enableLightSensor(bool interrupts)
00219 {
00220     
00221     /* Set default gain, interrupts, enable power, and enable sensor */
00222     if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
00223         return false;
00224     }
00225     if( interrupts ) {
00226         if( !setAmbientLightIntEnable(1) ) {
00227             return false;
00228         }
00229     } else {
00230         if( !setAmbientLightIntEnable(0) ) {
00231             return false;
00232         }
00233     }
00234     if( !enablePower() ){
00235         return false;
00236     }
00237     if( !setMode(AMBIENT_LIGHT, 1) ) {
00238         return false;
00239     }
00240     
00241     return true;
00242 
00243 }
00244 
00245 /**
00246  * @brief Ends the light sensor on the APDS-9960
00247  *
00248  * @return True if sensor disabled correctly. False on error.
00249  */
00250 bool glibr::disableLightSensor()
00251 {
00252     if( !setAmbientLightIntEnable(0) ) {
00253         return false;
00254     }
00255     if( !setMode(AMBIENT_LIGHT, 0) ) {
00256         return false;
00257     }
00258     
00259     return true;
00260 }
00261 
00262 /**
00263  * @brief Starts the proximity sensor on the APDS-9960
00264  *
00265  * @param[in] interrupts true to enable hardware external interrupt on proximity
00266  * @return True if sensor enabled correctly. False on error.
00267  */
00268 bool glibr::enableProximitySensor(bool interrupts)
00269 {
00270     /* Set default gain, LED, interrupts, enable power, and enable sensor */
00271     if( !setProximityGain(DEFAULT_PGAIN) ) {
00272         return false;
00273     }
00274     if( !setLEDDrive(DEFAULT_LDRIVE) ) {
00275         return false;
00276     }
00277     if( interrupts ) {
00278         if( !setProximityIntEnable(1) ) {
00279             return false;
00280         }
00281     } else {
00282         if( !setProximityIntEnable(0) ) {
00283             return false;
00284         }
00285     }
00286     if( !enablePower() ){
00287         return false;
00288     }
00289     if( !setMode(PROXIMITY, 1) ) {
00290         return false;
00291     }
00292     
00293     return true;
00294 }
00295 
00296 /**
00297  * @brief Ends the proximity sensor on the APDS-9960
00298  *
00299  * @return True if sensor disabled correctly. False on error.
00300  */
00301 bool glibr::disableProximitySensor()
00302 {
00303     if( !setProximityIntEnable(0) ) {
00304         return false;
00305     }
00306     if( !setMode(PROXIMITY, 0) ) {
00307         return false;
00308     }
00309 
00310     return true;
00311 }
00312 
00313 
00314 /**
00315  * @brief Starts the gesture recognition engine on the APDS-9960
00316  *
00317  * @param[in] interrupts true to enable hardware external interrupt on gesture
00318  * @return True if engine enabled correctly. False on error.
00319  */
00320 bool glibr::enableGestureSensor(bool interrupts)
00321 {
00322     
00323     /* Enable gesture mode
00324        Set ENABLE to 0 (power off)
00325        Set WTIME to 0xFF
00326        Set AUX to LED_BOOST_300
00327        Enable PON, WEN, PEN, GEN in ENABLE 
00328     */
00329 
00330     resetGestureParameters();
00331     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_WTIME, 0xFF) ) {
00332         return false;
00333     }
00334     if(I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) {
00335         return false;
00336     }
00337     if( !setLEDBoost(LED_BOOST_300) ) {
00338         return false;
00339     }
00340     if( interrupts ) {
00341         if( !setGestureIntEnable(1) ) {
00342             return false;
00343         }
00344     } else {
00345         if( !setGestureIntEnable(0) ) {
00346             return false;
00347         }
00348     }
00349     if( !setGestureMode(1) ) {
00350         return false;
00351     }
00352     if( !enablePower() ){
00353         return false;
00354     }
00355     if( !setMode(WAIT, 1) ) {
00356         return false;
00357     }
00358     if( !setMode(PROXIMITY, 1) ) {
00359         return false;
00360     }
00361     if( !setMode(GESTURE, 1) ) {
00362         return false;
00363     }
00364     
00365     return true;
00366 }
00367 
00368 /**
00369  * @brief Ends the gesture recognition engine on the APDS-9960
00370  *
00371  * @return True if engine disabled correctly. False on error.
00372  */
00373 bool glibr::disableGestureSensor()
00374 {
00375     resetGestureParameters();
00376     if( !setGestureIntEnable(0) ) {
00377         return false;
00378     }
00379     if( !setGestureMode(0) ) {
00380         return false;
00381     }
00382     if( !setMode(GESTURE, 0) ) {
00383         return false;
00384     }
00385     
00386     return true;
00387 }
00388 
00389 
00390 /**
00391  * @brief Determines if there is a gesture available for reading
00392  *
00393  * @return True if gesture available. False otherwise.
00394  */
00395 bool glibr::isGestureAvailable()
00396 {
00397     uint8_t val;
00398     
00399     /* Read value from GSTATUS register */
00400     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GSTATUS);
00401     if( val==ERROR) {
00402         return ERROR;
00403     }
00404     
00405     /* Shift and mask out GVALID bit */
00406     val &= APDS9960_GVALID;
00407     
00408     /* Return true/false based on GVALID bit */
00409     if( val == 1) {
00410         return true;
00411     } else {
00412         return false;
00413     }
00414 }
00415 
00416 int glibr::readGesture()
00417 {
00418     uint8_t fifo_level = 0;
00419    // uint8_t bytes_expected= 0;
00420     int check;
00421     //char fifo_data[128];
00422     char fifo_data[128];
00423    char *fptr;
00424    fptr= fifo_data;
00425     
00426     uint8_t gstatus;
00427     int motion;
00428     int i;
00429     
00430     /* Make sure that power and gesture is on and data is valid */
00431     if( !isGestureAvailable() || !(getMode() & 0x41) ) {
00432         return DIR_NONE;
00433     }
00434 
00435     
00436     /* Keep looping as long as gesture data is valid */
00437     while(1) {
00438       
00439         /* Wait some time to collect next batch of FIFO data */
00440         wait(FIFO_PAUSE_TIME);
00441         
00442         /* Get the contents of the STATUS register. Is data still valid? */
00443           
00444         gstatus=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GSTATUS);
00445         if( gstatus==ERROR ) {
00446             return ERROR;
00447         }
00448         /* If we have valid data, read in FIFO */
00449         if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) {
00450         
00451             /* Read the current FIFO level */
00452             fifo_level=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GFLVL);
00453             if( fifo_level==ERROR ) {
00454                 return ERROR;
00455             }
00456             
00457 //#if DEBUG
00458 //            Serial.print("FIFO Level: ");
00459 //            Serial.println(fifo_level);
00460 //#endif
00461 
00462             /* If there's stuff in the FIFO, read it into our data block */                 //NEED TO FIGURE OUT WHAT THIS IS DOING.
00463         
00464             if( fifo_level > 0) {
00465                 check = I2CReadDataBlock(APDS9960_I2C_ADDR,APDS9960_GFIFO_U, 
00466                                                 fptr, 
00467                                                 (fifo_level * 4) );
00468                 
00469                 if( check == -1 ) {
00470                     return ERROR;
00471                 }
00472                 
00473 #if DEBUG
00474                 //Serial.print("FIFO Dump: ");
00475                 for ( i = 0; i < (fifo_level * 4); i++ ) {
00476                  //   Serial.print(fifo_data[i]);
00477                   //  Serial.print(" ");
00478                 }
00479                 //Serial.println();
00480 #endif
00481 
00482                 /* If at least 1 set of data, sort the data into U/D/L/R */
00483                 if((fifo_level * 4)  >= 4 ) {
00484                     for( i = 0; i < (fifo_level * 4); i += 4 ) {
00485                         gesture_data_.u_data[gesture_data_.sindex] = \
00486                                                             fifo_data[i + 0];
00487                         gesture_data_.d_data[gesture_data_.sindex] = \
00488                                                             fifo_data[i + 1];
00489                         gesture_data_.l_data[gesture_data_.sindex] = \
00490                                                             fifo_data[i + 2];
00491                         gesture_data_.r_data[gesture_data_.sindex] = \
00492                                                             fifo_data[i + 3];
00493                         gesture_data_.sindex++;
00494                         gesture_data_.total_gestures++;
00495                     }
00496                     
00497 #if DEBUG
00498                // Serial.print("Up Data: ");
00499                 for ( i = 0; i < gesture_data_.total_gestures; i++ ) {
00500                  //   Serial.print(gesture_data_.u_data[i]);
00501                   //  Serial.print(" ");
00502                 }
00503               //  Serial.println();
00504 #endif
00505 
00506                     /* Filter and process gesture data. Decode near/far state */
00507                     if( processGestureData() ) {
00508                         if( decodeGesture() ) {
00509                             //***TODO: U-Turn Gestures
00510 #if DEBUG
00511                             //Serial.println(gesture_motion_);
00512 #endif
00513                         }
00514                     }
00515                     
00516                     /* Reset data */
00517                     gesture_data_.sindex = 0;
00518                     gesture_data_.total_gestures = 0;
00519                 }
00520             }
00521         } else {
00522     
00523             /* Determine best guessed gesture and clean up */
00524             wait(FIFO_PAUSE_TIME);
00525             decodeGesture();
00526             motion = gesture_motion_;
00527 #if DEBUG
00528         //    Serial.print("END: ");
00529         //    Serial.println(gesture_motion_);
00530 #endif
00531             resetGestureParameters();
00532             return motion;
00533         }
00534     }
00535    // delete fptr;
00536 }
00537 /**
00538  * Turn the APDS-9960 on
00539  *
00540  * @return True if operation successful. False otherwise.
00541  */
00542 bool glibr::enablePower()
00543 {
00544     if( !setMode(Power, 1) ) {
00545         return false;
00546     }
00547     
00548     return true;
00549 }
00550 
00551 /**
00552  * Turn the APDS-9960 off
00553  *
00554  * @return True if operation successful. False otherwise.
00555  */
00556 bool glibr::disablePower()
00557 {
00558     if( !setMode(Power, 0) ) {
00559         return false;
00560     }
00561     
00562     return true;
00563 }
00564 
00565 /*******************************************************************************
00566  * Ambient light and color sensor controls
00567  ******************************************************************************/
00568 
00569 /**
00570  * @brief Reads the ambient (clear) light level as a 16-bit value
00571  *
00572  * @param[out] val value of the light sensor.
00573  * @return True if operation successful. False otherwise.
00574  */
00575 bool glibr::readAmbientLight(uint16_t &val)
00576 {
00577     uint8_t val_byte;
00578     val = 0;
00579     
00580     /* Read value from clear channel, low byte register */
00581     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CDATAL);
00582     if( val_byte==ERROR) {
00583         return false;
00584     }
00585     val = val_byte;
00586     
00587     /* Read value from clear channel, high byte register */
00588    
00589     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CDATAH);
00590     if( val_byte==ERROR) {
00591         return false;
00592     }
00593     val = val + ((uint16_t)val_byte << 8);
00594     return true;
00595 }
00596 
00597 /**
00598  * @brief Reads the red light level as a 16-bit value
00599  *
00600  * @param[out] val value of the light sensor.
00601  * @return True if operation successful. False otherwise.
00602  */
00603 bool glibr::readRedLight(uint16_t &val)
00604 {
00605     uint8_t val_byte;
00606     val = 0;
00607     
00608     /* Read value from clear channel, low byte register */
00609     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_RDATAL);
00610     if( val_byte==ERROR) {
00611         return false;
00612     }
00613     
00614     val = val_byte;
00615     
00616     /* Read value from clear channel, high byte register */
00617     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_RDATAH);
00618     if( val_byte==ERROR) {
00619         return false;
00620     }
00621     val = val + ((uint16_t)val_byte << 8);
00622     
00623     return true;
00624 }
00625 
00626 /**
00627  * @brief Reads the green light level as a 16-bit value
00628  *
00629  * @param[out] val value of the light sensor.
00630  * @return True if operation successful. False otherwise.
00631  */
00632 
00633 bool glibr::readGreenLight(uint16_t &val)
00634 {
00635     uint8_t val_byte;
00636     val = 0;
00637     
00638     /* Read value from clear channel, low byte register */
00639     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GDATAL);
00640     if( val_byte==ERROR) {
00641         return false;
00642     }
00643     
00644     val = val_byte;
00645     
00646     /* Read value from clear channel, high byte register */
00647     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GDATAH);
00648     if( val_byte==ERROR) {
00649         return false;
00650     }
00651     val = val + ((uint16_t)val_byte << 8);
00652     
00653     return true;
00654 }
00655 
00656 /**
00657  * @brief Reads the red light level as a 16-bit value
00658  *
00659  * @param[out] val value of the light sensor.
00660  * @return True if operation successful. False otherwise.
00661 */
00662 
00663 bool glibr::readBlueLight(uint16_t &val)
00664 {
00665     uint8_t val_byte;
00666     val = 0;
00667     
00668     /* Read value from clear channel, low byte register */
00669     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_BDATAL);
00670     if( val_byte==ERROR) {
00671         return false;
00672     }
00673     
00674     val = val_byte;
00675     
00676     /* Read value from clear channel, high byte register */
00677     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_BDATAH);
00678     if( val_byte==ERROR) {
00679         return false;
00680     }
00681     val = val + ((uint16_t)val_byte << 8);
00682     
00683     return true;
00684 }
00685 
00686 /*******************************************************************************
00687  * Proximity sensor controls
00688  ******************************************************************************/
00689 
00690 /**
00691  * @brief Reads the proximity level as an 8-bit value
00692  *
00693  * @param[out] val value of the proximity sensor.
00694  * @return True if operation successful. False otherwise.
00695  */
00696 bool glibr::readProximity(uint8_t &val)
00697 {
00698     val = 0;
00699     
00700     /* Read value from proximity data register */
00701      val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PDATA);
00702     
00703     if(val==ERROR){
00704         return false;   
00705     }
00706     
00707     return true;
00708 }
00709 
00710 /*******************************************************************************
00711  * High-level gesture controls
00712  ******************************************************************************/
00713 
00714 /**
00715  * @brief Resets all the parameters in the gesture data member
00716  */
00717 void glibr::resetGestureParameters()
00718 {
00719     gesture_data_.sindex = 0;
00720     gesture_data_.total_gestures = 0;
00721     
00722     gesture_ud_delta_ = 0;
00723     gesture_lr_delta_ = 0;
00724     
00725     gesture_ud_count_ = 0;
00726     gesture_lr_count_ = 0;
00727     
00728     gesture_near_count_ = 0;
00729     gesture_far_count_ = 0;
00730     
00731     gesture_state_ = 0;
00732     gesture_motion_ = DIR_NONE;
00733 }
00734 
00735 bool glibr::processGestureData()
00736 {
00737     uint8_t u_first = 0;
00738     uint8_t d_first = 0;
00739     uint8_t l_first = 0;
00740     uint8_t r_first = 0;
00741     uint8_t u_last = 0;
00742     uint8_t d_last = 0;
00743     uint8_t l_last = 0;
00744     uint8_t r_last = 0;
00745     int ud_ratio_first;
00746     int lr_ratio_first;
00747     int ud_ratio_last;
00748     int lr_ratio_last;
00749     int ud_delta;
00750     int lr_delta;
00751     int i;
00752 
00753     /* If we have less than 4 total gestures, that's not enough */
00754     if( gesture_data_.total_gestures <= 4 ) {
00755         return false;
00756     }
00757     
00758     /* Check to make sure our data isn't out of bounds */
00759     if( (gesture_data_.total_gestures <= 32) && \
00760         (gesture_data_.total_gestures > 0) ) {
00761         
00762         /* Find the first value in U/D/L/R above the threshold */
00763         for( i = 0; i < gesture_data_.total_gestures; i++ ) {
00764             if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
00765                 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) &&
00766                 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
00767                 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
00768                 
00769                 u_first = gesture_data_.u_data[i];
00770                 d_first = gesture_data_.d_data[i];
00771                 l_first = gesture_data_.l_data[i];
00772                 r_first = gesture_data_.r_data[i];
00773                 break;
00774             }
00775         }
00776         
00777         /* If one of the _first values is 0, then there is no good data */
00778         if( (u_first == 0) || (d_first == 0) || \
00779             (l_first == 0) || (r_first == 0) ) {
00780             
00781             return false;
00782         }
00783         /* Find the last value in U/D/L/R above the threshold */
00784         for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) {
00785 /* #if DEBUG
00786             Serial.print(F("Finding last: "));
00787             Serial.print(F("U:"));
00788             Serial.print(gesture_data_.u_data[i]);
00789             Serial.print(F(" D:"));
00790             Serial.print(gesture_data_.d_data[i]);
00791             Serial.print(F(" L:"));
00792             Serial.print(gesture_data_.l_data[i]);
00793             Serial.print(F(" R:"));
00794             Serial.println(gesture_data_.r_data[i]);
00795 #endif */
00796             if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
00797                 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) &&
00798                 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
00799                 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
00800                 
00801                 u_last = gesture_data_.u_data[i];
00802                 d_last = gesture_data_.d_data[i];
00803                 l_last = gesture_data_.l_data[i];
00804                 r_last = gesture_data_.r_data[i];
00805                 break;
00806             }
00807         }
00808     }
00809     
00810     /* Calculate the first vs. last ratio of up/down and left/right */
00811     ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first);
00812     lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first);
00813     ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last);
00814     lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last);
00815        
00816 /* #if DEBUG
00817     Serial.print(F("Last Values: "));
00818     Serial.print(F("U:"));
00819     Serial.print(u_last);
00820     Serial.print(F(" D:"));
00821     Serial.print(d_last);
00822     Serial.print(F(" L:"));
00823     Serial.print(l_last);
00824     Serial.print(F(" R:"));
00825     Serial.println(r_last);
00826 
00827     Serial.print(F("Ratios: "));
00828     Serial.print(F("UD Fi: "));
00829     Serial.print(ud_ratio_first);
00830     Serial.print(F(" UD La: "));
00831     Serial.print(ud_ratio_last);
00832     Serial.print(F(" LR Fi: "));
00833     Serial.print(lr_ratio_first);
00834     Serial.print(F(" LR La: "));
00835     Serial.println(lr_ratio_last);
00836 #endif */
00837        
00838     /* Determine the difference between the first and last ratios */
00839     ud_delta = ud_ratio_last - ud_ratio_first;
00840     lr_delta = lr_ratio_last - lr_ratio_first;
00841     
00842 /* #if DEBUG
00843     Serial.print("Deltas: ");
00844     Serial.print("UD: ");
00845     Serial.print(ud_delta);
00846     Serial.print(" LR: ");
00847     Serial.println(lr_delta);
00848 #endif */
00849 
00850     /* Accumulate the UD and LR delta values */
00851     gesture_ud_delta_ += ud_delta;
00852     gesture_lr_delta_ += lr_delta;
00853     
00854 /* #if DEBUG
00855     Serial.print("Accumulations: ");
00856     Serial.print("UD: ");
00857     Serial.print(gesture_ud_delta_);
00858     Serial.print(" LR: ");
00859     Serial.println(gesture_lr_delta_);
00860 #endif */
00861     
00862     /* Determine U/D gesture */
00863     if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) {
00864         gesture_ud_count_ = 1;
00865     } else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) {
00866         gesture_ud_count_ = -1;
00867     } else {
00868         gesture_ud_count_ = 0;
00869     }
00870     
00871     /* Determine L/R gesture */
00872     if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) {
00873         gesture_lr_count_ = 1;
00874     } else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) {
00875         gesture_lr_count_ = -1;
00876     } else {
00877         gesture_lr_count_ = 0;
00878     }
00879     
00880     /* Determine Near/Far gesture */
00881     if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) {
00882         if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
00883             (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
00884             
00885             if( (ud_delta == 0) && (lr_delta == 0) ) {
00886                 gesture_near_count_++;
00887             } else if( (ud_delta != 0) || (lr_delta != 0) ) {
00888                 gesture_far_count_++;
00889             }
00890             
00891             if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) {
00892                 if( (ud_delta == 0) && (lr_delta == 0) ) {
00893                     gesture_state_ = NEAR_STATE;
00894                 } else if( (ud_delta != 0) && (lr_delta != 0) ) {
00895                     gesture_state_ = FAR_STATE;
00896                 }
00897                 return true;
00898             }
00899         }
00900     } else {
00901         if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
00902             (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
00903                 
00904             if( (ud_delta == 0) && (lr_delta == 0) ) {
00905                 gesture_near_count_++;
00906             }
00907             
00908             if( gesture_near_count_ >= 5 ) {
00909                 gesture_ud_count_ = 0;
00910                 gesture_lr_count_ = 0;
00911                 gesture_ud_delta_ = 0;
00912                 gesture_lr_delta_ = 0;
00913             }
00914         }
00915     }
00916     
00917 // #if DEBUG
00918   /*    printf("UD_CT: %d\n",gesture_ud_count_);
00919       printf("LR_CT: %d\n",gesture_lr_count_);
00920       printf("NEAR_CT: %d\n",gesture_near_count_);
00921       printf(" FAR_CT: %d\n",gesture_far_count_);
00922       printf("----------"); */
00923 //#endif */
00924     
00925     return false;
00926 }
00927 
00928 /**
00929  * @brief Determines swipe direction or near/far state
00930  *
00931  * @return True if near/far event. False otherwise.
00932  */
00933 bool glibr::decodeGesture()
00934 {
00935     /* Return if near or far event is detected */
00936     if( gesture_state_ == NEAR_STATE ) {
00937         gesture_motion_ = DIR_NEAR;
00938         return true;
00939     } else if ( gesture_state_ == FAR_STATE ) {
00940         gesture_motion_ = DIR_FAR;
00941         return true;
00942     }
00943     
00944     /* Determine swipe direction */
00945     if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) {
00946         gesture_motion_ = DIR_UP;
00947     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) {
00948         gesture_motion_ = DIR_DOWN;
00949     } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) {
00950         gesture_motion_ = DIR_RIGHT;
00951     } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) {
00952         gesture_motion_ = DIR_LEFT;
00953     } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) {
00954         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00955             gesture_motion_ = DIR_UP;
00956         } else {
00957             gesture_motion_ = DIR_RIGHT;
00958         }
00959     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) {
00960         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00961             gesture_motion_ = DIR_DOWN;
00962         } else {
00963             gesture_motion_ = DIR_LEFT;
00964         }
00965     } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) {
00966         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00967             gesture_motion_ = DIR_UP;
00968         } else {
00969             gesture_motion_ = DIR_LEFT;
00970         }
00971     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) {
00972         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00973             gesture_motion_ = DIR_DOWN;
00974         } else {
00975             gesture_motion_ = DIR_RIGHT;
00976         }
00977     } else {
00978         return false;
00979     }
00980     
00981     return true;
00982 }
00983 
00984 /*******************************************************************************
00985  * Getters and setters for register values
00986  ******************************************************************************/
00987 
00988 /**
00989  * @brief Returns the lower threshold for proximity detection
00990  *
00991  * @return lower threshold
00992  */
00993  
00994  uint8_t glibr::getProxIntLowThresh()
00995 {
00996     uint8_t val;
00997     
00998     /* Read value from PILT register */
00999    /* if( !wireReadDataByte(APDS9960_PILT, val) ) {
01000         val = 0;
01001     }*/
01002     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PILT);
01003     if(val==ERROR){
01004         val=0;   
01005     }
01006     
01007     return val;
01008 }
01009  
01010  /**
01011  * @brief Sets the lower threshold for proximity detection
01012  *
01013  * @param[in] threshold the lower proximity threshold
01014  * @return True if operation successful. False otherwise.
01015  */
01016  bool glibr::setProxIntLowThresh(uint8_t threshold)
01017 {
01018     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT, threshold) ) {
01019         return false;
01020     }
01021     
01022     return true;
01023 }
01024 
01025 /**
01026  * @brief Returns the high threshold for proximity detection
01027  *
01028  * @return high threshold
01029  */
01030 uint8_t glibr::getProxIntHighThresh()
01031 {
01032     uint8_t val;
01033     
01034     /* Read value from PIHT register */
01035     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PILT);
01036     if( val==ERROR ) {
01037         val = 0;
01038     }
01039     
01040     return val;
01041 }
01042 
01043 /**
01044  * @brief Sets the high threshold for proximity detection
01045  *
01046  * @param[in] threshold the high proximity threshold
01047  * @return True if operation successful. False otherwise.
01048  */
01049 bool glibr::setProxIntHighThresh(uint8_t threshold)
01050 {
01051    
01052     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PIHT, threshold) ) {
01053         return false;
01054     }
01055     
01056     return true;
01057 }
01058 
01059  /**
01060  * @brief Returns LED drive strength for proximity and ALS
01061  *
01062  * Value    LED Current
01063  *   0        100 mA
01064  *   1         50 mA
01065  *   2         25 mA
01066  *   3         12.5 mA
01067  *
01068  * @return the value of the LED drive strength. 0xFF on failure.
01069  */
01070 uint8_t glibr::getLEDDrive()
01071 {
01072     uint8_t val;
01073     
01074     /* Read value from CONTROL register */
01075     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01076     if(  val == ERROR ){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01077         return ERROR;
01078     }
01079     
01080     /* Shift and mask out LED drive bits */
01081     val = (val >> 6) & 0x03;//0b00000011;
01082     
01083     return val;
01084 }
01085  
01086  /**
01087  * @brief Sets the LED drive strength for proximity and ALS
01088  *
01089  * Value    LED Current
01090  *   0        100 mA
01091  *   1         50 mA
01092  *   2         25 mA
01093  *   3         12.5 mA
01094  *
01095  * @param[in] drive the value (0-3) for the LED drive strength
01096  * @return True if operation successful. False otherwise.
01097  */
01098  
01099 bool glibr::setLEDDrive(uint8_t drive)
01100 {
01101     uint8_t val;
01102     
01103     /* Read value from CONTROL register */
01104     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01105     if(val==ERROR){
01106         return false;   
01107     }
01108     /* Set bits in register to given value */
01109     //drive &= 0b00000011
01110     drive &= 0x03;
01111     drive = drive << 6;
01112     //val &= 0b00111111;
01113     val &= 0x3F;
01114     val |= drive;
01115     
01116     /* Write register value back into CONTROL register */
01117     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01118         return false;
01119     }
01120     
01121     return true;
01122 }
01123 
01124 /**
01125  * @brief Returns receiver gain for proximity detection
01126  *
01127  * Value    Gain
01128  *   0       1x
01129  *   1       2x
01130  *   2       4x
01131  *   3       8x
01132  *
01133  * @return the value of the proximity gain. 0xFF on failure.
01134  */
01135 uint8_t glibr::getProximityGain()
01136 {
01137     uint8_t val;
01138     
01139     /* Read value from CONTROL register */
01140     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01141     if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01142         return ERROR;
01143     }
01144     
01145     /* Shift and mask out PDRIVE bits */
01146     val = (val >> 2) & 0x03;//0b00000011;
01147     
01148     return val;
01149 }
01150 
01151 /**
01152  * @brief Sets the receiver gain for proximity detection
01153  *
01154  * Value    Gain
01155  *   0       1x
01156  *   1       2x
01157  *   2       4x
01158  *   3       8x
01159  *
01160  * @param[in] drive the value (0-3) for the gain
01161  * @return True if operation successful. False otherwise.
01162  */
01163 bool glibr::setProximityGain(uint8_t drive)
01164 {
01165     uint8_t val;
01166     
01167     /* Read value from CONTROL register */
01168    
01169     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01170     
01171     if(val==ERROR){
01172         return false;   
01173     }
01174     /* Set bits in register to given value */
01175     //drive &= 0b00000011;
01176     drive &=0x03;
01177     drive = drive << 2;
01178     //val &= 0b11110011
01179     val &= 0xF3;
01180     val |= drive;
01181     
01182     /* Write register value back into CONTROL register */
01183     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01184         return false;
01185     }
01186     return true;
01187 }
01188 
01189 /**
01190  * @brief Returns receiver gain for the ambient light sensor (ALS)
01191  *
01192  * Value    Gain
01193  *   0        1x
01194  *   1        4x
01195  *   2       16x
01196  *   3       64x
01197  *
01198  * @return the value of the ALS gain. 0xFF on failure.
01199  */
01200 uint8_t glibr::getAmbientLightGain()
01201 {
01202     uint8_t val;
01203     
01204     /* Read value from CONTROL register */
01205     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01206     if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01207         return ERROR;
01208     }
01209     
01210     /* Shift and mask out ADRIVE bits */
01211     val &= 0x03;//0b00000011;
01212     
01213     return val;
01214 }
01215 
01216 /**
01217  * @brief Sets the receiver gain for the ambient light sensor (ALS)
01218  *
01219  * Value    Gain
01220  *   0        1x
01221  *   1        4x
01222  *   2       16x
01223  *   3       64x
01224  *
01225  * @param[in] drive the value (0-3) for the gain
01226  * @return True if operation successful. False otherwise.
01227  */
01228 bool glibr::setAmbientLightGain(uint8_t drive){
01229 
01230     uint8_t val;
01231     
01232     /* Read value from CONTROL register */
01233    
01234     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01235     
01236     if(val==ERROR){
01237         return false;   
01238     }
01239     /* Set bits in register to given value */
01240     //drive &= 0b00000011;
01241     drive &=0x03;
01242     drive = drive << 2;
01243     //val &=0b11111100
01244     val &= 0xF3;
01245     val |= drive;
01246     
01247     /* Write register value back into CONTROL register */
01248     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01249         return false;
01250     }
01251     return true;
01252 }
01253 
01254 /**
01255  * @brief Get the current LED boost value
01256  * 
01257  * Value  Boost Current
01258  *   0        100%
01259  *   1        150%
01260  *   2        200%
01261  *   3        300%
01262  *
01263  * @return The LED boost value. 0xFF on failure.
01264  */
01265 uint8_t glibr::getLEDBoost() {
01266     uint8_t val;
01267     
01268     /* Read value from CONFIG2 register */
01269     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2);
01270     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) {
01271         return ERROR;
01272     }
01273     
01274     /* Shift and mask out LED_BOOST bits */
01275     val = (val >> 4) & 0x03;//0b00000011;
01276     
01277     return val;
01278 }
01279 
01280 /**
01281  * @brief Sets the LED current boost value
01282  *
01283  * Value  Boost Current
01284  *   0        100%
01285  *   1        150%
01286  *   2        200%
01287  *   3        300%
01288  *
01289  * @param[in] drive the value (0-3) for current boost (100-300%)
01290  * @return True if operation successful. False otherwise.
01291  */
01292 bool glibr::setLEDBoost(uint8_t boost)
01293 {
01294     uint8_t val;
01295     
01296     /* Read value from CONFIG2 register */
01297     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2);
01298     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) {
01299         return false;
01300     }
01301     
01302     /* Set bits in register to given value */
01303     boost &= 0x03;//0b00000011;
01304     boost = boost << 4;
01305     val &= 0xCF;//0b11001111;
01306     val |= boost;
01307     
01308     /* Write register value back into CONFIG2 register */
01309     
01310     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG2, val)){//!wireWriteDataByte(APDS9960_CONFIG2, val) ) {
01311         return false;
01312     }
01313     
01314     return true;
01315 }    
01316 
01317 /**
01318  * @brief Gets proximity gain compensation enable
01319  *
01320  * @return 1 if compensation is enabled. 0 if not. 0xFF on error.
01321  */
01322 uint8_t glibr::getProxGainCompEnable()
01323 {
01324     uint8_t val;
01325     
01326     /* Read value from CONFIG3 register */
01327     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); 
01328     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01329         return ERROR;
01330     }
01331     
01332     /* Shift and mask out PCMP bits */
01333     val = (val >> 5) & 0x01;//0b00000001;
01334     
01335     return val;
01336 }
01337 
01338 /**
01339  * @brief Sets the proximity gain compensation enable
01340  *
01341  * @param[in] enable 1 to enable compensation. 0 to disable compensation.
01342  * @return True if operation successful. False otherwise.
01343  */
01344  bool glibr::setProxGainCompEnable(uint8_t enable)
01345 {
01346     uint8_t val;
01347     
01348     /* Read value from CONFIG3 register */
01349     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01350     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01351         return false;
01352     }
01353     
01354     /* Set bits in register to given value */
01355     enable &= 0x01;//0b00000001;
01356     enable = enable << 5;
01357     val &= 0xCF;//0b11011111;
01358     val |= enable;
01359     
01360     /* Write register value back into CONFIG3 register */
01361     
01362     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG3, val)){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) {
01363         return false;
01364     }
01365     
01366     return true;
01367 }
01368 
01369 /**
01370  * @brief Gets the current mask for enabled/disabled proximity photodiodes
01371  *
01372  * 1 = disabled, 0 = enabled
01373  * Bit    Photodiode
01374  *  3       UP
01375  *  2       DOWN
01376  *  1       LEFT
01377  *  0       RIGHT
01378  *
01379  * @return Current proximity mask for photodiodes. 0xFF on error.
01380  */
01381 uint8_t glibr::getProxPhotoMask()
01382 {
01383     uint8_t val;
01384     
01385     /* Read value from CONFIG3 register */
01386     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01387     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01388         return ERROR;
01389     }
01390     
01391     /* Mask out photodiode enable mask bits */
01392     val &= 0x0F;//0b00001111;
01393     
01394     return val;
01395 }
01396 
01397 /**
01398  * @brief Sets the mask for enabling/disabling proximity photodiodes
01399  *
01400  * 1 = disabled, 0 = enabled
01401  * Bit    Photodiode
01402  *  3       UP
01403  *  2       DOWN
01404  *  1       LEFT
01405  *  0       RIGHT
01406  *
01407  * @param[in] mask 4-bit mask value
01408  * @return True if operation successful. False otherwise.
01409  */
01410 bool glibr::setProxPhotoMask(uint8_t mask)
01411 {
01412     uint8_t val;
01413     
01414     /* Read value from CONFIG3 register */
01415     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01416     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01417         return false;
01418     }
01419     
01420     /* Set bits in register to given value */
01421     mask &= 0x0F;//0b00001111;
01422     val &= 0xF0;//0b11110000;
01423     val |= mask;
01424     
01425     /* Write register value back into CONFIG3 register */
01426     I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val);
01427     if( val == ERROR){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) {
01428         return false;
01429     }
01430     
01431     return true;
01432 }
01433 
01434 /**
01435  * @brief Gets the entry proximity threshold for gesture sensing
01436  *
01437  * @return Current entry proximity threshold.
01438  */
01439 uint8_t glibr::getGestureEnterThresh()
01440 {
01441     uint8_t val;
01442     
01443     /* Read value from GPENTH register */
01444     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GPENTH);
01445     if( val == ERROR){//!wireReadDataByte(APDS9960_GPENTH, val) ) {
01446         val = 0;
01447     }
01448     
01449     return val;
01450 }
01451 
01452 /**
01453  * @brief Sets the entry proximity threshold for gesture sensing
01454  *
01455  * @param[in] threshold proximity value needed to start gesture mode
01456  * @return True if operation successful. False otherwise.
01457  */
01458 bool glibr::setGestureEnterThresh(uint8_t threshold)
01459 {
01460     
01461     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GPENTH, threshold)){;//!wireWriteDataByte(APDS9960_GPENTH, threshold) ) {
01462         return false;
01463     }
01464     
01465     return true;
01466 }
01467 
01468 /**
01469  * @brief Gets the exit proximity threshold for gesture sensing
01470  *
01471  * @return Current exit proximity threshold.
01472  */
01473 uint8_t glibr::getGestureExitThresh()
01474 {
01475     uint8_t val;
01476     
01477     /* Read value from GEXTH register */
01478     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GEXTH);
01479     if( val == ERROR){//!wireReadDataByte(APDS9960_GEXTH, val) ) {
01480         val = 0;
01481     }
01482     
01483     return val;
01484 }
01485 
01486 /**
01487  * @brief Sets the exit proximity threshold for gesture sensing
01488  *
01489  * @param[in] threshold proximity value needed to end gesture mode
01490  * @return True if operation successful. False otherwise.
01491  */
01492 bool glibr::setGestureExitThresh(uint8_t threshold)
01493 {
01494     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GEXTH, threshold)){//!wireWriteDataByte(APDS9960_GEXTH, threshold) ) {
01495         return false;
01496     }
01497     
01498     return true;
01499 }
01500 
01501 /**
01502  * @brief Gets the gain of the photodiode during gesture mode
01503  *
01504  * Value    Gain
01505  *   0       1x
01506  *   1       2x
01507  *   2       4x
01508  *   3       8x
01509  *
01510  * @return the current photodiode gain. 0xFF on error.
01511  */
01512 uint8_t glibr::getGestureGain()
01513 {
01514     uint8_t val;
01515     
01516     /* Read value from GCONF2 register */
01517     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01518     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01519         return ERROR;
01520     }
01521     
01522     /* Shift and mask out GGAIN bits */
01523     val = (val >> 5) & 0x03;//0b00000011;
01524     
01525     return val;
01526 }
01527 
01528 /**
01529  * @brief Sets the gain of the photodiode during gesture mode
01530  *
01531  * Value    Gain
01532  *   0       1x
01533  *   1       2x
01534  *   2       4x
01535  *   3       8x
01536  *
01537  * @param[in] gain the value for the photodiode gain
01538  * @return True if operation successful. False otherwise.
01539  */
01540 bool glibr::setGestureGain(uint8_t gain)
01541 {
01542     uint8_t val;
01543     
01544     /* Read value from GCONF2 register */
01545     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01546     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01547         return false;
01548     }
01549     
01550     /* Set bits in register to given value */
01551     gain &= 0x03;//0b00000011;
01552     gain = gain << 5;
01553     val &= 0x9F;//0b10011111;
01554     val |= gain;
01555     
01556     /* Write register value back into GCONF2 register */
01557     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01558         return false;
01559     }
01560     
01561     return true;
01562 }
01563 
01564 /**
01565  * @brief Gets the drive current of the LED during gesture mode
01566  *
01567  * Value    LED Current
01568  *   0        100 mA
01569  *   1         50 mA
01570  *   2         25 mA
01571  *   3         12.5 mA
01572  *
01573  * @return the LED drive current value. 0xFF on error.
01574  */
01575 uint8_t glibr::getGestureLEDDrive()
01576 {
01577     uint8_t val;
01578     
01579     /* Read value from GCONF2 register */
01580     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01581     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01582         return ERROR;
01583     }
01584     
01585     /* Shift and mask out GLDRIVE bits */
01586     val = (val >> 3) & 0x03;//0b00000011;
01587     
01588     return val;
01589 }
01590 
01591 /**
01592  * @brief Sets the LED drive current during gesture mode
01593  *
01594  * Value    LED Current
01595  *   0        100 mA
01596  *   1         50 mA
01597  *   2         25 mA
01598  *   3         12.5 mA
01599  *
01600  * @param[in] drive the value for the LED drive current
01601  * @return True if operation successful. False otherwise.
01602  */
01603 bool glibr::setGestureLEDDrive(uint8_t drive)
01604 {
01605     uint8_t val;
01606     
01607     /* Read value from GCONF2 register */
01608     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01609     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01610         return false;
01611     }
01612     
01613     /* Set bits in register to given value */
01614     drive &= 0x03;//0b00000011;
01615     drive = drive << 3;
01616     val &= 0xE7;//0b11100111;
01617     val |= drive;
01618     
01619     /* Write register value back into GCONF2 register */
01620     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01621         return false;
01622     }
01623     
01624     return true;
01625 }
01626 
01627 /**
01628  * @brief Gets the time in low power mode between gesture detections
01629  *
01630  * Value    Wait time
01631  *   0          0 ms
01632  *   1          2.8 ms
01633  *   2          5.6 ms
01634  *   3          8.4 ms
01635  *   4         14.0 ms
01636  *   5         22.4 ms
01637  *   6         30.8 ms
01638  *   7         39.2 ms
01639  *
01640  * @return the current wait time between gestures. 0xFF on error.
01641  */
01642 uint8_t glibr::getGestureWaitTime()
01643 {
01644     uint8_t val;
01645     
01646     /* Read value from GCONF2 register */
01647     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01648     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01649         return ERROR;
01650     }
01651     
01652     /* Mask out GWTIME bits */
01653     val &= 0x07;//0b00000111;
01654     
01655     return val;
01656 }
01657 
01658 /*
01659 *
01660 *
01661 *
01662 *LEFT Off HERE AT 3:47PM On 3/6/15
01663 *
01664 *
01665 *
01666 *
01667 */
01668 
01669 
01670 /**
01671  * @brief Sets the time in low power mode between gesture detections
01672  *
01673  * Value    Wait time
01674  *   0          0 ms
01675  *   1          2.8 ms
01676  *   2          5.6 ms
01677  *   3          8.4 ms
01678  *   4         14.0 ms
01679  *   5         22.4 ms
01680  *   6         30.8 ms
01681  *   7         39.2 ms
01682  *
01683  * @param[in] the value for the wait time
01684  * @return True if operation successful. False otherwise.
01685  */
01686 bool glibr::setGestureWaitTime(uint8_t time)
01687 {
01688     uint8_t val;
01689     
01690     /* Read value from GCONF2 register */
01691     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01692     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01693         return false;
01694     }
01695     /* if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
01696         return false;
01697     } */
01698     
01699     /* Set bits in register to given value */
01700     time &= 0x07;//0b00000111;
01701     val &= 0xF8;//0b11111000;
01702     val |= time;
01703     
01704     /* Write register value back into GCONF2 register */
01705     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF2,val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01706         return false;
01707     }
01708     /*if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
01709         return false;
01710     }*/
01711     return true;
01712 }
01713 
01714 /**
01715  * @brief Gets the low threshold for ambient light interrupts
01716  *
01717  * @param[out] threshold current low threshold stored on the APDS-9960
01718  * @return True if operation successful. False otherwise.
01719  */
01720 bool glibr::getLightIntLowThreshold(uint16_t &threshold)
01721 {
01722     uint8_t val_byte;
01723     threshold = 0;
01724     
01725     /* Read value from ambient light low threshold, low byte register */
01726     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTL);
01727     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTL, val_byte) ) {
01728         return false;
01729     }
01730     threshold = val_byte;
01731     
01732     /* Read value from ambient light low threshold, high byte register */
01733     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTH);
01734     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTH, val_byte) ) {
01735         return false;
01736     }
01737     threshold = threshold + ((uint16_t)val_byte << 8);
01738     
01739     return true;
01740 }
01741 
01742 /**
01743  * @brief Sets the low threshold for ambient light interrupts
01744  *
01745  * @param[in] threshold low threshold value for interrupt to trigger
01746  * @return True if operation successful. False otherwise.
01747  */
01748 bool glibr::setLightIntLowThreshold(uint16_t threshold)
01749 {
01750     uint8_t val_low;
01751     uint8_t val_high;
01752     
01753     /* Break 16-bit threshold into 2 8-bit values */
01754     val_low = threshold & 0x00FF;
01755     val_high = (threshold & 0xFF00) >> 8;
01756     
01757     /* Write low byte */
01758     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTL,val_low)){//!wireWriteDataByte(APDS9960_AILTL, val_low) ) {
01759         return false;
01760     }
01761     
01762     /* Write high byte */
01763     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTH,val_high)){//!wireWriteDataByte(APDS9960_AILTH, val_high) ) {
01764         return false;
01765     }
01766     
01767     return true;
01768 }
01769 
01770 /**
01771  * @brief Gets the high threshold for ambient light interrupts
01772  *
01773  * @param[out] threshold current low threshold stored on the APDS-9960
01774  * @return True if operation successful. False otherwise.
01775  */
01776 bool glibr::getLightIntHighThreshold(uint16_t &threshold)
01777 {
01778     uint8_t val_byte;
01779     threshold = 0;
01780     
01781     /* Read value from ambient light high threshold, low byte register */
01782     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTL);
01783     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTL, val_byte) ) {
01784         return false;
01785     }
01786     threshold = val_byte;
01787     
01788     /* Read value from ambient light high threshold, high byte register */
01789     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTH);
01790     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTH, val_byte) ) {
01791         return false;
01792     }
01793     threshold = threshold + ((uint16_t)val_byte << 8);
01794     
01795     return true;
01796 }
01797 
01798 /**
01799  * @brief Sets the high threshold for ambient light interrupts
01800  *
01801  * @param[in] threshold high threshold value for interrupt to trigger
01802  * @return True if operation successful. False otherwise.
01803  */
01804 bool glibr::setLightIntHighThreshold(uint16_t threshold)
01805 {
01806     uint8_t val_low;
01807     uint8_t val_high;
01808     
01809     /* Break 16-bit threshold into 2 8-bit values */
01810     val_low = threshold & 0x00FF;
01811     val_high = (threshold & 0xFF00) >> 8;
01812     
01813     /* Write low byte */
01814     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTL,val_low)){//!wireWriteDataByte(APDS9960_AIHTL, val_low) ) {
01815         return false;
01816     }
01817     
01818     /* Write high byte */
01819     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTH,val_high)){//!wireWriteDataByte(APDS9960_AIHTH, val_high) ) {
01820         return false;
01821     }
01822     
01823     return true;
01824 }
01825 
01826 /**
01827  * @brief Gets the low threshold for proximity interrupts
01828  *
01829  * @param[out] threshold current low threshold stored on the APDS-9960
01830  * @return True if operation successful. False otherwise.
01831  */
01832 bool glibr::getProximityIntLowThreshold(uint8_t &threshold)
01833 {
01834     threshold = 0;
01835     
01836     /* Read value from proximity low threshold register */
01837     threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PILT);
01838     if( threshold == ERROR){//!wireReadDataByte(APDS9960_PILT, threshold) ) {
01839         return false;
01840     }
01841     
01842     return true;
01843 }
01844 
01845 /**
01846  * @brief Sets the low threshold for proximity interrupts
01847  *
01848  * @param[in] threshold low threshold value for interrupt to trigger
01849  * @return True if operation successful. False otherwise.
01850  */
01851 bool glibr::setProximityIntLowThreshold(uint8_t threshold)
01852 {
01853     
01854     /* Write threshold value to register */
01855     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT,threshold)){//!wireWriteDataByte(APDS9960_PILT, threshold) ) {
01856         return false;
01857     }
01858     
01859     return true;
01860 }
01861     
01862 /**
01863  * @brief Gets the high threshold for proximity interrupts
01864  *
01865  * @param[out] threshold current low threshold stored on the APDS-9960
01866  * @return True if operation successful. False otherwise.
01867  */
01868 bool glibr::getProximityIntHighThreshold(uint8_t &threshold)
01869 {
01870     threshold = 0;
01871     
01872     /* Read value from proximity low threshold register */
01873     threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PIHT);
01874     if( threshold == ERROR){//!wireReadDataByte(APDS9960_PIHT, threshold) ) {
01875         return false;
01876     }
01877     
01878     return true;
01879 }
01880 
01881 /**
01882  * @brief Sets the high threshold for proximity interrupts
01883  *
01884  * @param[in] threshold high threshold value for interrupt to trigger
01885  * @return True if operation successful. False otherwise.
01886  */
01887 bool glibr::setProximityIntHighThreshold(uint8_t threshold)
01888 {
01889     
01890     /* Write threshold value to register */
01891     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PIHT,threshold)){//!wireWriteDataByte(APDS9960_PIHT, threshold) ) {
01892         return false;
01893     }
01894     
01895     return true;
01896 }
01897 
01898 /**
01899  * @brief Gets if ambient light interrupts are enabled or not
01900  *
01901  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
01902  */
01903 uint8_t glibr::getAmbientLightIntEnable()
01904 {
01905     uint8_t val;
01906     
01907     /* Read value from ENABLE register */
01908     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01909     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01910         return ERROR;
01911     }
01912     
01913     /* Shift and mask out AIEN bit */
01914     val = (val >> 4) & 0x01;//0b00000001;
01915     
01916     return val;
01917 }
01918 
01919 /**
01920  * @brief Turns ambient light interrupts on or off
01921  *
01922  * @param[in] enable 1 to enable interrupts, 0 to turn them off
01923  * @return True if operation successful. False otherwise.
01924  */
01925 bool glibr::setAmbientLightIntEnable(uint8_t enable)
01926 {
01927     uint8_t val;
01928     
01929     /* Read value from ENABLE register */
01930     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01931     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01932         return false;
01933     }
01934     
01935     /* Set bits in register to given value */
01936     enable &= 0x01;//0b00000001;
01937     enable = enable << 4;
01938     val &= 0xEF;//0b11101111;
01939     val |= enable;
01940     
01941     /* Write register value back into ENABLE register */
01942     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) {
01943         return false;
01944     }
01945     
01946     return true;
01947 }
01948 
01949 /**
01950  * @brief Gets if proximity interrupts are enabled or not
01951  *
01952  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
01953  */
01954 uint8_t glibr::getProximityIntEnable()
01955 {
01956     uint8_t val;
01957     
01958     /* Read value from ENABLE register */
01959     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01960     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01961         return ERROR;
01962     }
01963     
01964     /* Shift and mask out PIEN bit */
01965     val = (val >> 5) & 0x01;//0b00000001;
01966     
01967     return val;
01968 }
01969 
01970 /**
01971  * @brief Turns proximity interrupts on or off
01972  *
01973  * @param[in] enable 1 to enable interrupts, 0 to turn them off
01974  * @return True if operation successful. False otherwise.
01975  */
01976 bool glibr::setProximityIntEnable(uint8_t enable)
01977 {
01978     uint8_t val;
01979     
01980     /* Read value from ENABLE register */
01981     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01982     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01983         return false;
01984     }
01985     
01986     /* Set bits in register to given value */
01987     enable &= 0x01;//0b00000001;
01988     enable = enable << 5;
01989     val &= 0xDF;//0b11011111;
01990     val |= enable;
01991     
01992     /* Write register value back into ENABLE register */
01993     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) {
01994         return false;
01995     }
01996     
01997     return true;
01998 }
01999 
02000 /**
02001  * @brief Gets if gesture interrupts are enabled or not
02002  *
02003  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
02004  */
02005 uint8_t glibr::getGestureIntEnable()
02006 {
02007     uint8_t val;
02008     
02009     /* Read value from GCONF4 register */
02010     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02011     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02012         return ERROR;
02013     }
02014     
02015     /* Shift and mask out GIEN bit */
02016     val = (val >> 1) & 0x01;//0b00000001;
02017     
02018     return val;
02019 }
02020 
02021 /**
02022  * @brief Turns gesture-related interrupts on or off
02023  *
02024  * @param[in] enable 1 to enable interrupts, 0 to turn them off
02025  * @return True if operation successful. False otherwise.
02026  */
02027 bool glibr::setGestureIntEnable(uint8_t enable)
02028 {
02029     uint8_t val;
02030     
02031     /* Read value from GCONF4 register */
02032     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02033     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02034         return false;
02035     }
02036     
02037     /* Set bits in register to given value */
02038     enable &= 0x01;//0b00000001;
02039     enable = enable << 1;
02040     val &= 0xFD;//0b11111101;
02041     val |= enable;
02042     
02043     /* Write register value back into GCONF4 register */
02044     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) {
02045         return false;
02046     }
02047     
02048     return true;
02049 }
02050 
02051 /**
02052  * @brief Clears the ambient light interrupt
02053  *
02054  * @return True if operation completed successfully. False otherwise.
02055  */
02056 bool glibr::clearAmbientLightInt()
02057 {
02058     uint8_t throwaway;
02059     throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AICLEAR);
02060     if( throwaway == ERROR){//!wireReadDataByte(APDS9960_AICLEAR, throwaway) ) {
02061         return false;
02062     }
02063     
02064     return true;
02065 }
02066 
02067 /**
02068  * @brief Clears the proximity interrupt
02069  *
02070  * @return True if operation completed successfully. False otherwise.
02071  */
02072 bool glibr::clearProximityInt()
02073 {
02074     uint8_t throwaway;
02075     throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PICLEAR);
02076     if( throwaway == ERROR){//!wireReadDataByte(APDS9960_PICLEAR, throwaway) ) {
02077         return false;
02078     }
02079     
02080     return true;
02081 }
02082 
02083 /**
02084  * @brief Tells if the gesture state machine is currently running
02085  *
02086  * @return 1 if gesture state machine is running, 0 if not. 0xFF on error.
02087  */
02088 uint8_t glibr::getGestureMode()
02089 {
02090     uint8_t val;
02091     
02092     /* Read value from GCONF4 register */
02093     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02094     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02095         return ERROR;
02096     }
02097     
02098     /* Mask out GMODE bit */
02099     val &= 0x01;//0b00000001;
02100     
02101     return val;
02102 }
02103 
02104 /**
02105  * @brief Tells the state machine to either enter or exit gesture state machine
02106  *
02107  * @param[in] mode 1 to enter gesture state machine, 0 to exit.
02108  * @return True if operation successful. False otherwise.
02109  */
02110 bool glibr::setGestureMode(uint8_t mode)
02111 {
02112     uint8_t val;
02113     
02114     /* Read value from GCONF4 register */
02115     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02116     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02117         return false;
02118     }
02119     
02120     /* Set bits in register to given value */
02121     mode &= 0x01;//0b00000001;
02122     val &= 0xFE;//0b11111110;
02123     val |= mode;
02124     
02125     /* Write register value back into GCONF4 register */
02126     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) {
02127         return false;
02128     }
02129     
02130     return true;
02131 }
02132 
02133 
02134 
02135 
02136 
02137 int glibr::I2CwriteByte(char address, char subAddress, char data)
02138 {   
02139     int ret;
02140     char cmd[2] = {subAddress, data};
02141     ret=i2c.write(address<<1, cmd, 2);  //if ret is 1, then not acked.
02142     return ret;
02143 }
02144 
02145 
02146 
02147 uint8_t glibr::I2CreadByte(char address, char subAddress)
02148 {
02149     char data; // store the register data
02150     
02151     if(i2c.write(address<<1, &subAddress, 1, true)){
02152         return ERROR;   //7 bit   //not acked
02153     } 
02154     if(i2c.read(address<<1, &data, 1)){    /////CHANGED THIS NEED TO TEST.
02155         return ERROR;
02156     }
02157         
02158     
02159     //i2c.read(address<<1, &data, 1);
02160     return data;
02161 
02162 }
02163 
02164 
02165 // * @brief Reads a block (array) of bytes from the I2C device and register
02166 // *
02167 // * @param[in] reg the register to read from
02168 // * @param[out] val pointer to the beginning of the data
02169 // * @param[in] len number of bytes to read
02170 // * @return Number of bytes read. -1 on read error.
02171 // */
02172 int glibr::I2CReadDataBlock(char address, char subAddress, char *data, unsigned int len)
02173 {
02174   //  unsigned char i = 0;
02175 
02176     /* Indicate which register we want to read from */
02177    
02178       if(i2c.write(address<<1, &subAddress, 1, true)){
02179         return -1;   //7 bit   //not acked
02180       } 
02181     
02182     /* Read block data */
02183      
02184     if(i2c.read(address<<1, data, len)){
02185         return -1;
02186     }
02187     
02188     return 1;
02189     //Wire.requestFrom(APDS9960_I2C_ADDR, len);
02190     /*while (Wire.available()) {
02191         if (i >= len) {
02192             return -1;
02193         }
02194         val[i] = Wire.read();
02195         i++;
02196     }*/
02197 }