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