Abraham Marsen / Mbed 2 deprecated Jazz_Hands_Nordic

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers APDS9960.cpp Source File

APDS9960.cpp

00001 /**
00002  * @author Abraham Marsen & Allison Ashlock
00003  * Georgia Institute of Technology
00004  * ECE 4180 Embedded Systems Design
00005  * Professor Hamblen
00006  * Spring 2015
00007  *
00008  * @section LICENSE
00009  * ----------------------------------------------------------------------------
00010  * "THE BEER-WARE LICENSE" (Revision 42):
00011  * <amarsen3@gmail.com> wrote this file. As long as you retain this notice you
00012  * can do whatever you want with this stuff. If we meet some day, and you think
00013  * this stuff is worth it, you can buy me a beer in return.
00014  * ----------------------------------------------------------------------------
00015  *
00016  *
00017  * @section DESCRIPTION
00018  *
00019  * Avago Digital Proximity, Ambient Light, RGB and Gesture Sensor APDS-9960
00020  *
00021  * Datasheet, specs, and information:
00022  *
00023  * https://www.sparkfun.com/products/12787
00024  */
00025 
00026 #include "APDS9960.h"
00027 
00028 APDS9960::APDS9960(PinName sda, PinName scl): i2c_(sda, scl)
00029 {
00030     i2c_.frequency(400000);
00031     //i2c_ = I2C(sda, scl);
00032     //400KHz, as specified by the datasheet.
00033 
00034      gest_ud_delta_ =    0;
00035      gest_lr_delta_ =    0;
00036 
00037      gest_ud_count_ =    0;
00038      gest_lr_count_ =    0;
00039 
00040      gest_near_count_ =  0;
00041      gest_far_count_ =   0;
00042 
00043      gest_state_ =       0;
00044      gest_motion_ =      DIR_NA;
00045 }
00046 APDS9960::~APDS9960()
00047 {
00048 }
00049 bool APDS9960::init()
00050 {
00051 
00052 
00053 
00054     // Initialize I2C
00055     // Read ID register and check against known values for APDS-9960
00056     uint8_t id = ReadDataByte(APDS9960_ID);
00057     //printf("id:%u\n\r",id);
00058 
00059     if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2) ) {
00060 
00061         return false;
00062     }
00063     //printf("APDS9960_ID_1:%u\n\rAPDS9960_ID_2:%u\n\r",APDS9960_ID_1,APDS9960_ID_2);
00064     /* Set ENABLE register to 0 (disable all features) */
00065     if( !setMode(ALL, OFF) ) {
00066         return false;
00067     }
00068     //printf("Set Mode: All off.\n\r");
00069 
00070     /* Set default values for ambient light and proximity registers */
00071     if( WriteDataByte(APDS9960_ATIME, DEFAULT_ATIME) ) {
00072         return false;
00073     }
00074     //printf("DEFAULTT_ATIME:%u\n\r",DEFAULT_ATIME);
00075     if( WriteDataByte(APDS9960_WTIME, DEFAULT_WTIME) ) {
00076         return false;
00077     }
00078     //printf("DEFAULTT_WTIME:%u\n\r",DEFAULT_WTIME);
00079 
00080     if( WriteDataByte(APDS9960_PPULSE, DEFAULT_PROX_PPULSE) ) {
00081         return false;
00082     }
00083     //printf("DEFAULT_PROX_PPULSE:%u\n\r",DEFAULT_PROX_PPULSE);
00084 
00085 
00086     if( WriteDataByte(APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR) ) {
00087         return false;
00088     }
00089     //printf("DEFAULT_POFFSET_UR:%u\n\r",DEFAULT_POFFSET_UR);
00090 
00091     if( WriteDataByte(APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL) ) {
00092         return false;
00093     }
00094     //printf("DEFAULT_POFFSET_DL:%u\n\r",DEFAULT_POFFSET_DL);
00095 
00096     if( WriteDataByte(APDS9960_CONFIG1, DEFAULT_CONFIG1) ) {
00097         return false;
00098     }
00099      //printf("DEFAULT_CONFIG1:%u\n\r",DEFAULT_CONFIG1);
00100 if( !setLEDDrive(DEFAULT_LDRIVE) ) {
00101 return false;
00102 }
00103 //printf("led drive set\n\r");
00104 if( !setProxGain(DEFAULT_PGAIN) ) {
00105 return false;
00106 }
00107 //printf("proxgain set\n\r");
00108 if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
00109 return false;
00110 }
00111 //printf("ambient light gain set\r\n");
00112 if( !setProxIntLowThresh(DEFAULT_PILT) ) {
00113 return false;
00114 }
00115 //printf("proxintlowthresh set\n\r");
00116 if( !setProxIntHighThresh(DEFAULT_PIHT) ) {
00117 return false;
00118 }
00119 //printf("proxinthigh thresh set\r\n");
00120 if( !setLightIntLowThreshold(DEFAULT_AILT) ) {
00121 return false;
00122 }
00123 //printf("light int low thresh set\r\n");
00124 if( !setLightIntHighThreshold(DEFAULT_AIHT) ) {
00125 return false;
00126 }
00127 //printf("light int hight thresh set\n\r");
00128 //printf("All set\n\r");
00129 
00130     if( WriteDataByte(APDS9960_CONFIG2, DEFAULT_CONFIG2) ) {
00131         return false;
00132     }
00133 
00134 //printf("DEFAULT_CONFIG2:%u\n\r",DEFAULT_CONFIG2);
00135     if( WriteDataByte(APDS9960_CONFIG3, DEFAULT_CONFIG3) ) {
00136         return false;
00137     }
00138 //printf("DEFAULT_CONFIG3:%u\n\r",DEFAULT_CONFIG3);
00139     /* Set default values for gesture sense registers */
00140     if( !setGestEnterThresh(DEFAULT_GPENTH) ) {
00141         return false;
00142     }
00143 
00144 //printf("Set Gesture Enter Thershold\n\r");
00145     if( !setGestExitThresh(DEFAULT_GEXTH) ) {
00146         return false;
00147     }
00148 
00149 //printf("Set Gesture Exit Thershold\n\r");
00150     if( WriteDataByte(APDS9960_GCONF1, DEFAULT_GCONF1) ) {
00151         return false;
00152     }
00153 
00154 //printf("DEFAULT_CONFIG1:%u\n\r",DEFAULT_CONFIG1);
00155     if( !setGestGain(DEFAULT_GGAIN) ) {
00156         return false;
00157     }
00158 //printf("Set Gest Gain\n\r");
00159 
00160     if( !setGestLEDDrive(DEFAULT_GLDRIVE) ) {
00161         return false;
00162     }
00163 
00164 //printf("Set Gest LED Drive\n\r");
00165     if( !setGestWaitTime(DEFAULT_GWTIME) ) {
00166         return false;
00167     }
00168 //printf("set gest wait time\n\r");
00169 
00170     if( WriteDataByte(APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) {
00171         return false;
00172     }
00173 
00174 
00175     if( WriteDataByte(APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) {
00176         return false;
00177     }
00178 
00179 
00180     if( WriteDataByte(APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) {
00181         return false;
00182     }
00183 
00184 
00185     if( WriteDataByte(APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) {
00186         return false;
00187     }
00188 
00189 
00190     if( WriteDataByte(APDS9960_GPULSE, DEFAULT_GPULSE) ) {
00191         return false;
00192     }
00193 
00194 
00195     if( WriteDataByte(APDS9960_GCONF3, DEFAULT_GCONF3) ) {
00196         return false;
00197     }
00198 
00199 
00200     if( !setGestIntEnable(DEFAULT_GIEN) ) {
00201         return false;
00202     }
00203 
00204     return true;
00205 };
00206 
00207 
00208 
00209 uint8_t APDS9960::getMode()
00210 {
00211     uint8_t enable_value= ReadDataByte(APDS9960_ENABLE);
00212 
00213     /* Read current ENABLE register */
00214     if( enable_value == ERROR) {
00215         return ERROR;
00216     }
00217    // //printf("enable_value:%u\r\n", enable_value);
00218 
00219     return enable_value;
00220 }
00221 
00222 bool APDS9960::setMode(uint8_t mode, uint8_t enable)
00223 {
00224     uint8_t reg_val;
00225     /* Read current ENABLE register */
00226     reg_val = getMode();
00227     //printf("reg_val:%u\r\n", reg_val);
00228     if( reg_val == ERROR ) {
00229         return false;
00230     }
00231     /* Change bit(s) in ENABLE register */
00232     enable = enable & 0x01;
00233     if(mode <= 6 ) {
00234         if (enable) {
00235             reg_val |= (1 << mode);
00236         } else {
00237             reg_val &= ~(1 << mode);
00238         }
00239     } else if( mode == ALL ) {
00240         if (enable) {
00241             reg_val = 0x7F;
00242         } else {
00243             reg_val = 0x00;
00244         }
00245     }
00246     /* Write value back to ENABLE register */
00247     if( WriteDataByte(APDS9960_ENABLE, reg_val) ) {
00248         return false;
00249     }
00250     return true;
00251 }
00252 
00253 bool APDS9960::enPower()
00254 {
00255     if( !setMode(POWER, 1) ) {
00256         return false;
00257     }
00258     return true;
00259 }
00260 
00261 bool APDS9960::disPower()
00262 {
00263     if( !setMode(POWER, 0) ) {
00264         return false;
00265     }
00266     return true;
00267 }
00268 
00269 bool APDS9960::enLightSens(bool interrupts)
00270 {
00271     /* Set default gain, interrupts, enable power, and enable sensor */
00272     if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
00273         return false;
00274     }
00275     if( interrupts ) {
00276         if( !setAmbientLightIntEnable(1) ) {
00277             return false;
00278         }
00279     } else {
00280         if( !setAmbientLightIntEnable(0) ) {
00281             return false;
00282         }
00283     }
00284     if( !enPower() ){
00285         return false;
00286     }
00287     if( !setMode(AMBIENT_LIGHT, 1) ) {
00288         return false;
00289     }
00290     
00291     return true;
00292 
00293 }
00294 
00295 bool APDS9960::disLightSens()
00296 {
00297     if( !setAmbientLightIntEnable(0) ) {
00298         return false;
00299     }
00300     if( !setMode(AMBIENT_LIGHT, 0) ) {
00301         return false;
00302     }
00303     
00304     return true;
00305 }
00306 
00307 bool APDS9960::enProxSens(bool interrupts )
00308 {
00309      /* Set default gain, LED, interrupts, enable power, and enable sensor */
00310     if( !setProxGain(DEFAULT_PGAIN) ) {
00311         return false;
00312     }
00313     if( !setLEDDrive(DEFAULT_LDRIVE) ) {
00314         return false;
00315     }
00316     if( interrupts ) {
00317         if( !setProxIntEnable(1) ) {
00318             return false;
00319         }
00320     } else {
00321         if( !setProxIntEnable(0) ) {
00322             return false;
00323         }
00324     }
00325     if( !enPower() ){
00326         return false;
00327     }
00328     if( !setMode(PROXIMITY, 1) ) {
00329         return false;
00330     }
00331     
00332     return true;
00333 }
00334 
00335 bool APDS9960::disProxSens(){
00336     if( !setProxIntEnable(0) ) {
00337         return false;
00338     }
00339     if( !setMode(PROXIMITY, 0) ) {
00340         return false;
00341     }
00342  
00343     return true;
00344 }
00345 
00346 bool APDS9960::enGestSens(bool interrupts)
00347 {
00348     /* Enable gesture mode
00349        Set ENABLE to 0 (power off)
00350        Set WTIME to 0xFF
00351        Set AUX to LED_BOOST_300
00352        Enable PON, WEN, PEN, GEN in ENABLE
00353     */
00354     rstGestParameters();
00355     if( WriteDataByte(APDS9960_WTIME, 0xFF) ) {
00356         return false;
00357     }
00358     if( WriteDataByte(APDS9960_PPULSE, DEFAULT_GEST_PPULSE) ) {
00359         return false;
00360     }
00361     if( !setLEDBoost(LED_BOOST_300) ) {
00362         return false;
00363     }
00364     if( interrupts ) {
00365         if( !setGestIntEnable(1) ) {
00366             return false;
00367         }
00368     } else {
00369         if( !setGestIntEnable(0) ) {
00370             return false;
00371         }
00372     }
00373     if( !setGestMode(1) ) {
00374         return false;
00375     }
00376     if( !enPower() ) {
00377         return false;
00378     }
00379     if( !setMode(WAIT, 1) ) {
00380         return false;
00381     }
00382     if( !setMode(PROXIMITY, 1) ) {
00383         return false;
00384     }
00385     if( !setMode(GESTURE, 1) ) {
00386         return false;
00387     }
00388     //printf("gestures enabled");
00389     return true;
00390 }
00391 
00392 bool APDS9960::disGestSens()
00393 {
00394     rstGestParameters();
00395     if( !setGestIntEnable(0) ) {
00396         return false;
00397     }
00398     if( !setGestMode(0) ) {
00399         return false;
00400     }
00401     if( !setMode(GESTURE, 0) ) {
00402         return false;
00403     }
00404     return true;
00405 }
00406 
00407 uint8_t APDS9960::getLEDDrive()
00408 {
00409      uint8_t val = ReadDataByte(APDS9960_CONTROL);
00410     
00411     /* Read value from CONTROL register */
00412     if( val == ERROR ) {
00413         return ERROR;
00414     }
00415     
00416     /* Shift and mask out LED drive bits */
00417     val = (val >> 6) & 0x03;
00418     
00419     return val;    
00420 }
00421 
00422 bool APDS9960::setLEDDrive(uint8_t drive)
00423 {
00424      uint8_t val = ReadDataByte(APDS9960_CONTROL);
00425     
00426     /* Read value from CONTROL register */
00427     if( val == ERROR) {
00428         return false;
00429     }
00430     
00431     /* Set bits in register to given value */
00432     drive &= 0x03;
00433     drive = drive << 6;
00434     val &= 0x3F;
00435     val |= drive;
00436     
00437     /* Write register value back into CONTROL register */
00438     if( WriteDataByte(APDS9960_CONTROL, val) ) {
00439         return false;
00440     }
00441     
00442     return true;
00443 }
00444 
00445 uint8_t APDS9960::getGestLEDDrive()
00446 {
00447     uint8_t val=ReadDataByte(APDS9960_GCONF2);
00448     /* Read valeue from GCONF2 register */
00449     if( val == ERROR) {
00450         return ERROR;
00451     }
00452     /* Shift and mask out GLDRIVE bits */
00453     val = (val >> 3) & 0x03;
00454     return val;
00455 }
00456 
00457 bool APDS9960::setGestLEDDrive(uint8_t drive)
00458 {
00459     uint8_t val =ReadDataByte(APDS9960_GCONF2);
00460     
00461     /* Read value from GCONF2 register */
00462     
00463     if( val == ERROR){
00464         return false;
00465     }
00466     
00467     /* Set bits in register to given value */
00468     drive &= 0x03;//0b00000011;
00469     drive = drive << 3;
00470     val &= 0xE7;//0b11100111;
00471     val |= drive;
00472     
00473     /* Write register value back into GCONF2 register */
00474     if( WriteDataByte(APDS9960_GCONF2, val)){
00475         return false;
00476     }
00477     
00478     return true;
00479 }
00480 
00481 /* Gain control */
00482 uint8_t APDS9960::getAmbientLightGain()
00483 {   
00484      uint8_t val = ReadDataByte(APDS9960_CONTROL);
00485     
00486     /* Read value from CONTROL register */
00487     if( val == ERROR ) {
00488         return ERROR;
00489     }
00490     
00491     /* Shift and mask out ADRIVE bits */
00492     val &= 0x03;
00493     
00494     return val;
00495 }
00496 
00497 bool APDS9960::setAmbientLightGain(uint8_t gain)
00498 {
00499     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00500     
00501     /* Read value from CONTROL register */
00502     
00503     if( val == ERROR){//!wireReadDataByte(APDS9960_CONTROL, val) ) {
00504         return ERROR;
00505     }
00506     
00507     /* Set bits in register to given value */
00508     gain &= 0x03;
00509     gain = gain << 2;
00510     val &= 0xF3;
00511     val |= gain;
00512     
00513     /*Write register value back into CONTROL register*/
00514     if(WriteDataByte(APDS9960_CONTROL, val)){
00515         return false;
00516         }
00517     return true;
00518 }
00519 
00520 uint8_t APDS9960::getProxGain()
00521 {
00522      uint8_t val = ReadDataByte(APDS9960_CONTROL);
00523     
00524     /* Read value from CONTROL register */
00525     if( val == ERROR ) {
00526         return ERROR;
00527     }
00528     
00529     /* Shift and mask out PDRIVE bits */
00530     val = (val >> 2) & 0x03;
00531     
00532     return val;
00533 }
00534 
00535 bool APDS9960::setProxGain(uint8_t gain)
00536 {
00537     uint8_t val = ReadDataByte(APDS9960_CONTROL);
00538     
00539     /* Read value from CONTROL register */
00540     if( val == ERROR ) {
00541         return false;
00542     }
00543     
00544     /* Set bits in register to given value */
00545     gain &= 0x03;
00546     gain = gain << 2;
00547     val &= 0xF3;
00548     val |= gain;
00549     
00550     /* Write register value back into CONTROL register */
00551     if( WriteDataByte(APDS9960_CONTROL, val) ) {
00552         return false;
00553     }
00554     
00555     return true;
00556 }
00557 
00558 uint8_t APDS9960::getGestGain()
00559 {
00560     uint8_t val = ReadDataByte(APDS9960_GCONF2);
00561     /* Read value from GCONF2 register */
00562     if( val == ERROR ) {
00563         return ERROR;
00564     }
00565     /* Shift and mask out GGAIN bits */
00566     val = (val >> 5) & 0x03;
00567     return val;
00568 }
00569 
00570 bool APDS9960::setGestGain(uint8_t gain)
00571 {
00572     uint8_t val = ReadDataByte(APDS9960_GCONF2);
00573     /* Read value from GCONF2 register */
00574     if( val == ERROR ) {
00575         //printf("I'm over Here\r\n");
00576         return false;
00577     }
00578     /* Set bits in register to given value */
00579     gain &= 0x03;
00580     gain = gain << 5;
00581     val &= 0x9F;
00582     val |= gain;
00583     /* Write register value back into GCONF2 register */
00584     if( WriteDataByte(APDS9960_GCONF2, val) ) {
00585         //printf("Nope I'm over here!/r/n");
00586         return false;
00587         
00588     }
00589     return true;
00590 }
00591 
00592 /* Get and set light interrupt thresholds */
00593 bool APDS9960::getLightIntLowThreshold(uint16_t &threshold)
00594 {
00595     uint8_t val_byte = ReadDataByte(APDS9960_AILTL);
00596     threshold = 0;
00597     
00598     /* Read value from ambient light low threshold, low byte register */
00599     if( val_byte == ERROR) {
00600         return false;
00601     }
00602     threshold = val_byte;
00603     
00604     /* Read value from ambient light low threshold, high byte register */
00605     val_byte = ReadDataByte(APDS9960_AILTH);
00606     if( val_byte == ERROR ) {
00607         return false;
00608     }
00609     threshold = threshold + ((uint16_t)val_byte << 8);
00610     
00611     return true;    
00612 }
00613 
00614 bool APDS9960::setLightIntLowThreshold(uint16_t threshold)
00615 {
00616     uint8_t val_low;
00617     uint8_t val_high;
00618     
00619     /* Break 16-bit threshold into 2 8-bit values */
00620     val_low = threshold & 0x00FF;
00621     val_high = (threshold & 0xFF00) >> 8;
00622     
00623     /* Write low byte */
00624     if( WriteDataByte(APDS9960_AILTL, val_low) ) {
00625         return false;
00626     }
00627     
00628     /* Write high byte */
00629     if( WriteDataByte(APDS9960_AILTH, val_high) ) {
00630         return false;
00631     }
00632     
00633     return true;
00634 }
00635 
00636 bool APDS9960::getLightIntHighThreshold(uint16_t &threshold)
00637 {
00638      uint8_t val_byte = ReadDataByte(APDS9960_AIHTL);
00639     threshold = 0;
00640     
00641     /* Read value from ambient light high threshold, low byte register */
00642     if( val_byte == ERROR ) {
00643         return false;
00644     }
00645     threshold = val_byte;
00646     
00647     /* Read value from ambient light high threshold, high byte register */
00648     val_byte = ReadDataByte(APDS9960_AIHTH);
00649     if( val_byte == ERROR ) {
00650         return false;
00651     }
00652     threshold = threshold + ((uint16_t)val_byte << 8);
00653     
00654     return true;
00655 }
00656 
00657 bool APDS9960::setLightIntHighThreshold(uint16_t threshold)
00658 {
00659     uint8_t val_low;
00660     uint8_t val_high;
00661     
00662     /* Break 16-bit threshold into 2 8-bit values */
00663     val_low = threshold & 0x00FF;
00664     val_high = (threshold & 0xFF00) >> 8;
00665     
00666     /* Write low byte */
00667     if( WriteDataByte(APDS9960_AIHTL, val_low) ) {
00668         //printf("fail here\r\n");
00669         return false;
00670     }
00671     
00672     /* Write high byte */
00673     if( WriteDataByte(APDS9960_AIHTH, val_high) ) {
00674         //printf("fail over here\r\n");
00675         return false;
00676     }
00677     
00678     return true;
00679 }
00680 
00681 /* Get and set proximity interrupt thresholds */
00682 bool APDS9960::getProxIntLowThreshold(uint8_t &threshold)
00683 {
00684     
00685     
00686     /* Read value from proximity low threshold register */
00687     threshold = ReadDataByte(APDS9960_PILT);
00688     if( threshold == ERROR ) {
00689         threshold = 0;
00690         return false;
00691     }
00692     
00693     return true;
00694 }
00695 
00696 bool APDS9960::setProxIntLowThreshold(uint8_t threshold)
00697 {
00698     /* Write threshold value to register */
00699     if( WriteDataByte(APDS9960_PILT, threshold) ) {
00700         return false;
00701     }
00702     
00703     return true;
00704 }
00705 
00706 bool APDS9960::getProxIntHighThreshold(uint8_t &threshold)
00707 {
00708     threshold = 0;
00709     
00710     /* Read value from proximity low threshold register */
00711     threshold = ReadDataByte(APDS9960_PIHT);
00712     if( threshold == ERROR ) {
00713         threshold = 0;
00714         return false;
00715     }
00716     
00717     return true;
00718 }
00719 
00720 bool APDS9960::setProxIntHighThreshold(uint8_t threshold)
00721 {
00722      /* Write threshold value to register */
00723     if( WriteDataByte(APDS9960_PIHT, threshold) ) {
00724         return false;
00725     }
00726     
00727     return true;
00728 }
00729 
00730 /* Get and set interrupt enables */
00731 uint8_t APDS9960::getAmbientLightIntEnable()
00732 {
00733     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00734     
00735     /* Read value from ENABLE register */
00736     if( val == ERROR ) {
00737         return ERROR;
00738     }
00739     
00740     /* Shift and mask out AIEN bit */
00741     val = (val >> 4) & 0x01;
00742     
00743     return val;
00744 }
00745 
00746 bool APDS9960::setAmbientLightIntEnable(uint8_t enable)
00747 {
00748     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00749     
00750     /* Read value from ENABLE register */
00751     if( val == ERROR ) {
00752         return false;
00753     }
00754     
00755     /* Set bits in register to given value */
00756     enable &= 0x01;
00757     enable = enable << 4;
00758     val &= 0xEF;
00759     val |= enable;
00760     
00761     /* Write register value back into ENABLE register */
00762     if( WriteDataByte(APDS9960_ENABLE, val) ) {
00763         return false;
00764     }
00765     
00766     return true;
00767 }
00768 
00769 uint8_t APDS9960::getProxIntEnable()
00770 {
00771     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00772     
00773     /* Read value from ENABLE register */
00774     if( val == ERROR ) {
00775         return ERROR;
00776     }
00777     
00778     /* Shift and mask out PIEN bit */
00779     val = (val >> 5) & 0x01;
00780     
00781     return val;
00782 }
00783 
00784 bool APDS9960::setProxIntEnable(uint8_t enable)
00785 {
00786     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00787     
00788     /* Read value from ENABLE register */
00789     if( val == ERROR ) {
00790         return false;
00791     }
00792     
00793     /* Set bits in register to given value */
00794     enable &= 0x01;
00795     enable = enable << 5;
00796     val &= 0xDF;
00797     val |= enable;
00798     
00799     /* Write register value back into ENABLE register */
00800     if( WriteDataByte(APDS9960_ENABLE, val) ) {
00801         return false;
00802     }
00803     
00804     return true;
00805 }
00806 
00807 uint8_t APDS9960::getGestIntEnable()
00808 {
00809     uint8_t val = ReadDataByte(APDS9960_ENABLE);
00810     /* Read value from GCONF4 register */
00811     if( val ==ERROR ) {
00812         return ERROR;
00813     }
00814     /* Shift and mask out GIEN bit */
00815     val = (val >> 1) & 0x01;
00816     return val;
00817 }
00818 
00819 bool APDS9960::setGestIntEnable(uint8_t enable)
00820 {
00821     uint8_t val = ReadDataByte(APDS9960_GCONF4);
00822     /* Read value from GCONF4 register */
00823     if( val == ERROR ) {
00824         return false;
00825     }
00826     /* Set bits in register to given value */
00827     enable &= 0x01;
00828     enable = enable << 1;
00829     val &= 0xFD;
00830     val |= enable;
00831     /* Write register value back into GCONF4 register */
00832     if( WriteDataByte(APDS9960_GCONF4, val) ) {
00833         return false;
00834     }
00835     return true;
00836 }
00837 
00838 /* Clear interrupts */
00839 bool APDS9960::clrAmbientLightInt()
00840 {
00841     uint8_t throwaway = ReadDataByte(APDS9960_AICLEAR);
00842     if( throwaway == ERROR ) {
00843         return false;
00844     }
00845     
00846     return true;
00847 }
00848 
00849 bool APDS9960::clrProxInt()
00850 {
00851      uint8_t throwaway = ReadDataByte(APDS9960_PICLEAR);
00852     if( throwaway == ERROR ) {
00853         return false;
00854     }
00855     
00856     return true;
00857 }
00858 
00859 // Ambient light methods
00860 bool APDS9960::readAmbientLight(uint16_t &val)
00861 {
00862     uint8_t val_byte = ReadDataByte(APDS9960_CDATAL);
00863     val = 0;
00864     
00865     /* Read value from clear channel, low byte register */
00866     if( val_byte == ERROR ) {
00867         return false;
00868     }
00869     val = val_byte;
00870     
00871     /* Read value from clear channel, high byte register */
00872     val_byte = ReadDataByte(APDS9960_CDATAH);
00873     if( val_byte == ERROR ) {
00874         return false;
00875     }
00876     val = val + ((uint16_t)val_byte << 8);
00877     
00878     return true;
00879 }
00880 
00881 bool APDS9960::readRedLight(uint16_t &val)
00882 {
00883     uint8_t val_byte = ReadDataByte(APDS9960_RDATAL);
00884     val = 0;
00885     
00886     /* Read value from clear channel, low byte register */
00887     if( val_byte == ERROR ) {
00888         return false;
00889     }
00890     val = val_byte;
00891     
00892     /* Read value from clear channel, high byte register */
00893     val_byte = ReadDataByte(APDS9960_RDATAH);
00894     if( val_byte == ERROR ) {
00895         return false;
00896     }
00897     val = val + ((uint16_t)val_byte << 8);
00898     
00899     return true;
00900 }
00901 
00902 bool APDS9960::readGreenLight(uint16_t &val)
00903 {
00904     uint8_t val_byte = ReadDataByte(APDS9960_GDATAL);
00905     val = 0;
00906     
00907     /* Read value from clear channel, low byte register */
00908     if( val_byte ==ERROR ) {
00909         return false;
00910     }
00911     val = val_byte;
00912     
00913     /* Read value from clear channel, high byte register */
00914     val_byte = ReadDataByte(APDS9960_GDATAH);
00915     if( val_byte == ERROR ) {
00916         return false;
00917     }
00918     val = val + ((uint16_t)val_byte << 8);
00919     
00920     return true;
00921 }
00922 
00923 bool APDS9960::readBlueLight(uint16_t &val)
00924 {
00925     uint8_t val_byte =ReadDataByte(APDS9960_BDATAL);;
00926     val = 0;
00927     
00928     /* Read value from clear channel, low byte register */
00929     if( val_byte ==ERROR ) {
00930         return false;
00931     }
00932     val = val_byte;
00933     
00934     /* Read value from clear channel, high byte register */
00935     val_byte = ReadDataByte(APDS9960_BDATAH);
00936     if( val_byte == ERROR ) {
00937         return false;
00938     }
00939     val = val + ((uint16_t)val_byte << 8);
00940     
00941     return true;
00942 }
00943 
00944 // Proximity methods
00945 bool APDS9960::readProx(uint8_t &val)
00946 {
00947     val = ReadDataByte(APDS9960_PDATA);
00948     
00949     /* Read value from proximity data register */
00950     if( val == ERROR) {
00951         return false;
00952     }
00953     
00954     return true;
00955 }
00956 
00957 // Gesture methods
00958 bool APDS9960::isGestAvailable()
00959 {
00960     uint8_t val = ReadDataByte(APDS9960_GSTATUS);
00961 
00962     /* Read value from GSTATUS register */
00963     if( val == ERROR ) {
00964         return ERROR;
00965     }
00966     //printf("val is %u\r\n", val);
00967     /* Shift and mask out GVALID bit */
00968     val &= APDS9960_GVALID;
00969     
00970     //printf("val & with APDS9960_GVAILD=%u\r\n",val);
00971     /* Return true/false based on GVALID bit */
00972     if( val == 1) {
00973         return true;
00974     } else {
00975         return false;
00976     }
00977 }
00978 
00979 int APDS9960::readGest()
00980 {
00981     uint8_t fifo_level = 0;
00982     int bytes_read = 0;
00983     uint8_t fifo_data[128];
00984     uint8_t gstatus;
00985     int motion;
00986     int i;
00987 
00988     /* Make sure that power and gesture is on and data is valid */
00989     if( !isGestAvailable() || !(getMode() & 0x41) ) {
00990         return DIR_NA;
00991     }
00992 
00993     /* Keep looping as long as gesture data is valid */
00994     while(1) {
00995 
00996         /* Wait some time to collect next batch of FIFO data */
00997         wait(FIFO_TIME);
00998 
00999         /* Get the contents of the STATUS register. Is data still valid? */
01000         gstatus = ReadDataByte(APDS9960_GSTATUS);
01001         if( gstatus == ERROR ) {
01002             return ERROR;
01003         }
01004 
01005         /* If we have valid data, read in FIFO */
01006         if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) {
01007 
01008             /* Read the current FIFO level */
01009             fifo_level = ReadDataByte(APDS9960_GFLVL);
01010             if( fifo_level == ERROR ) {
01011                 return ERROR;
01012             }
01013 
01014 #if DEBUG
01015             Serial.print("FIFO Level: ");
01016             Serial.println(fifo_level);
01017 #endif
01018 
01019             /* If there's stuff in the FIFO, read it into our data block */
01020             if( fifo_level > 0) {
01021                 bytes_read = ReadDataBlock(  APDS9960_GFIFO_U,
01022                                              fifo_data,
01023                                              (fifo_level * 4) );
01024                 if( bytes_read == -1 ) {
01025                     return ERROR;
01026                 }
01027 #if DEBUG
01028                 Serial.print("FIFO Dump: ");
01029                 for ( i = 0; i < bytes_read; i++ ) {
01030                     Serial.print(fifo_data[i]);
01031                     Serial.print(" ");
01032                 }
01033                 Serial.println();
01034 #endif
01035 
01036                 /* If at least 1 set of data, sort the data into U/D/L/R */
01037                 if( bytes_read >= 4 ) {
01038                     for( i = 0; i < bytes_read; i += 4 ) {
01039                         gest_data_.u_data[gest_data_.index_gest] = \
01040                                 fifo_data[i + 0];
01041                         gest_data_.d_data[gest_data_.index_gest] = \
01042                                 fifo_data[i + 1];
01043                         gest_data_.l_data[gest_data_.index_gest] = \
01044                                 fifo_data[i + 2];
01045                         gest_data_.r_data[gest_data_.index_gest] = \
01046                                 fifo_data[i + 3];
01047                         gest_data_.index_gest++;
01048                         gest_data_.total_gests++;
01049                     }
01050 
01051 #if DEBUG
01052                     Serial.print("Up Data: ");
01053                     for ( i = 0; i < gest_data_.total_gests; i++ ) {
01054                         Serial.print(gest_data_.u_data[i]);
01055                         Serial.print(" ");
01056                     }
01057                     Serial.println();
01058 #endif
01059 
01060                     /* Filter and process gest data. Decode near/far state */
01061                     if( procGestData() ) {
01062                         if( decodeGest() ) {
01063                             //***TODO: U-Turn Gestures
01064 #if DEBUG
01065                             //Serial.println(gest_motion_);
01066 #endif
01067                         }
01068                     }
01069 
01070                     /* Reset data */
01071                     gest_data_.index_gest = 0;
01072                     gest_data_.total_gests = 0;
01073                 }
01074             }
01075         } else {
01076 
01077             /* Determine best guessed gest and clean up */
01078             wait(FIFO_TIME);
01079             decodeGest();
01080             motion = gest_motion_;
01081 #if DEBUG
01082             Serial.print("END: ");
01083             Serial.println(gest_motion_);
01084 #endif
01085             rstGestParameters();
01086             return motion;
01087         }
01088     }
01089 }
01090 
01091 // Gesture processing
01092 void APDS9960::rstGestParameters()
01093 {
01094     gest_data_.index_gest = 0;
01095     gest_data_.total_gests = 0;
01096 
01097     gest_ud_delta_ = 0;
01098     gest_lr_delta_ = 0;
01099 
01100     gest_ud_count_ = 0;
01101     gest_lr_count_ = 0;
01102 
01103     gest_near_count_ = 0;
01104     gest_far_count_ = 0;
01105 
01106     gest_state_ = 0;
01107     gest_motion_ = DIR_NA;
01108 }
01109 
01110 bool APDS9960::procGestData()
01111 {
01112     uint8_t u_first = 0;
01113     uint8_t d_first = 0;
01114     uint8_t l_first = 0;
01115     uint8_t r_first = 0;
01116     uint8_t u_last = 0;
01117     uint8_t d_last = 0;
01118     uint8_t l_last = 0;
01119     uint8_t r_last = 0;
01120     int ud_ratio_first;
01121     int lr_ratio_first;
01122     int ud_ratio_last;
01123     int lr_ratio_last;
01124     int ud_delta;
01125     int lr_delta;
01126     int i;
01127 
01128     /* If we have less than 4 total gestures, that's not enough */
01129     if( gest_data_.total_gests <= 4 ) {
01130         return false;
01131     }
01132 
01133     /* Check to make sure our data isn't out of bounds */
01134     if( (gest_data_.total_gests <= 32) && \
01135             (gest_data_.total_gests > 0) ) {
01136 
01137         /* Find the first value in U/D/L/R above the threshold */
01138         for( i = 0; i < gest_data_.total_gests; i++ ) {
01139             if( (gest_data_.u_data[i] > GEST_THRESHOLD_OUT) &&
01140                     (gest_data_.d_data[i] > GEST_THRESHOLD_OUT) &&
01141                     (gest_data_.l_data[i] > GEST_THRESHOLD_OUT) &&
01142                     (gest_data_.r_data[i] > GEST_THRESHOLD_OUT) ) {
01143 
01144                 u_first = gest_data_.u_data[i];
01145                 d_first = gest_data_.d_data[i];
01146                 l_first = gest_data_.l_data[i];
01147                 r_first = gest_data_.r_data[i];
01148                 break;
01149             }
01150         }
01151 
01152         /* If one of the _first values is 0, then there is no good data */
01153         if( (u_first == 0) || (d_first == 0) || \
01154                 (l_first == 0) || (r_first == 0) ) {
01155 
01156             return false;
01157         }
01158         /* Find the last value in U/D/L/R above the threshold */
01159         for( i = gest_data_.total_gests - 1; i >= 0; i-- ) {
01160 #if DEBUG
01161             Serial.print(F("Finding last: "));
01162             Serial.print(F("U:"));
01163             Serial.print(gest_data_.u_data[i]);
01164             Serial.print(F(" D:"));
01165             Serial.print(gest_data_.d_data[i]);
01166             Serial.print(F(" L:"));
01167             Serial.print(gest_data_.l_data[i]);
01168             Serial.print(F(" R:"));
01169             Serial.println(gest_data_.r_data[i]);
01170 #endif
01171             if( (gest_data_.u_data[i] > GEST_THRESHOLD_OUT) &&
01172                     (gest_data_.d_data[i] > GEST_THRESHOLD_OUT) &&
01173                     (gest_data_.l_data[i] > GEST_THRESHOLD_OUT) &&
01174                     (gest_data_.r_data[i] > GEST_THRESHOLD_OUT) ) {
01175 
01176                 u_last = gest_data_.u_data[i];
01177                 d_last = gest_data_.d_data[i];
01178                 l_last = gest_data_.l_data[i];
01179                 r_last = gest_data_.r_data[i];
01180                 break;
01181             }
01182         }
01183     }
01184 
01185     /* Calculate the first vs. last ratio of up/down and left/right */
01186     ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first);
01187     lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first);
01188     ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last);
01189     lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last);
01190 
01191 #if DEBUG
01192     Serial.print(F("Last Values: "));
01193     Serial.print(F("U:"));
01194     Serial.print(u_last);
01195     Serial.print(F(" D:"));
01196     Serial.print(d_last);
01197     Serial.print(F(" L:"));
01198     Serial.print(l_last);
01199     Serial.print(F(" R:"));
01200     Serial.println(r_last);
01201 
01202     Serial.print(F("Ratios: "));
01203     Serial.print(F("UD Fi: "));
01204     Serial.print(ud_ratio_first);
01205     Serial.print(F(" UD La: "));
01206     Serial.print(ud_ratio_last);
01207     Serial.print(F(" LR Fi: "));
01208     Serial.print(lr_ratio_first);
01209     Serial.print(F(" LR La: "));
01210     Serial.println(lr_ratio_last);
01211 #endif
01212 
01213     /* Determine the difference between the first and last ratios */
01214     ud_delta = ud_ratio_last - ud_ratio_first;
01215     lr_delta = lr_ratio_last - lr_ratio_first;
01216 
01217 #if DEBUG
01218     Serial.print("Deltas: ");
01219     Serial.print("UD: ");
01220     Serial.print(ud_delta);
01221     Serial.print(" LR: ");
01222     Serial.println(lr_delta);
01223 #endif
01224 
01225     /* Accumulate the UD and LR delta values */
01226     gest_ud_delta_ += ud_delta;
01227     gest_lr_delta_ += lr_delta;
01228 
01229 #if DEBUG
01230     Serial.print("Accumulations: ");
01231     Serial.print("UD: ");
01232     Serial.print(gest_ud_delta_);
01233     Serial.print(" LR: ");
01234     Serial.println(gest_lr_delta_);
01235 #endif
01236 
01237     /* Determine U/D gesture */
01238     if( gest_ud_delta_ >= GEST_SENSITIVITY_1 ) {
01239         gest_ud_count_ = 1;
01240     } else if( gest_ud_delta_ <= -GEST_SENSITIVITY_1 ) {
01241         gest_ud_count_ = -1;
01242     } else {
01243         gest_ud_count_ = 0;
01244     }
01245 
01246     /* Determine L/R gesture */
01247     if( gest_lr_delta_ >= GEST_SENSITIVITY_1 ) {
01248         gest_lr_count_ = 1;
01249     } else if( gest_lr_delta_ <= -GEST_SENSITIVITY_1 ) {
01250         gest_lr_count_ = -1;
01251     } else {
01252         gest_lr_count_ = 0;
01253     }
01254 
01255     /* Determine Near/Far gesture */
01256     if( (gest_ud_count_ == 0) && (gest_lr_count_ == 0) ) {
01257         if( (abs(ud_delta) < GEST_SENSITIVITY_2) && \
01258                 (abs(lr_delta) < GEST_SENSITIVITY_2) ) {
01259 
01260             if( (ud_delta == 0) && (lr_delta == 0) ) {
01261                // printf("increase near count\n\r");
01262                 gest_near_count_++;
01263             } else if( (ud_delta != 0) || (lr_delta != 0) ) {
01264                // printf("increase far count\r\n");
01265                 gest_far_count_++;
01266             }
01267 
01268             if( (gest_near_count_ >= 3) && (gest_far_count_ >= 2) ) {
01269                 if( (ud_delta == 0) && (lr_delta == 0) ) {
01270                     gest_state_ = NEAR_STATE;
01271                 } else if( (ud_delta != 0) && (lr_delta != 0) ) {
01272                     gest_state_ = FAR_STATE;
01273                 }
01274                 return true;
01275             }
01276         }
01277     } else {
01278         if( (abs(ud_delta) < GEST_SENSITIVITY_2) && \
01279                 (abs(lr_delta) < GEST_SENSITIVITY_2) ) {
01280 
01281             if( (ud_delta == 0) && (lr_delta == 0) ) {
01282                 gest_near_count_++;
01283             }
01284 
01285             if( gest_near_count_ >= 5 ) {
01286                 gest_ud_count_ = 0;
01287                 gest_lr_count_ = 0;
01288                 gest_ud_delta_ = 0;
01289                 gest_lr_delta_ = 0;
01290             }
01291         }
01292     }
01293 
01294 #if DEBUG
01295     Serial.print("UD_CT: ");
01296     Serial.print(gest_ud_count_);
01297     Serial.print(" LR_CT: ");
01298     Serial.print(gest_lr_count_);
01299     Serial.print(" NEAR_CT: ");
01300     Serial.print(gest_near_count_);
01301     Serial.print(" FAR_CT: ");
01302     Serial.println(gest_far_count_);
01303     Serial.println("----------");
01304 #endif
01305 
01306     return false;
01307 }
01308 
01309 bool APDS9960::decodeGest()
01310 {
01311     /* Return if near or far event is detected */
01312     if( gest_state_ == NEAR_STATE ) {
01313         gest_motion_ = DIR_I;
01314         return true;
01315     } else if ( gest_state_ == FAR_STATE ) {
01316         gest_motion_ = DIR_O;
01317         return true;
01318     }
01319 
01320     /* Determine swipe direction */
01321     if( (gest_ud_count_ == -1) && (gest_lr_count_ == 0) ) {
01322         gest_motion_ = DIR_N;
01323     } else if( (gest_ud_count_ == 1) && (gest_lr_count_ == 0) ) {
01324         gest_motion_ = DIR_S;
01325     } else if( (gest_ud_count_ == 0) && (gest_lr_count_ == 1) ) {
01326         gest_motion_ = DIR_E;
01327     } else if( (gest_ud_count_ == 0) && (gest_lr_count_ == -1) ) {
01328         gest_motion_ = DIR_W;
01329     } else if( (gest_ud_count_ == -1) && (gest_lr_count_ == 1) ) {
01330         gest_motion_ = DIR_NE;
01331         /*if( abs(gest_ud_delta_) > abs(gest_lr_delta_) ) {
01332             gest_motion_ = DIR_N;
01333         } else {
01334             gest_motion_ = DIR_E;
01335         }*/
01336     } else if( (gest_ud_count_ == 1) && (gest_lr_count_ == -1) ) {
01337         if( abs(gest_ud_delta_) > abs(gest_lr_delta_) ) {
01338             gest_motion_ = DIR_S;
01339         } else {
01340             gest_motion_ = DIR_W;
01341         }
01342     } else if( (gest_ud_count_ == -1) && (gest_lr_count_ == -1) ) {
01343         if( abs(gest_ud_delta_) > abs(gest_lr_delta_) ) {
01344             gest_motion_ = DIR_N;
01345         } else {
01346             gest_motion_ = DIR_W;
01347         }
01348     } else if( (gest_ud_count_ == 1) && (gest_lr_count_ == 1) ) {
01349         if( abs(gest_ud_delta_) > abs(gest_lr_delta_) ) {
01350             gest_motion_ = DIR_S;
01351         } else {
01352             gest_motion_ = DIR_E;
01353         }
01354     } else {
01355         return false;
01356     }
01357 
01358     return true;
01359 }
01360 // Proximity Interrupt Threshold
01361 uint8_t APDS9960::getProxIntLowThresh()
01362 {
01363     uint8_t val = ReadDataByte(APDS9960_PILT);
01364     
01365     /* Read value from PILT register */
01366     if( val == ERROR ) {
01367         val = 0;
01368     }
01369     
01370     return val;
01371 }
01372 
01373 bool APDS9960::setProxIntLowThresh(uint8_t threshold)
01374 {
01375     if( WriteDataByte(APDS9960_PILT, threshold) ) {
01376         return false;
01377     }
01378     
01379     return true;
01380 }
01381 
01382 uint8_t APDS9960::getProxIntHighThresh()
01383 {
01384     uint8_t val = ReadDataByte(APDS9960_PIHT);
01385     
01386     /* Read value from PIHT register */
01387     if( val == ERROR ) {
01388         val = 0;
01389     }
01390     
01391     return val;
01392 }
01393 
01394 bool APDS9960::setProxIntHighThresh(uint8_t threshold)
01395 {
01396     if( WriteDataByte(APDS9960_PIHT, threshold) ) {
01397         return false;
01398     }
01399     
01400     return true;
01401 }
01402 
01403 // LED Boost Control
01404 uint8_t APDS9960::getLEDBoost()
01405 {
01406     uint8_t val = ReadDataByte(APDS9960_CONFIG2);
01407     
01408     /* Read value from CONFIG2 register */
01409     if( val == ERROR ) {
01410         return ERROR;
01411     }
01412     
01413     /* Shift and mask out LED_BOOST bits */
01414     val = (val >> 4) & 0x03;
01415     
01416     return val;
01417 }
01418 
01419 bool APDS9960::setLEDBoost(uint8_t boost)
01420 {
01421     uint8_t val = ReadDataByte(APDS9960_CONFIG2);
01422 
01423     /* Read value from CONFIG2 register */
01424     if( val == ERROR ) {
01425         return false;
01426     }
01427 
01428     /* Set bits in register to given value */
01429     boost &= 0x03;
01430     boost = boost << 4;
01431     val &= 0xCF;
01432     val |= boost;
01433 
01434     /* Write register value back into CONFIG2 register */
01435     if( WriteDataByte(APDS9960_CONFIG2, val) ) {
01436         return false;
01437     }
01438 
01439     return true;
01440 }
01441 
01442 // Proximity photodiode select
01443 uint8_t APDS9960::getProxGainCompEnable()
01444 {
01445     uint8_t val = ReadDataByte(APDS9960_CONFIG3);
01446     
01447     /* Read value from CONFIG3 register */
01448     if( val == ERROR ) {
01449         return ERROR;
01450     }
01451     
01452     /* Shift and mask out PCMP bits */
01453     val = (val >> 5) & 0x01;
01454     
01455     return val;
01456 }
01457 
01458 bool APDS9960::setProxGainCompEnable(uint8_t enable)
01459 {
01460     uint8_t val = ReadDataByte(APDS9960_CONFIG3);
01461     
01462     /* Read value from CONFIG3 register */
01463     if( val == ERROR ) {
01464         return false;
01465     }
01466     
01467     /* Set bits in register to given value */
01468     enable &= 0x01;
01469     enable = enable << 5;
01470     val &= 0xDF;
01471     val |= enable;
01472     
01473     /* Write register value back into CONFIG3 register */
01474     if( WriteDataByte(APDS9960_CONFIG3, val) ) {
01475         return false;
01476     }
01477     
01478     return true;
01479 }
01480 
01481 uint8_t APDS9960::getProxPhotoMask()
01482 {
01483     uint8_t val = ReadDataByte(APDS9960_CONFIG3);
01484     
01485     /* Read value from CONFIG3 register */
01486     if( val == ERROR ) {
01487         return ERROR;
01488     }
01489     
01490     /* Mask out photodiode enable mask bits */
01491     val &= 0x0F;
01492     
01493     return val;
01494 }
01495 
01496 bool APDS9960::setProxPhotoMask(uint8_t mask)
01497 {
01498     uint8_t val = ReadDataByte(APDS9960_CONFIG3);
01499     
01500     /* Read value from CONFIG3 register */
01501     if( val == ERROR ) {
01502         return false;
01503     }
01504     
01505     /* Set bits in register to given value */
01506     mask &= 0x0F;
01507     val &= 0xF0;
01508     val |= mask;
01509     
01510     /* Write register value back into CONFIG3 register */
01511     if( WriteDataByte(APDS9960_CONFIG3, val) ) {
01512         return false;
01513     }
01514     
01515     return true;
01516 }
01517 
01518 // Gesture threshold control
01519 uint8_t APDS9960::getGestEnterThresh()
01520 {
01521     uint8_t val = ReadDataByte(APDS9960_GPENTH);
01522     /* Read value from GPENTH register */
01523     if( val == ERROR ) {
01524         val = 0;
01525     }
01526     return val;
01527 }
01528 
01529 bool APDS9960::setGestEnterThresh(uint8_t threshold)
01530 {
01531     if( WriteDataByte(APDS9960_GPENTH, threshold) ) {
01532         return false;
01533     }
01534     return true;
01535 }
01536 
01537 uint8_t APDS9960::getGestExitThresh()
01538 {
01539     uint8_t val = ReadDataByte(APDS9960_GEXTH);
01540     /* Read value from GEXTH register */
01541     if( val == ERROR ) {
01542         val = 0;
01543     }
01544     return val;
01545 }
01546 
01547 bool APDS9960::setGestExitThresh(uint8_t threshold)
01548 {
01549     if( WriteDataByte(APDS9960_GEXTH, threshold) ) {
01550         return false;
01551     }
01552     return true;
01553 }
01554 
01555 // Gesture LED, gain, and time control
01556 uint8_t APDS9960::getGestWaitTime()
01557 {
01558     uint8_t val = ReadDataByte(APDS9960_GCONF2);
01559     /* Read value from GCONF2 register */
01560     if( val == ERROR ) {
01561         return ERROR;
01562     }
01563     /* Mask out GWTIME bits */
01564     val &= 0x07;
01565     return val;
01566 }
01567 
01568 bool APDS9960::setGestWaitTime(uint8_t time)
01569 {
01570     uint8_t val = ReadDataByte(APDS9960_GCONF2);
01571     /* Read value from GCONF2 register */
01572     if( val == ERROR ) {
01573         return false;
01574     }
01575     /* Set bits in register to given value */
01576     time &= 0x07;
01577     val &= 0xF8;
01578     val |= time;
01579     /* Write register value back into GCONF2 register */
01580     if( WriteDataByte(APDS9960_GCONF2, val) ) {
01581         return false;
01582     }
01583     return true;
01584 }
01585 
01586 // Gesture mode
01587 uint8_t APDS9960::getGestMode()
01588 {
01589     uint8_t val = ReadDataByte(APDS9960_GCONF4);
01590     /* Read value from GCONF4 register */
01591     if( val == ERROR ) {
01592         return ERROR;
01593     }
01594     /* Mask out GMODE bit */
01595     val &= 0x01;
01596     return val;
01597 }
01598 
01599 bool APDS9960::setGestMode(uint8_t mode)
01600 {
01601     uint8_t val = ReadDataByte(APDS9960_GCONF4);
01602     /* Read value from GCONF4 register */
01603     if( val == ERROR ) {
01604         return false;
01605     }
01606     /* Set bits in register to given value */
01607     mode &= 0x01;
01608     val &= 0xFE;
01609     val |= mode;
01610     /* Write register value back into GCONF4 register */
01611     if( WriteDataByte(APDS9960_GCONF4, val) ) {
01612         return false;
01613     }
01614     return true;
01615 }
01616 
01617 // Raw I2C Commands
01618 bool APDS9960::WriteByte(uint8_t val)
01619 {
01620     if(i2c_.write(val)) {
01621         return false;
01622     }
01623 
01624     return true;
01625 }
01626 
01627 int APDS9960::WriteDataByte(char reg, char val)
01628 {
01629     /*Wire.beginTransmission(APDS9960_I2C_ADDR);
01630     Wire.write(reg);
01631     Wire.write(val);
01632     if( Wire.endTransmission() != 0 ) {
01633         return false;
01634     }*/
01635     /*char regdata[1];
01636     regdata[0] = reg;*/
01637    // printf("reg is %u, val is %u\r\n", reg, val);
01638     
01639     char cmd[2] = {reg, val};
01640     uint8_t data = i2c_.write(APDS9960_I2C_ADDR, cmd, 2,true); 
01641   /*  if(i2c_.write(APDS9960_I2C_ADDR, (char*) &val, 1) !=0) {
01642         return false;
01643     }*/
01644 
01645    // uint8_t temp=i2c_.read(APDS9960_I2C_ADDR);
01646     //printf("temp:%u\r\n");
01647 
01648     return data;
01649 
01650 }
01651 
01652 /*bool APDS9960::WriteDataBlock(uint8_t reg, uint8_t *val, unsigned int len){
01653         unsigned int i;
01654         char regdata[len];
01655 
01656     //Wire.beginTransmission(APDS9960_I2C_ADDR);
01657     //Wire.write(reg);
01658     for(i = 0; i < len; i++) {
01659         //Wire.beginTransmission(val[i]);
01660         regdata[i]= reg;
01661 
01662     }
01663     if( Wire.endTransmission() != 0 ) {
01664         return false;
01665     }
01666 
01667     return true;
01668 }*/
01669 
01670 uint8_t APDS9960::ReadDataByte(char reg)
01671 {
01672     char val;
01673     /* Indicate which register we want to read from */
01674     if (i2c_.write(APDS9960_I2C_ADDR, &reg, 1, true)) {
01675         //printf("write failed\n\r");
01676         return false;
01677     }
01678     /* Read from register */
01679     if(i2c_.read(APDS9960_I2C_ADDR, &val, 1)) {
01680         //printf("read failed\r\n");
01681         return false;
01682     }
01683 
01684     /*while (Wire.available()) {
01685         val = Wire.read();
01686     }*/
01687     // printf("The register we are reading from is %u\r\n",reg);
01688    // printf("The read value is %u\r\n", *val);
01689 
01690     return val;
01691 }
01692 
01693 int APDS9960::ReadDataBlock(uint8_t reg, uint8_t *val, unsigned int len)
01694 {
01695 
01696     /*Indicate which register we want to read from */
01697     if (i2c_.write(APDS9960_I2C_ADDR,(char*) &reg,1)) {
01698         return -1;
01699     }
01700     if ( len == 0) {
01701         return -1;
01702     }
01703     /*Read block data */
01704     //Wire.requestFrom(APDS9960_I2C_ADDR, len);
01705     // while (i < len) {
01706     if (i2c_.read(APDS9960_I2C_ADDR,(char*) val, len) != 0) {
01707         return -1;
01708     }
01709 
01710     // i++;
01711     //}
01712     /* if (i > len) {
01713          return -1;
01714      }*/
01715 
01716     return len;
01717 }