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