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