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.
Fork of SFE_APDS9960 by
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 Mon Jul 18 2022 11:13:42 by
1.7.2
