Krishan Bhagat / Mbed 2 deprecated GestureSensor_Test

Dependencies:   mbed SDFileSystem wave_player

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==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     
00595     return true;
00596 }
00597 
00598 /**
00599  * @brief Reads the red light level as a 16-bit value
00600  *
00601  * @param[out] val value of the light sensor.
00602  * @return True if operation successful. False otherwise.
00603  */
00604 bool glibr::readRedLight(uint16_t &val)
00605 {
00606     uint8_t val_byte;
00607     val = 0;
00608     
00609     /* Read value from clear channel, low byte register */
00610     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_RDATAL);
00611     if( val_byte==ERROR) {
00612         return false;
00613     }
00614     
00615     val = val_byte;
00616     
00617     /* Read value from clear channel, high byte register */
00618     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_RDATAH);
00619     if( val_byte==ERROR) {
00620         return false;
00621     }
00622     val = val + ((uint16_t)val_byte << 8);
00623     
00624     return true;
00625 }
00626 
00627 /**
00628  * @brief Reads the green light level as a 16-bit value
00629  *
00630  * @param[out] val value of the light sensor.
00631  * @return True if operation successful. False otherwise.
00632  */
00633 
00634 bool glibr::readGreenLight(uint16_t &val)
00635 {
00636     uint8_t val_byte;
00637     val = 0;
00638     
00639     /* Read value from clear channel, low byte register */
00640     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GDATAL);
00641     if( val_byte==ERROR) {
00642         return false;
00643     }
00644     
00645     val = val_byte;
00646     
00647     /* Read value from clear channel, high byte register */
00648     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_GDATAH);
00649     if( val_byte==ERROR) {
00650         return false;
00651     }
00652     val = val + ((uint16_t)val_byte << 8);
00653     
00654     return true;
00655 }
00656 
00657 /**
00658  * @brief Reads the red light level as a 16-bit value
00659  *
00660  * @param[out] val value of the light sensor.
00661  * @return True if operation successful. False otherwise.
00662 */
00663 
00664 bool glibr::readBlueLight(uint16_t &val)
00665 {
00666     uint8_t val_byte;
00667     val = 0;
00668     
00669     /* Read value from clear channel, low byte register */
00670     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_BDATAL);
00671     if( val_byte==ERROR) {
00672         return false;
00673     }
00674     
00675     val = val_byte;
00676     
00677     /* Read value from clear channel, high byte register */
00678     val_byte=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_BDATAH);
00679     if( val_byte==ERROR) {
00680         return false;
00681     }
00682     val = val + ((uint16_t)val_byte << 8);
00683     
00684     return true;
00685 }
00686 
00687 /*******************************************************************************
00688  * Proximity sensor controls
00689  ******************************************************************************/
00690 
00691 /**
00692  * @brief Reads the proximity level as an 8-bit value
00693  *
00694  * @param[out] val value of the proximity sensor.
00695  * @return True if operation successful. False otherwise.
00696  */
00697 bool glibr::readProximity(uint8_t &val)
00698 {
00699     val = 0;
00700     
00701     /* Read value from proximity data register */
00702      val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PDATA);
00703     
00704     if(val==ERROR){
00705         return false;   
00706     }
00707     
00708     return true;
00709 }
00710 
00711 /*******************************************************************************
00712  * High-level gesture controls
00713  ******************************************************************************/
00714 
00715 /**
00716  * @brief Resets all the parameters in the gesture data member
00717  */
00718 void glibr::resetGestureParameters()
00719 {
00720     gesture_data_.sindex = 0;
00721     gesture_data_.total_gestures = 0;
00722     
00723     gesture_ud_delta_ = 0;
00724     gesture_lr_delta_ = 0;
00725     
00726     gesture_ud_count_ = 0;
00727     gesture_lr_count_ = 0;
00728     
00729     gesture_near_count_ = 0;
00730     gesture_far_count_ = 0;
00731     
00732     gesture_state_ = 0;
00733     gesture_motion_ = DIR_NONE;
00734 }
00735 
00736 bool glibr::processGestureData()
00737 {
00738     uint8_t u_first = 0;
00739     uint8_t d_first = 0;
00740     uint8_t l_first = 0;
00741     uint8_t r_first = 0;
00742     uint8_t u_last = 0;
00743     uint8_t d_last = 0;
00744     uint8_t l_last = 0;
00745     uint8_t r_last = 0;
00746     int ud_ratio_first;
00747     int lr_ratio_first;
00748     int ud_ratio_last;
00749     int lr_ratio_last;
00750     int ud_delta;
00751     int lr_delta;
00752     int i;
00753 
00754     /* If we have less than 4 total gestures, that's not enough */
00755     if( gesture_data_.total_gestures <= 4 ) {
00756         return false;
00757     }
00758     
00759     /* Check to make sure our data isn't out of bounds */
00760     if( (gesture_data_.total_gestures <= 32) && \
00761         (gesture_data_.total_gestures > 0) ) {
00762         
00763         /* Find the first value in U/D/L/R above the threshold */
00764         for( i = 0; i < gesture_data_.total_gestures; i++ ) {
00765             if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
00766                 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) &&
00767                 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
00768                 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
00769                 
00770                 u_first = gesture_data_.u_data[i];
00771                 d_first = gesture_data_.d_data[i];
00772                 l_first = gesture_data_.l_data[i];
00773                 r_first = gesture_data_.r_data[i];
00774                 break;
00775             }
00776         }
00777         
00778         /* If one of the _first values is 0, then there is no good data */
00779         if( (u_first == 0) || (d_first == 0) || \
00780             (l_first == 0) || (r_first == 0) ) {
00781             
00782             return false;
00783         }
00784         /* Find the last value in U/D/L/R above the threshold */
00785         for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) {
00786 /* #if DEBUG
00787             Serial.print(F("Finding last: "));
00788             Serial.print(F("U:"));
00789             Serial.print(gesture_data_.u_data[i]);
00790             Serial.print(F(" D:"));
00791             Serial.print(gesture_data_.d_data[i]);
00792             Serial.print(F(" L:"));
00793             Serial.print(gesture_data_.l_data[i]);
00794             Serial.print(F(" R:"));
00795             Serial.println(gesture_data_.r_data[i]);
00796 #endif */
00797             if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
00798                 (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) &&
00799                 (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
00800                 (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
00801                 
00802                 u_last = gesture_data_.u_data[i];
00803                 d_last = gesture_data_.d_data[i];
00804                 l_last = gesture_data_.l_data[i];
00805                 r_last = gesture_data_.r_data[i];
00806                 break;
00807             }
00808         }
00809     }
00810     
00811     /* Calculate the first vs. last ratio of up/down and left/right */
00812     ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first);
00813     lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first);
00814     ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last);
00815     lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last);
00816        
00817 /* #if DEBUG
00818     Serial.print(F("Last Values: "));
00819     Serial.print(F("U:"));
00820     Serial.print(u_last);
00821     Serial.print(F(" D:"));
00822     Serial.print(d_last);
00823     Serial.print(F(" L:"));
00824     Serial.print(l_last);
00825     Serial.print(F(" R:"));
00826     Serial.println(r_last);
00827 
00828     Serial.print(F("Ratios: "));
00829     Serial.print(F("UD Fi: "));
00830     Serial.print(ud_ratio_first);
00831     Serial.print(F(" UD La: "));
00832     Serial.print(ud_ratio_last);
00833     Serial.print(F(" LR Fi: "));
00834     Serial.print(lr_ratio_first);
00835     Serial.print(F(" LR La: "));
00836     Serial.println(lr_ratio_last);
00837 #endif */
00838        
00839     /* Determine the difference between the first and last ratios */
00840     ud_delta = ud_ratio_last - ud_ratio_first;
00841     lr_delta = lr_ratio_last - lr_ratio_first;
00842     
00843 /* #if DEBUG
00844     Serial.print("Deltas: ");
00845     Serial.print("UD: ");
00846     Serial.print(ud_delta);
00847     Serial.print(" LR: ");
00848     Serial.println(lr_delta);
00849 #endif */
00850 
00851     /* Accumulate the UD and LR delta values */
00852     gesture_ud_delta_ += ud_delta;
00853     gesture_lr_delta_ += lr_delta;
00854     
00855 /* #if DEBUG
00856     Serial.print("Accumulations: ");
00857     Serial.print("UD: ");
00858     Serial.print(gesture_ud_delta_);
00859     Serial.print(" LR: ");
00860     Serial.println(gesture_lr_delta_);
00861 #endif */
00862     
00863     /* Determine U/D gesture */
00864     if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) {
00865         gesture_ud_count_ = 1;
00866     } else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) {
00867         gesture_ud_count_ = -1;
00868     } else {
00869         gesture_ud_count_ = 0;
00870     }
00871     
00872     /* Determine L/R gesture */
00873     if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) {
00874         gesture_lr_count_ = 1;
00875     } else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) {
00876         gesture_lr_count_ = -1;
00877     } else {
00878         gesture_lr_count_ = 0;
00879     }
00880     
00881     /* Determine Near/Far gesture */
00882     if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) {
00883         if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
00884             (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
00885             
00886             if( (ud_delta == 0) && (lr_delta == 0) ) {
00887                 gesture_near_count_++;
00888             } else if( (ud_delta != 0) || (lr_delta != 0) ) {
00889                 gesture_far_count_++;
00890             }
00891             
00892             if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) {
00893                 if( (ud_delta == 0) && (lr_delta == 0) ) {
00894                     gesture_state_ = NEAR_STATE;
00895                 } else if( (ud_delta != 0) && (lr_delta != 0) ) {
00896                     gesture_state_ = FAR_STATE;
00897                 }
00898                 return true;
00899             }
00900         }
00901     } else {
00902         if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
00903             (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
00904                 
00905             if( (ud_delta == 0) && (lr_delta == 0) ) {
00906                 gesture_near_count_++;
00907             }
00908             
00909             if( gesture_near_count_ >= 5 ) {
00910                 gesture_ud_count_ = 0;
00911                 gesture_lr_count_ = 0;
00912                 gesture_ud_delta_ = 0;
00913                 gesture_lr_delta_ = 0;
00914             }
00915         }
00916     }
00917     
00918 // #if DEBUG
00919   /*    printf("UD_CT: %d\n",gesture_ud_count_);
00920       printf("LR_CT: %d\n",gesture_lr_count_);
00921       printf("NEAR_CT: %d\n",gesture_near_count_);
00922       printf(" FAR_CT: %d\n",gesture_far_count_);
00923       printf("----------"); */
00924 //#endif */
00925     
00926     return false;
00927 }
00928 
00929 /**
00930  * @brief Determines swipe direction or near/far state
00931  *
00932  * @return True if near/far event. False otherwise.
00933  */
00934 bool glibr::decodeGesture()
00935 {
00936     /* Return if near or far event is detected */
00937     if( gesture_state_ == NEAR_STATE ) {
00938         gesture_motion_ = DIR_NEAR;
00939         return true;
00940     } else if ( gesture_state_ == FAR_STATE ) {
00941         gesture_motion_ = DIR_FAR;
00942         return true;
00943     }
00944     
00945     /* Determine swipe direction */
00946     if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) {
00947         gesture_motion_ = DIR_UP;
00948     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) {
00949         gesture_motion_ = DIR_DOWN;
00950     } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) {
00951         gesture_motion_ = DIR_RIGHT;
00952     } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) {
00953         gesture_motion_ = DIR_LEFT;
00954     } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) {
00955         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00956             gesture_motion_ = DIR_UP;
00957         } else {
00958             gesture_motion_ = DIR_RIGHT;
00959         }
00960     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) {
00961         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00962             gesture_motion_ = DIR_DOWN;
00963         } else {
00964             gesture_motion_ = DIR_LEFT;
00965         }
00966     } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) {
00967         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00968             gesture_motion_ = DIR_UP;
00969         } else {
00970             gesture_motion_ = DIR_LEFT;
00971         }
00972     } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) {
00973         if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
00974             gesture_motion_ = DIR_DOWN;
00975         } else {
00976             gesture_motion_ = DIR_RIGHT;
00977         }
00978     } else {
00979         return false;
00980     }
00981     
00982     return true;
00983 }
00984 
00985 /*******************************************************************************
00986  * Getters and setters for register values
00987  ******************************************************************************/
00988 
00989 /**
00990  * @brief Returns the lower threshold for proximity detection
00991  *
00992  * @return lower threshold
00993  */
00994  
00995  uint8_t glibr::getProxIntLowThresh()
00996 {
00997     uint8_t val;
00998     
00999     /* Read value from PILT register */
01000    /* if( !wireReadDataByte(APDS9960_PILT, val) ) {
01001         val = 0;
01002     }*/
01003     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PILT);
01004     if(val==ERROR){
01005         val=0;   
01006     }
01007     
01008     return val;
01009 }
01010  
01011  /**
01012  * @brief Sets the lower threshold for proximity detection
01013  *
01014  * @param[in] threshold the lower proximity threshold
01015  * @return True if operation successful. False otherwise.
01016  */
01017  bool glibr::setProxIntLowThresh(uint8_t threshold)
01018 {
01019     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT, threshold) ) {
01020         return false;
01021     }
01022     
01023     return true;
01024 }
01025 
01026 /**
01027  * @brief Returns the high threshold for proximity detection
01028  *
01029  * @return high threshold
01030  */
01031 uint8_t glibr::getProxIntHighThresh()
01032 {
01033     uint8_t val;
01034     
01035     /* Read value from PIHT register */
01036     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_PILT);
01037     if( val==ERROR ) {
01038         val = 0;
01039     }
01040     
01041     return val;
01042 }
01043 
01044 /**
01045  * @brief Sets the high threshold for proximity detection
01046  *
01047  * @param[in] threshold the high proximity threshold
01048  * @return True if operation successful. False otherwise.
01049  */
01050 bool glibr::setProxIntHighThresh(uint8_t threshold)
01051 {
01052    
01053     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PIHT, threshold) ) {
01054         return false;
01055     }
01056     
01057     return true;
01058 }
01059 
01060  /**
01061  * @brief Returns LED drive strength for proximity and ALS
01062  *
01063  * Value    LED Current
01064  *   0        100 mA
01065  *   1         50 mA
01066  *   2         25 mA
01067  *   3         12.5 mA
01068  *
01069  * @return the value of the LED drive strength. 0xFF on failure.
01070  */
01071 uint8_t glibr::getLEDDrive()
01072 {
01073     uint8_t val;
01074     
01075     /* Read value from CONTROL register */
01076     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01077     if(  val == ERROR ){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01078         return ERROR;
01079     }
01080     
01081     /* Shift and mask out LED drive bits */
01082     val = (val >> 6) & 0x03;//0b00000011;
01083     
01084     return val;
01085 }
01086  
01087  /**
01088  * @brief Sets the LED drive strength for proximity and ALS
01089  *
01090  * Value    LED Current
01091  *   0        100 mA
01092  *   1         50 mA
01093  *   2         25 mA
01094  *   3         12.5 mA
01095  *
01096  * @param[in] drive the value (0-3) for the LED drive strength
01097  * @return True if operation successful. False otherwise.
01098  */
01099  
01100 bool glibr::setLEDDrive(uint8_t drive)
01101 {
01102     uint8_t val;
01103     
01104     /* Read value from CONTROL register */
01105     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01106     if(val==ERROR){
01107         return false;   
01108     }
01109     /* Set bits in register to given value */
01110     //drive &= 0b00000011
01111     drive &= 0x03;
01112     drive = drive << 6;
01113     //val &= 0b00111111;
01114     val &= 0x3F;
01115     val |= drive;
01116     
01117     /* Write register value back into CONTROL register */
01118     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01119         return false;
01120     }
01121     
01122     return true;
01123 }
01124 
01125 /**
01126  * @brief Returns receiver gain for proximity detection
01127  *
01128  * Value    Gain
01129  *   0       1x
01130  *   1       2x
01131  *   2       4x
01132  *   3       8x
01133  *
01134  * @return the value of the proximity gain. 0xFF on failure.
01135  */
01136 uint8_t glibr::getProximityGain()
01137 {
01138     uint8_t val;
01139     
01140     /* Read value from CONTROL register */
01141     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01142     if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01143         return ERROR;
01144     }
01145     
01146     /* Shift and mask out PDRIVE bits */
01147     val = (val >> 2) & 0x03;//0b00000011;
01148     
01149     return val;
01150 }
01151 
01152 /**
01153  * @brief Sets the receiver gain for proximity detection
01154  *
01155  * Value    Gain
01156  *   0       1x
01157  *   1       2x
01158  *   2       4x
01159  *   3       8x
01160  *
01161  * @param[in] drive the value (0-3) for the gain
01162  * @return True if operation successful. False otherwise.
01163  */
01164 bool glibr::setProximityGain(uint8_t drive)
01165 {
01166     uint8_t val;
01167     
01168     /* Read value from CONTROL register */
01169    
01170     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01171     
01172     if(val==ERROR){
01173         return false;   
01174     }
01175     /* Set bits in register to given value */
01176     //drive &= 0b00000011;
01177     drive &=0x03;
01178     drive = drive << 2;
01179     //val &= 0b11110011
01180     val &= 0xF3;
01181     val |= drive;
01182     
01183     /* Write register value back into CONTROL register */
01184     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01185         return false;
01186     }
01187     return true;
01188 }
01189 
01190 /**
01191  * @brief Returns receiver gain for the ambient light sensor (ALS)
01192  *
01193  * Value    Gain
01194  *   0        1x
01195  *   1        4x
01196  *   2       16x
01197  *   3       64x
01198  *
01199  * @return the value of the ALS gain. 0xFF on failure.
01200  */
01201 uint8_t glibr::getAmbientLightGain()
01202 {
01203     uint8_t val;
01204     
01205     /* Read value from CONTROL register */
01206     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01207     if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
01208         return ERROR;
01209     }
01210     
01211     /* Shift and mask out ADRIVE bits */
01212     val &= 0x03;//0b00000011;
01213     
01214     return val;
01215 }
01216 
01217 /**
01218  * @brief Sets the receiver gain for the ambient light sensor (ALS)
01219  *
01220  * Value    Gain
01221  *   0        1x
01222  *   1        4x
01223  *   2       16x
01224  *   3       64x
01225  *
01226  * @param[in] drive the value (0-3) for the gain
01227  * @return True if operation successful. False otherwise.
01228  */
01229 bool glibr::setAmbientLightGain(uint8_t drive){
01230 
01231     uint8_t val;
01232     
01233     /* Read value from CONTROL register */
01234    
01235     val=I2CreadByte(APDS9960_I2C_ADDR,APDS9960_CONTROL);
01236     
01237     if(val==ERROR){
01238         return false;   
01239     }
01240     /* Set bits in register to given value */
01241     //drive &= 0b00000011;
01242     drive &=0x03;
01243     drive = drive << 2;
01244     //val &=0b11111100
01245     val &= 0xF3;
01246     val |= drive;
01247     
01248     /* Write register value back into CONTROL register */
01249     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONTROL, val) ) {
01250         return false;
01251     }
01252     return true;
01253 }
01254 
01255 /**
01256  * @brief Get the current LED boost value
01257  * 
01258  * Value  Boost Current
01259  *   0        100%
01260  *   1        150%
01261  *   2        200%
01262  *   3        300%
01263  *
01264  * @return The LED boost value. 0xFF on failure.
01265  */
01266 uint8_t glibr::getLEDBoost() {
01267     uint8_t val;
01268     
01269     /* Read value from CONFIG2 register */
01270     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2);
01271     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) {
01272         return ERROR;
01273     }
01274     
01275     /* Shift and mask out LED_BOOST bits */
01276     val = (val >> 4) & 0x03;//0b00000011;
01277     
01278     return val;
01279 }
01280 
01281 /**
01282  * @brief Sets the LED current boost value
01283  *
01284  * Value  Boost Current
01285  *   0        100%
01286  *   1        150%
01287  *   2        200%
01288  *   3        300%
01289  *
01290  * @param[in] drive the value (0-3) for current boost (100-300%)
01291  * @return True if operation successful. False otherwise.
01292  */
01293 bool glibr::setLEDBoost(uint8_t boost)
01294 {
01295     uint8_t val;
01296     
01297     /* Read value from CONFIG2 register */
01298     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG2);
01299     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG2, val) ) {
01300         return false;
01301     }
01302     
01303     /* Set bits in register to given value */
01304     boost &= 0x03;//0b00000011;
01305     boost = boost << 4;
01306     val &= 0xCF;//0b11001111;
01307     val |= boost;
01308     
01309     /* Write register value back into CONFIG2 register */
01310     
01311     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG2, val)){//!wireWriteDataByte(APDS9960_CONFIG2, val) ) {
01312         return false;
01313     }
01314     
01315     return true;
01316 }    
01317 
01318 /**
01319  * @brief Gets proximity gain compensation enable
01320  *
01321  * @return 1 if compensation is enabled. 0 if not. 0xFF on error.
01322  */
01323 uint8_t glibr::getProxGainCompEnable()
01324 {
01325     uint8_t val;
01326     
01327     /* Read value from CONFIG3 register */
01328     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3); 
01329     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01330         return ERROR;
01331     }
01332     
01333     /* Shift and mask out PCMP bits */
01334     val = (val >> 5) & 0x01;//0b00000001;
01335     
01336     return val;
01337 }
01338 
01339 /**
01340  * @brief Sets the proximity gain compensation enable
01341  *
01342  * @param[in] enable 1 to enable compensation. 0 to disable compensation.
01343  * @return True if operation successful. False otherwise.
01344  */
01345  bool glibr::setProxGainCompEnable(uint8_t enable)
01346 {
01347     uint8_t val;
01348     
01349     /* Read value from CONFIG3 register */
01350     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01351     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01352         return false;
01353     }
01354     
01355     /* Set bits in register to given value */
01356     enable &= 0x01;//0b00000001;
01357     enable = enable << 5;
01358     val &= 0xCF;//0b11011111;
01359     val |= enable;
01360     
01361     /* Write register value back into CONFIG3 register */
01362     
01363     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_CONFIG3, val)){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) {
01364         return false;
01365     }
01366     
01367     return true;
01368 }
01369 
01370 /**
01371  * @brief Gets the current mask for enabled/disabled proximity photodiodes
01372  *
01373  * 1 = disabled, 0 = enabled
01374  * Bit    Photodiode
01375  *  3       UP
01376  *  2       DOWN
01377  *  1       LEFT
01378  *  0       RIGHT
01379  *
01380  * @return Current proximity mask for photodiodes. 0xFF on error.
01381  */
01382 uint8_t glibr::getProxPhotoMask()
01383 {
01384     uint8_t val;
01385     
01386     /* Read value from CONFIG3 register */
01387     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01388     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01389         return ERROR;
01390     }
01391     
01392     /* Mask out photodiode enable mask bits */
01393     val &= 0x0F;//0b00001111;
01394     
01395     return val;
01396 }
01397 
01398 /**
01399  * @brief Sets the mask for enabling/disabling proximity photodiodes
01400  *
01401  * 1 = disabled, 0 = enabled
01402  * Bit    Photodiode
01403  *  3       UP
01404  *  2       DOWN
01405  *  1       LEFT
01406  *  0       RIGHT
01407  *
01408  * @param[in] mask 4-bit mask value
01409  * @return True if operation successful. False otherwise.
01410  */
01411 bool glibr::setProxPhotoMask(uint8_t mask)
01412 {
01413     uint8_t val;
01414     
01415     /* Read value from CONFIG3 register */
01416     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3);
01417     if( val == ERROR){//!wireReadDataByte(APDS9960_CONFIG3, val) ) {
01418         return false;
01419     }
01420     
01421     /* Set bits in register to given value */
01422     mask &= 0x0F;//0b00001111;
01423     val &= 0xF0;//0b11110000;
01424     val |= mask;
01425     
01426     /* Write register value back into CONFIG3 register */
01427     I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val);
01428     if( val == ERROR){//!wireWriteDataByte(APDS9960_CONFIG3, val) ) {
01429         return false;
01430     }
01431     
01432     return true;
01433 }
01434 
01435 /**
01436  * @brief Gets the entry proximity threshold for gesture sensing
01437  *
01438  * @return Current entry proximity threshold.
01439  */
01440 uint8_t glibr::getGestureEnterThresh()
01441 {
01442     uint8_t val;
01443     
01444     /* Read value from GPENTH register */
01445     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GPENTH);
01446     if( val == ERROR){//!wireReadDataByte(APDS9960_GPENTH, val) ) {
01447         val = 0;
01448     }
01449     
01450     return val;
01451 }
01452 
01453 /**
01454  * @brief Sets the entry proximity threshold for gesture sensing
01455  *
01456  * @param[in] threshold proximity value needed to start gesture mode
01457  * @return True if operation successful. False otherwise.
01458  */
01459 bool glibr::setGestureEnterThresh(uint8_t threshold)
01460 {
01461     
01462     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GPENTH, threshold)){;//!wireWriteDataByte(APDS9960_GPENTH, threshold) ) {
01463         return false;
01464     }
01465     
01466     return true;
01467 }
01468 
01469 /**
01470  * @brief Gets the exit proximity threshold for gesture sensing
01471  *
01472  * @return Current exit proximity threshold.
01473  */
01474 uint8_t glibr::getGestureExitThresh()
01475 {
01476     uint8_t val;
01477     
01478     /* Read value from GEXTH register */
01479     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GEXTH);
01480     if( val == ERROR){//!wireReadDataByte(APDS9960_GEXTH, val) ) {
01481         val = 0;
01482     }
01483     
01484     return val;
01485 }
01486 
01487 /**
01488  * @brief Sets the exit proximity threshold for gesture sensing
01489  *
01490  * @param[in] threshold proximity value needed to end gesture mode
01491  * @return True if operation successful. False otherwise.
01492  */
01493 bool glibr::setGestureExitThresh(uint8_t threshold)
01494 {
01495     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GEXTH, threshold)){//!wireWriteDataByte(APDS9960_GEXTH, threshold) ) {
01496         return false;
01497     }
01498     
01499     return true;
01500 }
01501 
01502 /**
01503  * @brief Gets the gain of the photodiode during gesture mode
01504  *
01505  * Value    Gain
01506  *   0       1x
01507  *   1       2x
01508  *   2       4x
01509  *   3       8x
01510  *
01511  * @return the current photodiode gain. 0xFF on error.
01512  */
01513 uint8_t glibr::getGestureGain()
01514 {
01515     uint8_t val;
01516     
01517     /* Read value from GCONF2 register */
01518     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01519     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01520         return ERROR;
01521     }
01522     
01523     /* Shift and mask out GGAIN bits */
01524     val = (val >> 5) & 0x03;//0b00000011;
01525     
01526     return val;
01527 }
01528 
01529 /**
01530  * @brief Sets the gain of the photodiode during gesture mode
01531  *
01532  * Value    Gain
01533  *   0       1x
01534  *   1       2x
01535  *   2       4x
01536  *   3       8x
01537  *
01538  * @param[in] gain the value for the photodiode gain
01539  * @return True if operation successful. False otherwise.
01540  */
01541 bool glibr::setGestureGain(uint8_t gain)
01542 {
01543     uint8_t val;
01544     
01545     /* Read value from GCONF2 register */
01546     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01547     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01548         return false;
01549     }
01550     
01551     /* Set bits in register to given value */
01552     gain &= 0x03;//0b00000011;
01553     gain = gain << 5;
01554     val &= 0x9F;//0b10011111;
01555     val |= gain;
01556     
01557     /* Write register value back into GCONF2 register */
01558     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01559         return false;
01560     }
01561     
01562     return true;
01563 }
01564 
01565 /**
01566  * @brief Gets the drive current of the LED during gesture mode
01567  *
01568  * Value    LED Current
01569  *   0        100 mA
01570  *   1         50 mA
01571  *   2         25 mA
01572  *   3         12.5 mA
01573  *
01574  * @return the LED drive current value. 0xFF on error.
01575  */
01576 uint8_t glibr::getGestureLEDDrive()
01577 {
01578     uint8_t val;
01579     
01580     /* Read value from GCONF2 register */
01581     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01582     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01583         return ERROR;
01584     }
01585     
01586     /* Shift and mask out GLDRIVE bits */
01587     val = (val >> 3) & 0x03;//0b00000011;
01588     
01589     return val;
01590 }
01591 
01592 /**
01593  * @brief Sets the LED drive current during gesture mode
01594  *
01595  * Value    LED Current
01596  *   0        100 mA
01597  *   1         50 mA
01598  *   2         25 mA
01599  *   3         12.5 mA
01600  *
01601  * @param[in] drive the value for the LED drive current
01602  * @return True if operation successful. False otherwise.
01603  */
01604 bool glibr::setGestureLEDDrive(uint8_t drive)
01605 {
01606     uint8_t val;
01607     
01608     /* Read value from GCONF2 register */
01609     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01610     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01611         return false;
01612     }
01613     
01614     /* Set bits in register to given value */
01615     drive &= 0x03;//0b00000011;
01616     drive = drive << 3;
01617     val &= 0xE7;//0b11100111;
01618     val |= drive;
01619     
01620     /* Write register value back into GCONF2 register */
01621     if( I2CwriteByte(APDS9960_I2C_ADDR, APDS9960_GCONF2, val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01622         return false;
01623     }
01624     
01625     return true;
01626 }
01627 
01628 /**
01629  * @brief Gets the time in low power mode between gesture detections
01630  *
01631  * Value    Wait time
01632  *   0          0 ms
01633  *   1          2.8 ms
01634  *   2          5.6 ms
01635  *   3          8.4 ms
01636  *   4         14.0 ms
01637  *   5         22.4 ms
01638  *   6         30.8 ms
01639  *   7         39.2 ms
01640  *
01641  * @return the current wait time between gestures. 0xFF on error.
01642  */
01643 uint8_t glibr::getGestureWaitTime()
01644 {
01645     uint8_t val;
01646     
01647     /* Read value from GCONF2 register */
01648     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01649     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01650         return ERROR;
01651     }
01652     
01653     /* Mask out GWTIME bits */
01654     val &= 0x07;//0b00000111;
01655     
01656     return val;
01657 }
01658 
01659 /*
01660 *
01661 *
01662 *
01663 *LEFT OFF HERE AT 3:47PM ON 3/6/15
01664 *
01665 *
01666 *
01667 *
01668 */
01669 
01670 
01671 /**
01672  * @brief Sets the time in low power mode between gesture detections
01673  *
01674  * Value    Wait time
01675  *   0          0 ms
01676  *   1          2.8 ms
01677  *   2          5.6 ms
01678  *   3          8.4 ms
01679  *   4         14.0 ms
01680  *   5         22.4 ms
01681  *   6         30.8 ms
01682  *   7         39.2 ms
01683  *
01684  * @param[in] the value for the wait time
01685  * @return True if operation successful. False otherwise.
01686  */
01687 bool glibr::setGestureWaitTime(uint8_t time)
01688 {
01689     uint8_t val;
01690     
01691     /* Read value from GCONF2 register */
01692     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF2);
01693     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF2, val) ) {
01694         return false;
01695     }
01696     /* if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
01697         return false;
01698     } */
01699     
01700     /* Set bits in register to given value */
01701     time &= 0x07;//0b00000111;
01702     val &= 0xF8;//0b11111000;
01703     val |= time;
01704     
01705     /* Write register value back into GCONF2 register */
01706     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF2,val)){//!wireWriteDataByte(APDS9960_GCONF2, val) ) {
01707         return false;
01708     }
01709     /*if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
01710         return false;
01711     }*/
01712     return true;
01713 }
01714 
01715 /**
01716  * @brief Gets the low threshold for ambient light interrupts
01717  *
01718  * @param[out] threshold current low threshold stored on the APDS-9960
01719  * @return True if operation successful. False otherwise.
01720  */
01721 bool glibr::getLightIntLowThreshold(uint16_t &threshold)
01722 {
01723     uint8_t val_byte;
01724     threshold = 0;
01725     
01726     /* Read value from ambient light low threshold, low byte register */
01727     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTL);
01728     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTL, val_byte) ) {
01729         return false;
01730     }
01731     threshold = val_byte;
01732     
01733     /* Read value from ambient light low threshold, high byte register */
01734     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AILTH);
01735     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AILTH, val_byte) ) {
01736         return false;
01737     }
01738     threshold = threshold + ((uint16_t)val_byte << 8);
01739     
01740     return true;
01741 }
01742 
01743 /**
01744  * @brief Sets the low threshold for ambient light interrupts
01745  *
01746  * @param[in] threshold low threshold value for interrupt to trigger
01747  * @return True if operation successful. False otherwise.
01748  */
01749 bool glibr::setLightIntLowThreshold(uint16_t threshold)
01750 {
01751     uint8_t val_low;
01752     uint8_t val_high;
01753     
01754     /* Break 16-bit threshold into 2 8-bit values */
01755     val_low = threshold & 0x00FF;
01756     val_high = (threshold & 0xFF00) >> 8;
01757     
01758     /* Write low byte */
01759     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTL,val_low)){//!wireWriteDataByte(APDS9960_AILTL, val_low) ) {
01760         return false;
01761     }
01762     
01763     /* Write high byte */
01764     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AILTH,val_high)){//!wireWriteDataByte(APDS9960_AILTH, val_high) ) {
01765         return false;
01766     }
01767     
01768     return true;
01769 }
01770 
01771 /**
01772  * @brief Gets the high threshold for ambient light interrupts
01773  *
01774  * @param[out] threshold current low threshold stored on the APDS-9960
01775  * @return True if operation successful. False otherwise.
01776  */
01777 bool glibr::getLightIntHighThreshold(uint16_t &threshold)
01778 {
01779     uint8_t val_byte;
01780     threshold = 0;
01781     
01782     /* Read value from ambient light high threshold, low byte register */
01783     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTL);
01784     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTL, val_byte) ) {
01785         return false;
01786     }
01787     threshold = val_byte;
01788     
01789     /* Read value from ambient light high threshold, high byte register */
01790     val_byte = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AIHTH);
01791     if( val_byte == ERROR){//!wireReadDataByte(APDS9960_AIHTH, val_byte) ) {
01792         return false;
01793     }
01794     threshold = threshold + ((uint16_t)val_byte << 8);
01795     
01796     return true;
01797 }
01798 
01799 /**
01800  * @brief Sets the high threshold for ambient light interrupts
01801  *
01802  * @param[in] threshold high threshold value for interrupt to trigger
01803  * @return True if operation successful. False otherwise.
01804  */
01805 bool glibr::setLightIntHighThreshold(uint16_t threshold)
01806 {
01807     uint8_t val_low;
01808     uint8_t val_high;
01809     
01810     /* Break 16-bit threshold into 2 8-bit values */
01811     val_low = threshold & 0x00FF;
01812     val_high = (threshold & 0xFF00) >> 8;
01813     
01814     /* Write low byte */
01815     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTL,val_low)){//!wireWriteDataByte(APDS9960_AIHTL, val_low) ) {
01816         return false;
01817     }
01818     
01819     /* Write high byte */
01820     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_AIHTH,val_high)){//!wireWriteDataByte(APDS9960_AIHTH, val_high) ) {
01821         return false;
01822     }
01823     
01824     return true;
01825 }
01826 
01827 /**
01828  * @brief Gets the low threshold for proximity interrupts
01829  *
01830  * @param[out] threshold current low threshold stored on the APDS-9960
01831  * @return True if operation successful. False otherwise.
01832  */
01833 bool glibr::getProximityIntLowThreshold(uint8_t &threshold)
01834 {
01835     threshold = 0;
01836     
01837     /* Read value from proximity low threshold register */
01838     threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PILT);
01839     if( threshold == ERROR){//!wireReadDataByte(APDS9960_PILT, threshold) ) {
01840         return false;
01841     }
01842     
01843     return true;
01844 }
01845 
01846 /**
01847  * @brief Sets the low threshold for proximity interrupts
01848  *
01849  * @param[in] threshold low threshold value for interrupt to trigger
01850  * @return True if operation successful. False otherwise.
01851  */
01852 bool glibr::setProximityIntLowThreshold(uint8_t threshold)
01853 {
01854     
01855     /* Write threshold value to register */
01856     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PILT,threshold)){//!wireWriteDataByte(APDS9960_PILT, threshold) ) {
01857         return false;
01858     }
01859     
01860     return true;
01861 }
01862     
01863 /**
01864  * @brief Gets the high threshold for proximity interrupts
01865  *
01866  * @param[out] threshold current low threshold stored on the APDS-9960
01867  * @return True if operation successful. False otherwise.
01868  */
01869 bool glibr::getProximityIntHighThreshold(uint8_t &threshold)
01870 {
01871     threshold = 0;
01872     
01873     /* Read value from proximity low threshold register */
01874     threshold = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PIHT);
01875     if( threshold == ERROR){//!wireReadDataByte(APDS9960_PIHT, threshold) ) {
01876         return false;
01877     }
01878     
01879     return true;
01880 }
01881 
01882 /**
01883  * @brief Sets the high threshold for proximity interrupts
01884  *
01885  * @param[in] threshold high threshold value for interrupt to trigger
01886  * @return True if operation successful. False otherwise.
01887  */
01888 bool glibr::setProximityIntHighThreshold(uint8_t threshold)
01889 {
01890     
01891     /* Write threshold value to register */
01892     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_PIHT,threshold)){//!wireWriteDataByte(APDS9960_PIHT, threshold) ) {
01893         return false;
01894     }
01895     
01896     return true;
01897 }
01898 
01899 /**
01900  * @brief Gets if ambient light interrupts are enabled or not
01901  *
01902  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
01903  */
01904 uint8_t glibr::getAmbientLightIntEnable()
01905 {
01906     uint8_t val;
01907     
01908     /* Read value from ENABLE register */
01909     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01910     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01911         return ERROR;
01912     }
01913     
01914     /* Shift and mask out AIEN bit */
01915     val = (val >> 4) & 0x01;//0b00000001;
01916     
01917     return val;
01918 }
01919 
01920 /**
01921  * @brief Turns ambient light interrupts on or off
01922  *
01923  * @param[in] enable 1 to enable interrupts, 0 to turn them off
01924  * @return True if operation successful. False otherwise.
01925  */
01926 bool glibr::setAmbientLightIntEnable(uint8_t enable)
01927 {
01928     uint8_t val;
01929     
01930     /* Read value from ENABLE register */
01931     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01932     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01933         return false;
01934     }
01935     
01936     /* Set bits in register to given value */
01937     enable &= 0x01;//0b00000001;
01938     enable = enable << 4;
01939     val &= 0xEF;//0b11101111;
01940     val |= enable;
01941     
01942     /* Write register value back into ENABLE register */
01943     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) {
01944         return false;
01945     }
01946     
01947     return true;
01948 }
01949 
01950 /**
01951  * @brief Gets if proximity interrupts are enabled or not
01952  *
01953  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
01954  */
01955 uint8_t glibr::getProximityIntEnable()
01956 {
01957     uint8_t val;
01958     
01959     /* Read value from ENABLE register */
01960     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01961     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01962         return ERROR;
01963     }
01964     
01965     /* Shift and mask out PIEN bit */
01966     val = (val >> 5) & 0x01;//0b00000001;
01967     
01968     return val;
01969 }
01970 
01971 /**
01972  * @brief Turns proximity interrupts on or off
01973  *
01974  * @param[in] enable 1 to enable interrupts, 0 to turn them off
01975  * @return True if operation successful. False otherwise.
01976  */
01977 bool glibr::setProximityIntEnable(uint8_t enable)
01978 {
01979     uint8_t val;
01980     
01981     /* Read value from ENABLE register */
01982     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_ENABLE);
01983     if( val == ERROR){//!wireReadDataByte(APDS9960_ENABLE, val) ) {
01984         return false;
01985     }
01986     
01987     /* Set bits in register to given value */
01988     enable &= 0x01;//0b00000001;
01989     enable = enable << 5;
01990     val &= 0xDF;//0b11011111;
01991     val |= enable;
01992     
01993     /* Write register value back into ENABLE register */
01994     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_ENABLE,val)){//!wireWriteDataByte(APDS9960_ENABLE, val) ) {
01995         return false;
01996     }
01997     
01998     return true;
01999 }
02000 
02001 /**
02002  * @brief Gets if gesture interrupts are enabled or not
02003  *
02004  * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
02005  */
02006 uint8_t glibr::getGestureIntEnable()
02007 {
02008     uint8_t val;
02009     
02010     /* Read value from GCONF4 register */
02011     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02012     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02013         return ERROR;
02014     }
02015     
02016     /* Shift and mask out GIEN bit */
02017     val = (val >> 1) & 0x01;//0b00000001;
02018     
02019     return val;
02020 }
02021 
02022 /**
02023  * @brief Turns gesture-related interrupts on or off
02024  *
02025  * @param[in] enable 1 to enable interrupts, 0 to turn them off
02026  * @return True if operation successful. False otherwise.
02027  */
02028 bool glibr::setGestureIntEnable(uint8_t enable)
02029 {
02030     uint8_t val;
02031     
02032     /* Read value from GCONF4 register */
02033     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02034     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02035         return false;
02036     }
02037     
02038     /* Set bits in register to given value */
02039     enable &= 0x01;//0b00000001;
02040     enable = enable << 1;
02041     val &= 0xFD;//0b11111101;
02042     val |= enable;
02043     
02044     /* Write register value back into GCONF4 register */
02045     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) {
02046         return false;
02047     }
02048     
02049     return true;
02050 }
02051 
02052 /**
02053  * @brief Clears the ambient light interrupt
02054  *
02055  * @return True if operation completed successfully. False otherwise.
02056  */
02057 bool glibr::clearAmbientLightInt()
02058 {
02059     uint8_t throwaway;
02060     throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_AICLEAR);
02061     if( throwaway == ERROR){//!wireReadDataByte(APDS9960_AICLEAR, throwaway) ) {
02062         return false;
02063     }
02064     
02065     return true;
02066 }
02067 
02068 /**
02069  * @brief Clears the proximity interrupt
02070  *
02071  * @return True if operation completed successfully. False otherwise.
02072  */
02073 bool glibr::clearProximityInt()
02074 {
02075     uint8_t throwaway;
02076     throwaway = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_PICLEAR);
02077     if( throwaway == ERROR){//!wireReadDataByte(APDS9960_PICLEAR, throwaway) ) {
02078         return false;
02079     }
02080     
02081     return true;
02082 }
02083 
02084 /**
02085  * @brief Tells if the gesture state machine is currently running
02086  *
02087  * @return 1 if gesture state machine is running, 0 if not. 0xFF on error.
02088  */
02089 uint8_t glibr::getGestureMode()
02090 {
02091     uint8_t val;
02092     
02093     /* Read value from GCONF4 register */
02094     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02095     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02096         return ERROR;
02097     }
02098     
02099     /* Mask out GMODE bit */
02100     val &= 0x01;//0b00000001;
02101     
02102     return val;
02103 }
02104 
02105 /**
02106  * @brief Tells the state machine to either enter or exit gesture state machine
02107  *
02108  * @param[in] mode 1 to enter gesture state machine, 0 to exit.
02109  * @return True if operation successful. False otherwise.
02110  */
02111 bool glibr::setGestureMode(uint8_t mode)
02112 {
02113     uint8_t val;
02114     
02115     /* Read value from GCONF4 register */
02116     val = I2CreadByte(APDS9960_I2C_ADDR, APDS9960_GCONF4);
02117     if( val == ERROR){//!wireReadDataByte(APDS9960_GCONF4, val) ) {
02118         return false;
02119     }
02120     
02121     /* Set bits in register to given value */
02122     mode &= 0x01;//0b00000001;
02123     val &= 0xFE;//0b11111110;
02124     val |= mode;
02125     
02126     /* Write register value back into GCONF4 register */
02127     if( I2CwriteByte(APDS9960_I2C_ADDR,APDS9960_GCONF4,val)){//!wireWriteDataByte(APDS9960_GCONF4, val) ) {
02128         return false;
02129     }
02130     
02131     return true;
02132 }
02133 
02134 
02135 
02136 
02137 
02138 int glibr::I2CwriteByte(char address, char subAddress, char data)
02139 {   
02140     int ret;
02141     char cmd[2] = {subAddress, data};
02142     ret=i2c.write(address<<1, cmd, 2);  //if ret is 1, then not acked.
02143     return ret;
02144 }
02145 
02146 
02147 
02148 uint8_t glibr::I2CreadByte(char address, char subAddress)
02149 {
02150     char data; // store the register data
02151     
02152     if(i2c.write(address<<1, &subAddress, 1, true)){
02153         return ERROR;   //7 bit   //not acked
02154     } 
02155     
02156     if(i2c.read(address<<1, &data, 1)){   
02157         return ERROR;
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 }