| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208 |
- /**
- * @file SparkFun_APDS-9960.cpp
- * @brief Library for the SparkFun APDS-9960 breakout board
- * @author Shawn Hymel (SparkFun Electronics)
- *
- * @copyright This code is public domain but you buy me a beer if you use
- * this and we meet someday (Beerware license).
- *
- * This library interfaces the Avago APDS-9960 to Arduino over I2C. The library
- * relies on the Arduino Wire (I2C) library. to use the library, instantiate an
- * APDS9960 object, call init(), and call the appropriate functions.
- *
- * APDS-9960 current draw tests (default parameters):
- * Off: 1mA
- * Waiting for gesture: 14mA
- * Gesture in progress: 35mA
- */
- #include <Arduino.h>
- #include <Wire.h>
- #include "SparkFun_APDS9960.h"
- /**
- * @brief Constructor - Instantiates SparkFun_APDS9960 object
- */
- SparkFun_APDS9960::SparkFun_APDS9960()
- {
- gesture_ud_delta_ = 0;
- gesture_lr_delta_ = 0;
- gesture_ud_count_ = 0;
- gesture_lr_count_ = 0;
- gesture_near_count_ = 0;
- gesture_far_count_ = 0;
- gesture_state_ = 0;
- gesture_motion_ = DIR_NONE;
- }
- /**
- * @brief Destructor
- */
- SparkFun_APDS9960::~SparkFun_APDS9960()
- {
- }
- /**
- * @brief Configures I2C communications and initializes registers to defaults
- *
- * @return True if initialized successfully. False otherwise.
- */
- bool SparkFun_APDS9960::init()
- {
- uint8_t id;
- /* Initialize I2C */
- Wire.begin();
- /* Read ID register and check against known values for APDS-9960 */
- if( !wireReadDataByte(APDS9960_ID, id) ) {
- return false;
- }
- if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2 || id == APDS9960_ID_3) ) {
- return false;
- }
- /* Set ENABLE register to 0 (disable all features) */
- if( !setMode(ALL, OFF) ) {
- return false;
- }
- /* Set default values for ambient light and proximity registers */
- if( !wireWriteDataByte(APDS9960_ATIME, DEFAULT_ATIME) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_WTIME, DEFAULT_WTIME) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_PROX_PPULSE) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_CONFIG1, DEFAULT_CONFIG1) ) {
- return false;
- }
- if( !setLEDDrive(DEFAULT_LDRIVE) ) {
- return false;
- }
- if( !setProximityGain(DEFAULT_PGAIN) ) {
- return false;
- }
- if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
- return false;
- }
- if( !setProxIntLowThresh(DEFAULT_PILT) ) {
- return false;
- }
- if( !setProxIntHighThresh(DEFAULT_PIHT) ) {
- return false;
- }
- if( !setLightIntLowThreshold(DEFAULT_AILT) ) {
- return false;
- }
- if( !setLightIntHighThreshold(DEFAULT_AIHT) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_PERS, DEFAULT_PERS) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_CONFIG2, DEFAULT_CONFIG2) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_CONFIG3, DEFAULT_CONFIG3) ) {
- return false;
- }
- /* Set default values for gesture sense registers */
- if( !setGestureEnterThresh(DEFAULT_GPENTH) ) {
- return false;
- }
- if( !setGestureExitThresh(DEFAULT_GEXTH) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GCONF1, DEFAULT_GCONF1) ) {
- return false;
- }
- if( !setGestureGain(DEFAULT_GGAIN) ) {
- return false;
- }
- if( !setGestureLEDDrive(DEFAULT_GLDRIVE) ) {
- return false;
- }
- if( !setGestureWaitTime(DEFAULT_GWTIME) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GPULSE, DEFAULT_GPULSE) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_GCONF3, DEFAULT_GCONF3) ) {
- return false;
- }
- if( !setGestureIntEnable(DEFAULT_GIEN) ) {
- return false;
- }
- #if 0
- /* Gesture config register dump */
- uint8_t reg;
- uint8_t val;
- for(reg = 0x80; reg <= 0xAF; reg++) {
- if( (reg != 0x82) && \
- (reg != 0x8A) && \
- (reg != 0x91) && \
- (reg != 0xA8) && \
- (reg != 0xAC) && \
- (reg != 0xAD) )
- {
- wireReadDataByte(reg, val);
- Serial.print(reg, HEX);
- Serial.print(": 0x");
- Serial.println(val, HEX);
- }
- }
- for(reg = 0xE4; reg <= 0xE7; reg++) {
- wireReadDataByte(reg, val);
- Serial.print(reg, HEX);
- Serial.print(": 0x");
- Serial.println(val, HEX);
- }
- #endif
- return true;
- }
- /*******************************************************************************
- * Public methods for controlling the APDS-9960
- ******************************************************************************/
- /**
- * @brief Reads and returns the contents of the ENABLE register
- *
- * @return Contents of the ENABLE register. 0xFF if error.
- */
- uint8_t SparkFun_APDS9960::getMode()
- {
- uint8_t enable_value;
- /* Read current ENABLE register */
- if( !wireReadDataByte(APDS9960_ENABLE, enable_value) ) {
- return ERROR;
- }
- return enable_value;
- }
- /**
- * @brief Enables or disables a feature in the APDS-9960
- *
- * @param[in] mode which feature to enable
- * @param[in] enable ON (1) or OFF (0)
- * @return True if operation success. False otherwise.
- */
- bool SparkFun_APDS9960::setMode(uint8_t mode, uint8_t enable)
- {
- uint8_t reg_val;
- /* Read current ENABLE register */
- reg_val = getMode();
- if( reg_val == ERROR ) {
- return false;
- }
- /* Change bit(s) in ENABLE register */
- enable = enable & 0x01;
- if(mode <= 6 ) {
- if (enable) {
- reg_val |= (1 << mode);
- } else {
- reg_val &= ~(1 << mode);
- }
- } else if( mode == ALL ) {
- if (enable) {
- reg_val = 0x7F;
- } else {
- reg_val = 0x00;
- }
- }
- /* Write value back to ENABLE register */
- if( !wireWriteDataByte(APDS9960_ENABLE, reg_val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Starts the light (R/G/B/Ambient) sensor on the APDS-9960
- *
- * @param[in] interrupts true to enable hardware interrupt on high or low light
- * @return True if sensor enabled correctly. False on error.
- */
- bool SparkFun_APDS9960::enableLightSensor(bool interrupts)
- {
- /* Set default gain, interrupts, enable power, and enable sensor */
- if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
- return false;
- }
- if( interrupts ) {
- if( !setAmbientLightIntEnable(1) ) {
- return false;
- }
- } else {
- if( !setAmbientLightIntEnable(0) ) {
- return false;
- }
- }
- if( !enablePower() ){
- return false;
- }
- if( !setMode(AMBIENT_LIGHT, 1) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Ends the light sensor on the APDS-9960
- *
- * @return True if sensor disabled correctly. False on error.
- */
- bool SparkFun_APDS9960::disableLightSensor()
- {
- if( !setAmbientLightIntEnable(0) ) {
- return false;
- }
- if( !setMode(AMBIENT_LIGHT, 0) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Starts the proximity sensor on the APDS-9960
- *
- * @param[in] interrupts true to enable hardware external interrupt on proximity
- * @return True if sensor enabled correctly. False on error.
- */
- bool SparkFun_APDS9960::enableProximitySensor(bool interrupts)
- {
- /* Set default gain, LED, interrupts, enable power, and enable sensor */
- if( !setProximityGain(DEFAULT_PGAIN) ) {
- return false;
- }
- if( !setLEDDrive(DEFAULT_LDRIVE) ) {
- return false;
- }
- if( interrupts ) {
- if( !setProximityIntEnable(1) ) {
- return false;
- }
- } else {
- if( !setProximityIntEnable(0) ) {
- return false;
- }
- }
- if( !enablePower() ){
- return false;
- }
- if( !setMode(PROXIMITY, 1) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Ends the proximity sensor on the APDS-9960
- *
- * @return True if sensor disabled correctly. False on error.
- */
- bool SparkFun_APDS9960::disableProximitySensor()
- {
- if( !setProximityIntEnable(0) ) {
- return false;
- }
- if( !setMode(PROXIMITY, 0) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Starts the gesture recognition engine on the APDS-9960
- *
- * @param[in] interrupts true to enable hardware external interrupt on gesture
- * @return True if engine enabled correctly. False on error.
- */
- bool SparkFun_APDS9960::enableGestureSensor(bool interrupts)
- {
- /* Enable gesture mode
- Set ENABLE to 0 (power off)
- Set WTIME to 0xFF
- Set AUX to LED_BOOST_300
- Enable PON, WEN, PEN, GEN in ENABLE
- */
- resetGestureParameters();
- if( !wireWriteDataByte(APDS9960_WTIME, 0xFF) ) {
- return false;
- }
- if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) {
- return false;
- }
- if( !setLEDBoost(LED_BOOST_300) ) {
- return false;
- }
- if( interrupts ) {
- if( !setGestureIntEnable(1) ) {
- return false;
- }
- } else {
- if( !setGestureIntEnable(0) ) {
- return false;
- }
- }
- if( !setGestureMode(1) ) {
- return false;
- }
- if( !enablePower() ){
- return false;
- }
- if( !setMode(WAIT, 1) ) {
- return false;
- }
- if( !setMode(PROXIMITY, 1) ) {
- return false;
- }
- if( !setMode(GESTURE, 1) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Ends the gesture recognition engine on the APDS-9960
- *
- * @return True if engine disabled correctly. False on error.
- */
- bool SparkFun_APDS9960::disableGestureSensor()
- {
- resetGestureParameters();
- if( !setGestureIntEnable(0) ) {
- return false;
- }
- if( !setGestureMode(0) ) {
- return false;
- }
- if( !setMode(GESTURE, 0) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Determines if there is a gesture available for reading
- *
- * @return True if gesture available. False otherwise.
- */
- bool SparkFun_APDS9960::isGestureAvailable()
- {
- uint8_t val;
- /* Read value from GSTATUS register */
- if( !wireReadDataByte(APDS9960_GSTATUS, val) ) {
- return ERROR;
- }
- /* Shift and mask out GVALID bit */
- val &= APDS9960_GVALID;
- /* Return true/false based on GVALID bit */
- if( val == 1) {
- return true;
- } else {
- return false;
- }
- }
- /**
- * @brief Processes a gesture event and returns best guessed gesture
- *
- * @return Number corresponding to gesture. -1 on error.
- */
- int SparkFun_APDS9960::readGesture()
- {
- uint8_t fifo_level = 0;
- uint8_t fifo_data[128];
- uint8_t gstatus;
- int bytes_read = 0;
- int motion;
- int i;
- /* Make sure that power and gesture is on and data is valid */
- if( !isGestureAvailable() || !(getMode() & 0b01000001) ) {
- return DIR_NONE;
- }
- /* Keep looping as long as gesture data is valid */
- while(1) {
- /* Wait some time to collect next batch of FIFO data */
- delay(FIFO_PAUSE_TIME);
- /* Get the contents of the STATUS register. Is data still valid? */
- if( !wireReadDataByte(APDS9960_GSTATUS, gstatus) ) {
- return ERROR;
- }
- /* If we have valid data, read in FIFO */
- if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) {
- /* Read the current FIFO level */
- if( !wireReadDataByte(APDS9960_GFLVL, fifo_level) ) {
- return ERROR;
- }
- #if DEBUG
- Serial.print("FIFO Level: ");
- Serial.println(fifo_level);
- #endif
- /* If there's stuff in the FIFO, read it into our data block */
- if( fifo_level > 0) {
- bytes_read = wireReadDataBlock( APDS9960_GFIFO_U,
- (uint8_t*)fifo_data,
- (fifo_level * 4) );
- if( bytes_read == -1 ) {
- return ERROR;
- }
- #if DEBUG
- Serial.print("FIFO Dump: ");
- for ( i = 0; i < bytes_read; i++ ) {
- Serial.print(fifo_data[i]);
- Serial.print(" ");
- }
- Serial.println();
- #endif
- /* If at least 1 set of data, sort the data into U/D/L/R */
- if( bytes_read >= 4 ) {
- for( i = 0; i < bytes_read; i += 4 ) {
- gesture_data_.u_data[gesture_data_.index] = \
- fifo_data[i + 0];
- gesture_data_.d_data[gesture_data_.index] = \
- fifo_data[i + 1];
- gesture_data_.l_data[gesture_data_.index] = \
- fifo_data[i + 2];
- gesture_data_.r_data[gesture_data_.index] = \
- fifo_data[i + 3];
- gesture_data_.index++;
- gesture_data_.total_gestures++;
- }
- #if DEBUG
- Serial.print("Up Data: ");
- for ( i = 0; i < gesture_data_.total_gestures; i++ ) {
- Serial.print(gesture_data_.u_data[i]);
- Serial.print(" ");
- }
- Serial.println();
- #endif
- /* Filter and process gesture data. Decode near/far state */
- if( processGestureData() ) {
- if( decodeGesture() ) {
- //***TODO: U-Turn Gestures
- #if DEBUG
- //Serial.println(gesture_motion_);
- #endif
- }
- }
- /* Reset data */
- gesture_data_.index = 0;
- gesture_data_.total_gestures = 0;
- }
- }
- } else {
- /* Determine best guessed gesture and clean up */
- delay(FIFO_PAUSE_TIME);
- decodeGesture();
- motion = gesture_motion_;
- #if DEBUG
- Serial.print("END: ");
- Serial.println(gesture_motion_);
- #endif
- resetGestureParameters();
- return motion;
- }
- }
- }
- /**
- * Turn the APDS-9960 on
- *
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::enablePower()
- {
- if( !setMode(POWER, 1) ) {
- return false;
- }
- return true;
- }
- /**
- * Turn the APDS-9960 off
- *
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::disablePower()
- {
- if( !setMode(POWER, 0) ) {
- return false;
- }
- return true;
- }
- /*******************************************************************************
- * Ambient light and color sensor controls
- ******************************************************************************/
- /**
- * @brief Reads the ambient (clear) light level as a 16-bit value
- *
- * @param[out] val value of the light sensor.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::readAmbientLight(uint16_t &val)
- {
- uint8_t val_byte;
- val = 0;
- /* Read value from clear channel, low byte register */
- if( !wireReadDataByte(APDS9960_CDATAL, val_byte) ) {
- return false;
- }
- val = val_byte;
- /* Read value from clear channel, high byte register */
- if( !wireReadDataByte(APDS9960_CDATAH, val_byte) ) {
- return false;
- }
- val = val + ((uint16_t)val_byte << 8);
- return true;
- }
- /**
- * @brief Reads the red light level as a 16-bit value
- *
- * @param[out] val value of the light sensor.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::readRedLight(uint16_t &val)
- {
- uint8_t val_byte;
- val = 0;
- /* Read value from clear channel, low byte register */
- if( !wireReadDataByte(APDS9960_RDATAL, val_byte) ) {
- return false;
- }
- val = val_byte;
- /* Read value from clear channel, high byte register */
- if( !wireReadDataByte(APDS9960_RDATAH, val_byte) ) {
- return false;
- }
- val = val + ((uint16_t)val_byte << 8);
- return true;
- }
- /**
- * @brief Reads the green light level as a 16-bit value
- *
- * @param[out] val value of the light sensor.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::readGreenLight(uint16_t &val)
- {
- uint8_t val_byte;
- val = 0;
- /* Read value from clear channel, low byte register */
- if( !wireReadDataByte(APDS9960_GDATAL, val_byte) ) {
- return false;
- }
- val = val_byte;
- /* Read value from clear channel, high byte register */
- if( !wireReadDataByte(APDS9960_GDATAH, val_byte) ) {
- return false;
- }
- val = val + ((uint16_t)val_byte << 8);
- return true;
- }
- /**
- * @brief Reads the red light level as a 16-bit value
- *
- * @param[out] val value of the light sensor.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::readBlueLight(uint16_t &val)
- {
- uint8_t val_byte;
- val = 0;
- /* Read value from clear channel, low byte register */
- if( !wireReadDataByte(APDS9960_BDATAL, val_byte) ) {
- return false;
- }
- val = val_byte;
- /* Read value from clear channel, high byte register */
- if( !wireReadDataByte(APDS9960_BDATAH, val_byte) ) {
- return false;
- }
- val = val + ((uint16_t)val_byte << 8);
- return true;
- }
- /*******************************************************************************
- * Proximity sensor controls
- ******************************************************************************/
- /**
- * @brief Reads the proximity level as an 8-bit value
- *
- * @param[out] val value of the proximity sensor.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::readProximity(uint8_t &val)
- {
- val = 0;
- /* Read value from proximity data register */
- if( !wireReadDataByte(APDS9960_PDATA, val) ) {
- return false;
- }
- return true;
- }
- /*******************************************************************************
- * High-level gesture controls
- ******************************************************************************/
- /**
- * @brief Resets all the parameters in the gesture data member
- */
- void SparkFun_APDS9960::resetGestureParameters()
- {
- gesture_data_.index = 0;
- gesture_data_.total_gestures = 0;
- gesture_ud_delta_ = 0;
- gesture_lr_delta_ = 0;
- gesture_ud_count_ = 0;
- gesture_lr_count_ = 0;
- gesture_near_count_ = 0;
- gesture_far_count_ = 0;
- gesture_state_ = 0;
- gesture_motion_ = DIR_NONE;
- }
- /**
- * @brief Processes the raw gesture data to determine swipe direction
- *
- * @return True if near or far state seen. False otherwise.
- */
- bool SparkFun_APDS9960::processGestureData()
- {
- uint8_t u_first = 1;
- uint8_t d_first = 1;
- uint8_t l_first = 1;
- uint8_t r_first = 1;
- uint8_t u_last = 1;
- uint8_t d_last = 1;
- uint8_t l_last = 1;
- uint8_t r_last = 1;
- int ud_ratio_first;
- int lr_ratio_first;
- int ud_ratio_last;
- int lr_ratio_last;
- int ud_delta;
- int lr_delta;
- int i;
- /* If we have less than 4 total gestures, that's not enough */
- if( gesture_data_.total_gestures <= 4 ) {
- return false;
- }
- /* Check to make sure our data isn't out of bounds */
- if( (gesture_data_.total_gestures <= 32) && \
- (gesture_data_.total_gestures > 0) ) {
- /* Find the first value in U/D/L/R above the threshold */
- for( i = 0; i < gesture_data_.total_gestures; i++ ) {
- if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
- (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) ||
- (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
- (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
- u_first = gesture_data_.u_data[i];
- d_first = gesture_data_.d_data[i];
- l_first = gesture_data_.l_data[i];
- r_first = gesture_data_.r_data[i];
- break;
- }
- }
- /* Find the last value in U/D/L/R above the threshold */
- for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) {
- #if DEBUG
- Serial.print(F("Finding last: "));
- Serial.print(F("U:"));
- Serial.print(gesture_data_.u_data[i]);
- Serial.print(F(" D:"));
- Serial.print(gesture_data_.d_data[i]);
- Serial.print(F(" L:"));
- Serial.print(gesture_data_.l_data[i]);
- Serial.print(F(" R:"));
- Serial.println(gesture_data_.r_data[i]);
- #endif
- if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
- (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) ||
- (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
- (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
- u_last = gesture_data_.u_data[i];
- d_last = gesture_data_.d_data[i];
- l_last = gesture_data_.l_data[i];
- r_last = gesture_data_.r_data[i];
- break;
- }
- }
- }
- /* Calculate the first vs. last ratio of up/down and left/right */
- ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first);
- lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first);
- ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last);
- lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last);
- #if DEBUG
- Serial.print(F("Last Values: "));
- Serial.print(F("U:"));
- Serial.print(u_last);
- Serial.print(F(" D:"));
- Serial.print(d_last);
- Serial.print(F(" L:"));
- Serial.print(l_last);
- Serial.print(F(" R:"));
- Serial.println(r_last);
- Serial.print(F("Ratios: "));
- Serial.print(F("UD Fi: "));
- Serial.print(ud_ratio_first);
- Serial.print(F(" UD La: "));
- Serial.print(ud_ratio_last);
- Serial.print(F(" LR Fi: "));
- Serial.print(lr_ratio_first);
- Serial.print(F(" LR La: "));
- Serial.println(lr_ratio_last);
- #endif
- /* Determine the difference between the first and last ratios */
- ud_delta = ud_ratio_last - ud_ratio_first;
- lr_delta = lr_ratio_last - lr_ratio_first;
- #if DEBUG
- Serial.print("Deltas: ");
- Serial.print("UD: ");
- Serial.print(ud_delta);
- Serial.print(" LR: ");
- Serial.println(lr_delta);
- #endif
- /* Accumulate the UD and LR delta values */
- gesture_ud_delta_ += ud_delta;
- gesture_lr_delta_ += lr_delta;
- #if DEBUG
- Serial.print("Accumulations: ");
- Serial.print("UD: ");
- Serial.print(gesture_ud_delta_);
- Serial.print(" LR: ");
- Serial.println(gesture_lr_delta_);
- #endif
- /* Determine U/D gesture */
- if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) {
- gesture_ud_count_ = 1;
- } else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) {
- gesture_ud_count_ = -1;
- } else {
- gesture_ud_count_ = 0;
- }
- /* Determine L/R gesture */
- if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) {
- gesture_lr_count_ = 1;
- } else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) {
- gesture_lr_count_ = -1;
- } else {
- gesture_lr_count_ = 0;
- }
- /* Determine Near/Far gesture */
- if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) {
- if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
- (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
- if( (ud_delta == 0) && (lr_delta == 0) ) {
- gesture_near_count_++;
- } else if( (ud_delta != 0) || (lr_delta != 0) ) {
- gesture_far_count_++;
- }
- if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) {
- if( (ud_delta == 0) && (lr_delta == 0) ) {
- gesture_state_ = NEAR_STATE;
- } else if( (ud_delta != 0) && (lr_delta != 0) ) {
- gesture_state_ = FAR_STATE;
- }
- return true;
- }
- }
- } else {
- if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
- (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
- if( (ud_delta == 0) && (lr_delta == 0) ) {
- gesture_near_count_++;
- }
- if( gesture_near_count_ >= 10 ) {
- gesture_ud_count_ = 0;
- gesture_lr_count_ = 0;
- gesture_ud_delta_ = 0;
- gesture_lr_delta_ = 0;
- }
- }
- }
- #if DEBUG
- Serial.print("UD_CT: ");
- Serial.print(gesture_ud_count_);
- Serial.print(" LR_CT: ");
- Serial.print(gesture_lr_count_);
- Serial.print(" NEAR_CT: ");
- Serial.print(gesture_near_count_);
- Serial.print(" FAR_CT: ");
- Serial.println(gesture_far_count_);
- Serial.println("----------");
- #endif
- return false;
- }
- /**
- * @brief Determines swipe direction or near/far state
- *
- * @return True if near/far event. False otherwise.
- */
- bool SparkFun_APDS9960::decodeGesture()
- {
- /* Return if near or far event is detected */
- if( gesture_state_ == NEAR_STATE ) {
- gesture_motion_ = DIR_NEAR;
- return true;
- } else if ( gesture_state_ == FAR_STATE ) {
- gesture_motion_ = DIR_FAR;
- return true;
- }
- /* Determine swipe direction */
- if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) {
- gesture_motion_ = DIR_UP;
- } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) {
- gesture_motion_ = DIR_DOWN;
- } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) {
- gesture_motion_ = DIR_RIGHT;
- } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) {
- gesture_motion_ = DIR_LEFT;
- } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) {
- if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
- gesture_motion_ = DIR_UP;
- } else {
- gesture_motion_ = DIR_RIGHT;
- }
- } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) {
- if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
- gesture_motion_ = DIR_DOWN;
- } else {
- gesture_motion_ = DIR_LEFT;
- }
- } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) {
- if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
- gesture_motion_ = DIR_UP;
- } else {
- gesture_motion_ = DIR_LEFT;
- }
- } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) {
- if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
- gesture_motion_ = DIR_DOWN;
- } else {
- gesture_motion_ = DIR_RIGHT;
- }
- } else {
- return false;
- }
- return true;
- }
- /*******************************************************************************
- * Getters and setters for register values
- ******************************************************************************/
- /**
- * @brief Returns the lower threshold for proximity detection
- *
- * @return lower threshold
- */
- uint8_t SparkFun_APDS9960::getProxIntLowThresh()
- {
- uint8_t val;
- /* Read value from PILT register */
- if( !wireReadDataByte(APDS9960_PILT, val) ) {
- val = 0;
- }
- return val;
- }
- /**
- * @brief Sets the lower threshold for proximity detection
- *
- * @param[in] threshold the lower proximity threshold
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProxIntLowThresh(uint8_t threshold)
- {
- if( !wireWriteDataByte(APDS9960_PILT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Returns the high threshold for proximity detection
- *
- * @return high threshold
- */
- uint8_t SparkFun_APDS9960::getProxIntHighThresh()
- {
- uint8_t val;
- /* Read value from PIHT register */
- if( !wireReadDataByte(APDS9960_PIHT, val) ) {
- val = 0;
- }
- return val;
- }
- /**
- * @brief Sets the high threshold for proximity detection
- *
- * @param[in] threshold the high proximity threshold
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProxIntHighThresh(uint8_t threshold)
- {
- if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Returns LED drive strength for proximity and ALS
- *
- * Value LED Current
- * 0 100 mA
- * 1 50 mA
- * 2 25 mA
- * 3 12.5 mA
- *
- * @return the value of the LED drive strength. 0xFF on failure.
- */
- uint8_t SparkFun_APDS9960::getLEDDrive()
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return ERROR;
- }
- /* Shift and mask out LED drive bits */
- val = (val >> 6) & 0b00000011;
- return val;
- }
- /**
- * @brief Sets the LED drive strength for proximity and ALS
- *
- * Value LED Current
- * 0 100 mA
- * 1 50 mA
- * 2 25 mA
- * 3 12.5 mA
- *
- * @param[in] drive the value (0-3) for the LED drive strength
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setLEDDrive(uint8_t drive)
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- drive &= 0b00000011;
- drive = drive << 6;
- val &= 0b00111111;
- val |= drive;
- /* Write register value back into CONTROL register */
- if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Returns receiver gain for proximity detection
- *
- * Value Gain
- * 0 1x
- * 1 2x
- * 2 4x
- * 3 8x
- *
- * @return the value of the proximity gain. 0xFF on failure.
- */
- uint8_t SparkFun_APDS9960::getProximityGain()
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return ERROR;
- }
- /* Shift and mask out PDRIVE bits */
- val = (val >> 2) & 0b00000011;
- return val;
- }
- /**
- * @brief Sets the receiver gain for proximity detection
- *
- * Value Gain
- * 0 1x
- * 1 2x
- * 2 4x
- * 3 8x
- *
- * @param[in] drive the value (0-3) for the gain
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProximityGain(uint8_t drive)
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- drive &= 0b00000011;
- drive = drive << 2;
- val &= 0b11110011;
- val |= drive;
- /* Write register value back into CONTROL register */
- if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Returns receiver gain for the ambient light sensor (ALS)
- *
- * Value Gain
- * 0 1x
- * 1 4x
- * 2 16x
- * 3 64x
- *
- * @return the value of the ALS gain. 0xFF on failure.
- */
- uint8_t SparkFun_APDS9960::getAmbientLightGain()
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return ERROR;
- }
- /* Shift and mask out ADRIVE bits */
- val &= 0b00000011;
- return val;
- }
- /**
- * @brief Sets the receiver gain for the ambient light sensor (ALS)
- *
- * Value Gain
- * 0 1x
- * 1 4x
- * 2 16x
- * 3 64x
- *
- * @param[in] drive the value (0-3) for the gain
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setAmbientLightGain(uint8_t drive)
- {
- uint8_t val;
- /* Read value from CONTROL register */
- if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- drive &= 0b00000011;
- val &= 0b11111100;
- val |= drive;
- /* Write register value back into CONTROL register */
- if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Get the current LED boost value
- *
- * Value Boost Current
- * 0 100%
- * 1 150%
- * 2 200%
- * 3 300%
- *
- * @return The LED boost value. 0xFF on failure.
- */
- uint8_t SparkFun_APDS9960::getLEDBoost()
- {
- uint8_t val;
- /* Read value from CONFIG2 register */
- if( !wireReadDataByte(APDS9960_CONFIG2, val) ) {
- return ERROR;
- }
- /* Shift and mask out LED_BOOST bits */
- val = (val >> 4) & 0b00000011;
- return val;
- }
- /**
- * @brief Sets the LED current boost value
- *
- * Value Boost Current
- * 0 100%
- * 1 150%
- * 2 200%
- * 3 300%
- *
- * @param[in] drive the value (0-3) for current boost (100-300%)
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setLEDBoost(uint8_t boost)
- {
- uint8_t val;
- /* Read value from CONFIG2 register */
- if( !wireReadDataByte(APDS9960_CONFIG2, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- boost &= 0b00000011;
- boost = boost << 4;
- val &= 0b11001111;
- val |= boost;
- /* Write register value back into CONFIG2 register */
- if( !wireWriteDataByte(APDS9960_CONFIG2, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets proximity gain compensation enable
- *
- * @return 1 if compensation is enabled. 0 if not. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getProxGainCompEnable()
- {
- uint8_t val;
- /* Read value from CONFIG3 register */
- if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
- return ERROR;
- }
- /* Shift and mask out PCMP bits */
- val = (val >> 5) & 0b00000001;
- return val;
- }
- /**
- * @brief Sets the proximity gain compensation enable
- *
- * @param[in] enable 1 to enable compensation. 0 to disable compensation.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProxGainCompEnable(uint8_t enable)
- {
- uint8_t val;
- /* Read value from CONFIG3 register */
- if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- enable &= 0b00000001;
- enable = enable << 5;
- val &= 0b11011111;
- val |= enable;
- /* Write register value back into CONFIG3 register */
- if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the current mask for enabled/disabled proximity photodiodes
- *
- * 1 = disabled, 0 = enabled
- * Bit Photodiode
- * 3 UP
- * 2 DOWN
- * 1 LEFT
- * 0 RIGHT
- *
- * @return Current proximity mask for photodiodes. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getProxPhotoMask()
- {
- uint8_t val;
- /* Read value from CONFIG3 register */
- if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
- return ERROR;
- }
- /* Mask out photodiode enable mask bits */
- val &= 0b00001111;
- return val;
- }
- /**
- * @brief Sets the mask for enabling/disabling proximity photodiodes
- *
- * 1 = disabled, 0 = enabled
- * Bit Photodiode
- * 3 UP
- * 2 DOWN
- * 1 LEFT
- * 0 RIGHT
- *
- * @param[in] mask 4-bit mask value
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProxPhotoMask(uint8_t mask)
- {
- uint8_t val;
- /* Read value from CONFIG3 register */
- if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- mask &= 0b00001111;
- val &= 0b11110000;
- val |= mask;
- /* Write register value back into CONFIG3 register */
- if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the entry proximity threshold for gesture sensing
- *
- * @return Current entry proximity threshold.
- */
- uint8_t SparkFun_APDS9960::getGestureEnterThresh()
- {
- uint8_t val;
- /* Read value from GPENTH register */
- if( !wireReadDataByte(APDS9960_GPENTH, val) ) {
- val = 0;
- }
- return val;
- }
- /**
- * @brief Sets the entry proximity threshold for gesture sensing
- *
- * @param[in] threshold proximity value needed to start gesture mode
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureEnterThresh(uint8_t threshold)
- {
- if( !wireWriteDataByte(APDS9960_GPENTH, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the exit proximity threshold for gesture sensing
- *
- * @return Current exit proximity threshold.
- */
- uint8_t SparkFun_APDS9960::getGestureExitThresh()
- {
- uint8_t val;
- /* Read value from GEXTH register */
- if( !wireReadDataByte(APDS9960_GEXTH, val) ) {
- val = 0;
- }
- return val;
- }
- /**
- * @brief Sets the exit proximity threshold for gesture sensing
- *
- * @param[in] threshold proximity value needed to end gesture mode
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureExitThresh(uint8_t threshold)
- {
- if( !wireWriteDataByte(APDS9960_GEXTH, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the gain of the photodiode during gesture mode
- *
- * Value Gain
- * 0 1x
- * 1 2x
- * 2 4x
- * 3 8x
- *
- * @return the current photodiode gain. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getGestureGain()
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return ERROR;
- }
- /* Shift and mask out GGAIN bits */
- val = (val >> 5) & 0b00000011;
- return val;
- }
- /**
- * @brief Sets the gain of the photodiode during gesture mode
- *
- * Value Gain
- * 0 1x
- * 1 2x
- * 2 4x
- * 3 8x
- *
- * @param[in] gain the value for the photodiode gain
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureGain(uint8_t gain)
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- gain &= 0b00000011;
- gain = gain << 5;
- val &= 0b10011111;
- val |= gain;
- /* Write register value back into GCONF2 register */
- if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the drive current of the LED during gesture mode
- *
- * Value LED Current
- * 0 100 mA
- * 1 50 mA
- * 2 25 mA
- * 3 12.5 mA
- *
- * @return the LED drive current value. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getGestureLEDDrive()
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return ERROR;
- }
- /* Shift and mask out GLDRIVE bits */
- val = (val >> 3) & 0b00000011;
- return val;
- }
- /**
- * @brief Sets the LED drive current during gesture mode
- *
- * Value LED Current
- * 0 100 mA
- * 1 50 mA
- * 2 25 mA
- * 3 12.5 mA
- *
- * @param[in] drive the value for the LED drive current
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureLEDDrive(uint8_t drive)
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- drive &= 0b00000011;
- drive = drive << 3;
- val &= 0b11100111;
- val |= drive;
- /* Write register value back into GCONF2 register */
- if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the time in low power mode between gesture detections
- *
- * Value Wait time
- * 0 0 ms
- * 1 2.8 ms
- * 2 5.6 ms
- * 3 8.4 ms
- * 4 14.0 ms
- * 5 22.4 ms
- * 6 30.8 ms
- * 7 39.2 ms
- *
- * @return the current wait time between gestures. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getGestureWaitTime()
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return ERROR;
- }
- /* Mask out GWTIME bits */
- val &= 0b00000111;
- return val;
- }
- /**
- * @brief Sets the time in low power mode between gesture detections
- *
- * Value Wait time
- * 0 0 ms
- * 1 2.8 ms
- * 2 5.6 ms
- * 3 8.4 ms
- * 4 14.0 ms
- * 5 22.4 ms
- * 6 30.8 ms
- * 7 39.2 ms
- *
- * @param[in] the value for the wait time
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureWaitTime(uint8_t time)
- {
- uint8_t val;
- /* Read value from GCONF2 register */
- if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- time &= 0b00000111;
- val &= 0b11111000;
- val |= time;
- /* Write register value back into GCONF2 register */
- if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the low threshold for ambient light interrupts
- *
- * @param[out] threshold current low threshold stored on the APDS-9960
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::getLightIntLowThreshold(uint16_t &threshold)
- {
- uint8_t val_byte;
- threshold = 0;
- /* Read value from ambient light low threshold, low byte register */
- if( !wireReadDataByte(APDS9960_AILTL, val_byte) ) {
- return false;
- }
- threshold = val_byte;
- /* Read value from ambient light low threshold, high byte register */
- if( !wireReadDataByte(APDS9960_AILTH, val_byte) ) {
- return false;
- }
- threshold = threshold + ((uint16_t)val_byte << 8);
- return true;
- }
- /**
- * @brief Sets the low threshold for ambient light interrupts
- *
- * @param[in] threshold low threshold value for interrupt to trigger
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setLightIntLowThreshold(uint16_t threshold)
- {
- uint8_t val_low;
- uint8_t val_high;
- /* Break 16-bit threshold into 2 8-bit values */
- val_low = threshold & 0x00FF;
- val_high = (threshold & 0xFF00) >> 8;
- /* Write low byte */
- if( !wireWriteDataByte(APDS9960_AILTL, val_low) ) {
- return false;
- }
- /* Write high byte */
- if( !wireWriteDataByte(APDS9960_AILTH, val_high) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the high threshold for ambient light interrupts
- *
- * @param[out] threshold current low threshold stored on the APDS-9960
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::getLightIntHighThreshold(uint16_t &threshold)
- {
- uint8_t val_byte;
- threshold = 0;
- /* Read value from ambient light high threshold, low byte register */
- if( !wireReadDataByte(APDS9960_AIHTL, val_byte) ) {
- return false;
- }
- threshold = val_byte;
- /* Read value from ambient light high threshold, high byte register */
- if( !wireReadDataByte(APDS9960_AIHTH, val_byte) ) {
- return false;
- }
- threshold = threshold + ((uint16_t)val_byte << 8);
- return true;
- }
- /**
- * @brief Sets the high threshold for ambient light interrupts
- *
- * @param[in] threshold high threshold value for interrupt to trigger
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setLightIntHighThreshold(uint16_t threshold)
- {
- uint8_t val_low;
- uint8_t val_high;
- /* Break 16-bit threshold into 2 8-bit values */
- val_low = threshold & 0x00FF;
- val_high = (threshold & 0xFF00) >> 8;
- /* Write low byte */
- if( !wireWriteDataByte(APDS9960_AIHTL, val_low) ) {
- return false;
- }
- /* Write high byte */
- if( !wireWriteDataByte(APDS9960_AIHTH, val_high) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the low threshold for proximity interrupts
- *
- * @param[out] threshold current low threshold stored on the APDS-9960
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::getProximityIntLowThreshold(uint8_t &threshold)
- {
- threshold = 0;
- /* Read value from proximity low threshold register */
- if( !wireReadDataByte(APDS9960_PILT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Sets the low threshold for proximity interrupts
- *
- * @param[in] threshold low threshold value for interrupt to trigger
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProximityIntLowThreshold(uint8_t threshold)
- {
- /* Write threshold value to register */
- if( !wireWriteDataByte(APDS9960_PILT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets the high threshold for proximity interrupts
- *
- * @param[out] threshold current low threshold stored on the APDS-9960
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::getProximityIntHighThreshold(uint8_t &threshold)
- {
- threshold = 0;
- /* Read value from proximity low threshold register */
- if( !wireReadDataByte(APDS9960_PIHT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Sets the high threshold for proximity interrupts
- *
- * @param[in] threshold high threshold value for interrupt to trigger
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProximityIntHighThreshold(uint8_t threshold)
- {
- /* Write threshold value to register */
- if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets if ambient light interrupts are enabled or not
- *
- * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getAmbientLightIntEnable()
- {
- uint8_t val;
- /* Read value from ENABLE register */
- if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
- return ERROR;
- }
- /* Shift and mask out AIEN bit */
- val = (val >> 4) & 0b00000001;
- return val;
- }
- /**
- * @brief Turns ambient light interrupts on or off
- *
- * @param[in] enable 1 to enable interrupts, 0 to turn them off
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setAmbientLightIntEnable(uint8_t enable)
- {
- uint8_t val;
- /* Read value from ENABLE register */
- if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- enable &= 0b00000001;
- enable = enable << 4;
- val &= 0b11101111;
- val |= enable;
- /* Write register value back into ENABLE register */
- if( !wireWriteDataByte(APDS9960_ENABLE, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets if proximity interrupts are enabled or not
- *
- * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getProximityIntEnable()
- {
- uint8_t val;
- /* Read value from ENABLE register */
- if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
- return ERROR;
- }
- /* Shift and mask out PIEN bit */
- val = (val >> 5) & 0b00000001;
- return val;
- }
- /**
- * @brief Turns proximity interrupts on or off
- *
- * @param[in] enable 1 to enable interrupts, 0 to turn them off
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setProximityIntEnable(uint8_t enable)
- {
- uint8_t val;
- /* Read value from ENABLE register */
- if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- enable &= 0b00000001;
- enable = enable << 5;
- val &= 0b11011111;
- val |= enable;
- /* Write register value back into ENABLE register */
- if( !wireWriteDataByte(APDS9960_ENABLE, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Gets if gesture interrupts are enabled or not
- *
- * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getGestureIntEnable()
- {
- uint8_t val;
- /* Read value from GCONF4 register */
- if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
- return ERROR;
- }
- /* Shift and mask out GIEN bit */
- val = (val >> 1) & 0b00000001;
- return val;
- }
- /**
- * @brief Turns gesture-related interrupts on or off
- *
- * @param[in] enable 1 to enable interrupts, 0 to turn them off
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureIntEnable(uint8_t enable)
- {
- uint8_t val;
- /* Read value from GCONF4 register */
- if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- enable &= 0b00000001;
- enable = enable << 1;
- val &= 0b11111101;
- val |= enable;
- /* Write register value back into GCONF4 register */
- if( !wireWriteDataByte(APDS9960_GCONF4, val) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Clears the ambient light interrupt
- *
- * @return True if operation completed successfully. False otherwise.
- */
- bool SparkFun_APDS9960::clearAmbientLightInt()
- {
- uint8_t throwaway;
- if( !wireReadDataByte(APDS9960_AICLEAR, throwaway) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Clears the proximity interrupt
- *
- * @return True if operation completed successfully. False otherwise.
- */
- bool SparkFun_APDS9960::clearProximityInt()
- {
- uint8_t throwaway;
- if( !wireReadDataByte(APDS9960_PICLEAR, throwaway) ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Tells if the gesture state machine is currently running
- *
- * @return 1 if gesture state machine is running, 0 if not. 0xFF on error.
- */
- uint8_t SparkFun_APDS9960::getGestureMode()
- {
- uint8_t val;
- /* Read value from GCONF4 register */
- if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
- return ERROR;
- }
- /* Mask out GMODE bit */
- val &= 0b00000001;
- return val;
- }
- /**
- * @brief Tells the state machine to either enter or exit gesture state machine
- *
- * @param[in] mode 1 to enter gesture state machine, 0 to exit.
- * @return True if operation successful. False otherwise.
- */
- bool SparkFun_APDS9960::setGestureMode(uint8_t mode)
- {
- uint8_t val;
- /* Read value from GCONF4 register */
- if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
- return false;
- }
- /* Set bits in register to given value */
- mode &= 0b00000001;
- val &= 0b11111110;
- val |= mode;
- /* Write register value back into GCONF4 register */
- if( !wireWriteDataByte(APDS9960_GCONF4, val) ) {
- return false;
- }
- return true;
- }
- /*******************************************************************************
- * Raw I2C Reads and Writes
- ******************************************************************************/
- /**
- * @brief Writes a single byte to the I2C device (no register)
- *
- * @param[in] val the 1-byte value to write to the I2C device
- * @return True if successful write operation. False otherwise.
- */
- bool SparkFun_APDS9960::wireWriteByte(uint8_t val)
- {
- Wire.beginTransmission(APDS9960_I2C_ADDR);
- Wire.write(val);
- if( Wire.endTransmission() != 0 ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Writes a single byte to the I2C device and specified register
- *
- * @param[in] reg the register in the I2C device to write to
- * @param[in] val the 1-byte value to write to the I2C device
- * @return True if successful write operation. False otherwise.
- */
- bool SparkFun_APDS9960::wireWriteDataByte(uint8_t reg, uint8_t val)
- {
- Wire.beginTransmission(APDS9960_I2C_ADDR);
- Wire.write(reg);
- Wire.write(val);
- if( Wire.endTransmission() != 0 ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Writes a block (array) of bytes to the I2C device and register
- *
- * @param[in] reg the register in the I2C device to write to
- * @param[in] val pointer to the beginning of the data byte array
- * @param[in] len the length (in bytes) of the data to write
- * @return True if successful write operation. False otherwise.
- */
- bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg,
- uint8_t *val,
- unsigned int len)
- {
- unsigned int i;
- Wire.beginTransmission(APDS9960_I2C_ADDR);
- Wire.write(reg);
- for(i = 0; i < len; i++) {
- Wire.write(val[i]);
- }
- if( Wire.endTransmission() != 0 ) {
- return false;
- }
- return true;
- }
- /**
- * @brief Reads a single byte from the I2C device and specified register
- *
- * @param[in] reg the register to read from
- * @param[out] the value returned from the register
- * @return True if successful read operation. False otherwise.
- */
- bool SparkFun_APDS9960::wireReadDataByte(uint8_t reg, uint8_t &val)
- {
- /* Indicate which register we want to read from */
- if (!wireWriteByte(reg)) {
- return false;
- }
- /* Read from register */
- Wire.requestFrom(APDS9960_I2C_ADDR, 1);
- while (Wire.available()) {
- val = Wire.read();
- }
- return true;
- }
- /**
- * @brief Reads a block (array) of bytes from the I2C device and register
- *
- * @param[in] reg the register to read from
- * @param[out] val pointer to the beginning of the data
- * @param[in] len number of bytes to read
- * @return Number of bytes read. -1 on read error.
- */
- int SparkFun_APDS9960::wireReadDataBlock( uint8_t reg,
- uint8_t *val,
- unsigned int len)
- {
- unsigned char i = 0;
- /* Indicate which register we want to read from */
- if (!wireWriteByte(reg)) {
- return -1;
- }
- /* Read block data */
- Wire.requestFrom(APDS9960_I2C_ADDR, len);
- while (Wire.available()) {
- if (i >= len) {
- return -1;
- }
- val[i] = Wire.read();
- i++;
- }
- return i;
- }
|