Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed SDFileSystem wave_player
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 }
Generated on Wed Jul 13 2022 05:03:27 by
1.7.2
Sparkfun RGB and Gesture Sensor APDS-9960