SparkFun_APDS9960.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208
  1. /**
  2. * @file SparkFun_APDS-9960.cpp
  3. * @brief Library for the SparkFun APDS-9960 breakout board
  4. * @author Shawn Hymel (SparkFun Electronics)
  5. *
  6. * @copyright This code is public domain but you buy me a beer if you use
  7. * this and we meet someday (Beerware license).
  8. *
  9. * This library interfaces the Avago APDS-9960 to Arduino over I2C. The library
  10. * relies on the Arduino Wire (I2C) library. to use the library, instantiate an
  11. * APDS9960 object, call init(), and call the appropriate functions.
  12. *
  13. * APDS-9960 current draw tests (default parameters):
  14. * Off: 1mA
  15. * Waiting for gesture: 14mA
  16. * Gesture in progress: 35mA
  17. */
  18. #include <Arduino.h>
  19. #include <Wire.h>
  20. #include "SparkFun_APDS9960.h"
  21. /**
  22. * @brief Constructor - Instantiates SparkFun_APDS9960 object
  23. */
  24. SparkFun_APDS9960::SparkFun_APDS9960()
  25. {
  26. gesture_ud_delta_ = 0;
  27. gesture_lr_delta_ = 0;
  28. gesture_ud_count_ = 0;
  29. gesture_lr_count_ = 0;
  30. gesture_near_count_ = 0;
  31. gesture_far_count_ = 0;
  32. gesture_state_ = 0;
  33. gesture_motion_ = DIR_NONE;
  34. }
  35. /**
  36. * @brief Destructor
  37. */
  38. SparkFun_APDS9960::~SparkFun_APDS9960()
  39. {
  40. }
  41. /**
  42. * @brief Configures I2C communications and initializes registers to defaults
  43. *
  44. * @return True if initialized successfully. False otherwise.
  45. */
  46. bool SparkFun_APDS9960::init()
  47. {
  48. uint8_t id;
  49. /* Initialize I2C */
  50. Wire.begin();
  51. /* Read ID register and check against known values for APDS-9960 */
  52. if( !wireReadDataByte(APDS9960_ID, id) ) {
  53. return false;
  54. }
  55. if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2 || id == APDS9960_ID_3) ) {
  56. return false;
  57. }
  58. /* Set ENABLE register to 0 (disable all features) */
  59. if( !setMode(ALL, OFF) ) {
  60. return false;
  61. }
  62. /* Set default values for ambient light and proximity registers */
  63. if( !wireWriteDataByte(APDS9960_ATIME, DEFAULT_ATIME) ) {
  64. return false;
  65. }
  66. if( !wireWriteDataByte(APDS9960_WTIME, DEFAULT_WTIME) ) {
  67. return false;
  68. }
  69. if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_PROX_PPULSE) ) {
  70. return false;
  71. }
  72. if( !wireWriteDataByte(APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR) ) {
  73. return false;
  74. }
  75. if( !wireWriteDataByte(APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL) ) {
  76. return false;
  77. }
  78. if( !wireWriteDataByte(APDS9960_CONFIG1, DEFAULT_CONFIG1) ) {
  79. return false;
  80. }
  81. if( !setLEDDrive(DEFAULT_LDRIVE) ) {
  82. return false;
  83. }
  84. if( !setProximityGain(DEFAULT_PGAIN) ) {
  85. return false;
  86. }
  87. if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
  88. return false;
  89. }
  90. if( !setProxIntLowThresh(DEFAULT_PILT) ) {
  91. return false;
  92. }
  93. if( !setProxIntHighThresh(DEFAULT_PIHT) ) {
  94. return false;
  95. }
  96. if( !setLightIntLowThreshold(DEFAULT_AILT) ) {
  97. return false;
  98. }
  99. if( !setLightIntHighThreshold(DEFAULT_AIHT) ) {
  100. return false;
  101. }
  102. if( !wireWriteDataByte(APDS9960_PERS, DEFAULT_PERS) ) {
  103. return false;
  104. }
  105. if( !wireWriteDataByte(APDS9960_CONFIG2, DEFAULT_CONFIG2) ) {
  106. return false;
  107. }
  108. if( !wireWriteDataByte(APDS9960_CONFIG3, DEFAULT_CONFIG3) ) {
  109. return false;
  110. }
  111. /* Set default values for gesture sense registers */
  112. if( !setGestureEnterThresh(DEFAULT_GPENTH) ) {
  113. return false;
  114. }
  115. if( !setGestureExitThresh(DEFAULT_GEXTH) ) {
  116. return false;
  117. }
  118. if( !wireWriteDataByte(APDS9960_GCONF1, DEFAULT_GCONF1) ) {
  119. return false;
  120. }
  121. if( !setGestureGain(DEFAULT_GGAIN) ) {
  122. return false;
  123. }
  124. if( !setGestureLEDDrive(DEFAULT_GLDRIVE) ) {
  125. return false;
  126. }
  127. if( !setGestureWaitTime(DEFAULT_GWTIME) ) {
  128. return false;
  129. }
  130. if( !wireWriteDataByte(APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) {
  131. return false;
  132. }
  133. if( !wireWriteDataByte(APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) {
  134. return false;
  135. }
  136. if( !wireWriteDataByte(APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) {
  137. return false;
  138. }
  139. if( !wireWriteDataByte(APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) {
  140. return false;
  141. }
  142. if( !wireWriteDataByte(APDS9960_GPULSE, DEFAULT_GPULSE) ) {
  143. return false;
  144. }
  145. if( !wireWriteDataByte(APDS9960_GCONF3, DEFAULT_GCONF3) ) {
  146. return false;
  147. }
  148. if( !setGestureIntEnable(DEFAULT_GIEN) ) {
  149. return false;
  150. }
  151. #if 0
  152. /* Gesture config register dump */
  153. uint8_t reg;
  154. uint8_t val;
  155. for(reg = 0x80; reg <= 0xAF; reg++) {
  156. if( (reg != 0x82) && \
  157. (reg != 0x8A) && \
  158. (reg != 0x91) && \
  159. (reg != 0xA8) && \
  160. (reg != 0xAC) && \
  161. (reg != 0xAD) )
  162. {
  163. wireReadDataByte(reg, val);
  164. Serial.print(reg, HEX);
  165. Serial.print(": 0x");
  166. Serial.println(val, HEX);
  167. }
  168. }
  169. for(reg = 0xE4; reg <= 0xE7; reg++) {
  170. wireReadDataByte(reg, val);
  171. Serial.print(reg, HEX);
  172. Serial.print(": 0x");
  173. Serial.println(val, HEX);
  174. }
  175. #endif
  176. return true;
  177. }
  178. /*******************************************************************************
  179. * Public methods for controlling the APDS-9960
  180. ******************************************************************************/
  181. /**
  182. * @brief Reads and returns the contents of the ENABLE register
  183. *
  184. * @return Contents of the ENABLE register. 0xFF if error.
  185. */
  186. uint8_t SparkFun_APDS9960::getMode()
  187. {
  188. uint8_t enable_value;
  189. /* Read current ENABLE register */
  190. if( !wireReadDataByte(APDS9960_ENABLE, enable_value) ) {
  191. return ERROR;
  192. }
  193. return enable_value;
  194. }
  195. /**
  196. * @brief Enables or disables a feature in the APDS-9960
  197. *
  198. * @param[in] mode which feature to enable
  199. * @param[in] enable ON (1) or OFF (0)
  200. * @return True if operation success. False otherwise.
  201. */
  202. bool SparkFun_APDS9960::setMode(uint8_t mode, uint8_t enable)
  203. {
  204. uint8_t reg_val;
  205. /* Read current ENABLE register */
  206. reg_val = getMode();
  207. if( reg_val == ERROR ) {
  208. return false;
  209. }
  210. /* Change bit(s) in ENABLE register */
  211. enable = enable & 0x01;
  212. if(mode <= 6 ) {
  213. if (enable) {
  214. reg_val |= (1 << mode);
  215. } else {
  216. reg_val &= ~(1 << mode);
  217. }
  218. } else if( mode == ALL ) {
  219. if (enable) {
  220. reg_val = 0x7F;
  221. } else {
  222. reg_val = 0x00;
  223. }
  224. }
  225. /* Write value back to ENABLE register */
  226. if( !wireWriteDataByte(APDS9960_ENABLE, reg_val) ) {
  227. return false;
  228. }
  229. return true;
  230. }
  231. /**
  232. * @brief Starts the light (R/G/B/Ambient) sensor on the APDS-9960
  233. *
  234. * @param[in] interrupts true to enable hardware interrupt on high or low light
  235. * @return True if sensor enabled correctly. False on error.
  236. */
  237. bool SparkFun_APDS9960::enableLightSensor(bool interrupts)
  238. {
  239. /* Set default gain, interrupts, enable power, and enable sensor */
  240. if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
  241. return false;
  242. }
  243. if( interrupts ) {
  244. if( !setAmbientLightIntEnable(1) ) {
  245. return false;
  246. }
  247. } else {
  248. if( !setAmbientLightIntEnable(0) ) {
  249. return false;
  250. }
  251. }
  252. if( !enablePower() ){
  253. return false;
  254. }
  255. if( !setMode(AMBIENT_LIGHT, 1) ) {
  256. return false;
  257. }
  258. return true;
  259. }
  260. /**
  261. * @brief Ends the light sensor on the APDS-9960
  262. *
  263. * @return True if sensor disabled correctly. False on error.
  264. */
  265. bool SparkFun_APDS9960::disableLightSensor()
  266. {
  267. if( !setAmbientLightIntEnable(0) ) {
  268. return false;
  269. }
  270. if( !setMode(AMBIENT_LIGHT, 0) ) {
  271. return false;
  272. }
  273. return true;
  274. }
  275. /**
  276. * @brief Starts the proximity sensor on the APDS-9960
  277. *
  278. * @param[in] interrupts true to enable hardware external interrupt on proximity
  279. * @return True if sensor enabled correctly. False on error.
  280. */
  281. bool SparkFun_APDS9960::enableProximitySensor(bool interrupts)
  282. {
  283. /* Set default gain, LED, interrupts, enable power, and enable sensor */
  284. if( !setProximityGain(DEFAULT_PGAIN) ) {
  285. return false;
  286. }
  287. if( !setLEDDrive(DEFAULT_LDRIVE) ) {
  288. return false;
  289. }
  290. if( interrupts ) {
  291. if( !setProximityIntEnable(1) ) {
  292. return false;
  293. }
  294. } else {
  295. if( !setProximityIntEnable(0) ) {
  296. return false;
  297. }
  298. }
  299. if( !enablePower() ){
  300. return false;
  301. }
  302. if( !setMode(PROXIMITY, 1) ) {
  303. return false;
  304. }
  305. return true;
  306. }
  307. /**
  308. * @brief Ends the proximity sensor on the APDS-9960
  309. *
  310. * @return True if sensor disabled correctly. False on error.
  311. */
  312. bool SparkFun_APDS9960::disableProximitySensor()
  313. {
  314. if( !setProximityIntEnable(0) ) {
  315. return false;
  316. }
  317. if( !setMode(PROXIMITY, 0) ) {
  318. return false;
  319. }
  320. return true;
  321. }
  322. /**
  323. * @brief Starts the gesture recognition engine on the APDS-9960
  324. *
  325. * @param[in] interrupts true to enable hardware external interrupt on gesture
  326. * @return True if engine enabled correctly. False on error.
  327. */
  328. bool SparkFun_APDS9960::enableGestureSensor(bool interrupts)
  329. {
  330. /* Enable gesture mode
  331. Set ENABLE to 0 (power off)
  332. Set WTIME to 0xFF
  333. Set AUX to LED_BOOST_300
  334. Enable PON, WEN, PEN, GEN in ENABLE
  335. */
  336. resetGestureParameters();
  337. if( !wireWriteDataByte(APDS9960_WTIME, 0xFF) ) {
  338. return false;
  339. }
  340. if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) {
  341. return false;
  342. }
  343. if( !setLEDBoost(LED_BOOST_300) ) {
  344. return false;
  345. }
  346. if( interrupts ) {
  347. if( !setGestureIntEnable(1) ) {
  348. return false;
  349. }
  350. } else {
  351. if( !setGestureIntEnable(0) ) {
  352. return false;
  353. }
  354. }
  355. if( !setGestureMode(1) ) {
  356. return false;
  357. }
  358. if( !enablePower() ){
  359. return false;
  360. }
  361. if( !setMode(WAIT, 1) ) {
  362. return false;
  363. }
  364. if( !setMode(PROXIMITY, 1) ) {
  365. return false;
  366. }
  367. if( !setMode(GESTURE, 1) ) {
  368. return false;
  369. }
  370. return true;
  371. }
  372. /**
  373. * @brief Ends the gesture recognition engine on the APDS-9960
  374. *
  375. * @return True if engine disabled correctly. False on error.
  376. */
  377. bool SparkFun_APDS9960::disableGestureSensor()
  378. {
  379. resetGestureParameters();
  380. if( !setGestureIntEnable(0) ) {
  381. return false;
  382. }
  383. if( !setGestureMode(0) ) {
  384. return false;
  385. }
  386. if( !setMode(GESTURE, 0) ) {
  387. return false;
  388. }
  389. return true;
  390. }
  391. /**
  392. * @brief Determines if there is a gesture available for reading
  393. *
  394. * @return True if gesture available. False otherwise.
  395. */
  396. bool SparkFun_APDS9960::isGestureAvailable()
  397. {
  398. uint8_t val;
  399. /* Read value from GSTATUS register */
  400. if( !wireReadDataByte(APDS9960_GSTATUS, val) ) {
  401. return ERROR;
  402. }
  403. /* Shift and mask out GVALID bit */
  404. val &= APDS9960_GVALID;
  405. /* Return true/false based on GVALID bit */
  406. if( val == 1) {
  407. return true;
  408. } else {
  409. return false;
  410. }
  411. }
  412. /**
  413. * @brief Processes a gesture event and returns best guessed gesture
  414. *
  415. * @return Number corresponding to gesture. -1 on error.
  416. */
  417. int SparkFun_APDS9960::readGesture()
  418. {
  419. uint8_t fifo_level = 0;
  420. uint8_t fifo_data[128];
  421. uint8_t gstatus;
  422. int bytes_read = 0;
  423. int motion;
  424. int i;
  425. /* Make sure that power and gesture is on and data is valid */
  426. if( !isGestureAvailable() || !(getMode() & 0b01000001) ) {
  427. return DIR_NONE;
  428. }
  429. /* Keep looping as long as gesture data is valid */
  430. while(1) {
  431. /* Wait some time to collect next batch of FIFO data */
  432. delay(FIFO_PAUSE_TIME);
  433. /* Get the contents of the STATUS register. Is data still valid? */
  434. if( !wireReadDataByte(APDS9960_GSTATUS, gstatus) ) {
  435. return ERROR;
  436. }
  437. /* If we have valid data, read in FIFO */
  438. if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) {
  439. /* Read the current FIFO level */
  440. if( !wireReadDataByte(APDS9960_GFLVL, fifo_level) ) {
  441. return ERROR;
  442. }
  443. #if DEBUG
  444. Serial.print("FIFO Level: ");
  445. Serial.println(fifo_level);
  446. #endif
  447. /* If there's stuff in the FIFO, read it into our data block */
  448. if( fifo_level > 0) {
  449. bytes_read = wireReadDataBlock( APDS9960_GFIFO_U,
  450. (uint8_t*)fifo_data,
  451. (fifo_level * 4) );
  452. if( bytes_read == -1 ) {
  453. return ERROR;
  454. }
  455. #if DEBUG
  456. Serial.print("FIFO Dump: ");
  457. for ( i = 0; i < bytes_read; i++ ) {
  458. Serial.print(fifo_data[i]);
  459. Serial.print(" ");
  460. }
  461. Serial.println();
  462. #endif
  463. /* If at least 1 set of data, sort the data into U/D/L/R */
  464. if( bytes_read >= 4 ) {
  465. for( i = 0; i < bytes_read; i += 4 ) {
  466. gesture_data_.u_data[gesture_data_.index] = \
  467. fifo_data[i + 0];
  468. gesture_data_.d_data[gesture_data_.index] = \
  469. fifo_data[i + 1];
  470. gesture_data_.l_data[gesture_data_.index] = \
  471. fifo_data[i + 2];
  472. gesture_data_.r_data[gesture_data_.index] = \
  473. fifo_data[i + 3];
  474. gesture_data_.index++;
  475. gesture_data_.total_gestures++;
  476. }
  477. #if DEBUG
  478. Serial.print("Up Data: ");
  479. for ( i = 0; i < gesture_data_.total_gestures; i++ ) {
  480. Serial.print(gesture_data_.u_data[i]);
  481. Serial.print(" ");
  482. }
  483. Serial.println();
  484. #endif
  485. /* Filter and process gesture data. Decode near/far state */
  486. if( processGestureData() ) {
  487. if( decodeGesture() ) {
  488. //***TODO: U-Turn Gestures
  489. #if DEBUG
  490. //Serial.println(gesture_motion_);
  491. #endif
  492. }
  493. }
  494. /* Reset data */
  495. gesture_data_.index = 0;
  496. gesture_data_.total_gestures = 0;
  497. }
  498. }
  499. } else {
  500. /* Determine best guessed gesture and clean up */
  501. delay(FIFO_PAUSE_TIME);
  502. decodeGesture();
  503. motion = gesture_motion_;
  504. #if DEBUG
  505. Serial.print("END: ");
  506. Serial.println(gesture_motion_);
  507. #endif
  508. resetGestureParameters();
  509. return motion;
  510. }
  511. }
  512. }
  513. /**
  514. * Turn the APDS-9960 on
  515. *
  516. * @return True if operation successful. False otherwise.
  517. */
  518. bool SparkFun_APDS9960::enablePower()
  519. {
  520. if( !setMode(POWER, 1) ) {
  521. return false;
  522. }
  523. return true;
  524. }
  525. /**
  526. * Turn the APDS-9960 off
  527. *
  528. * @return True if operation successful. False otherwise.
  529. */
  530. bool SparkFun_APDS9960::disablePower()
  531. {
  532. if( !setMode(POWER, 0) ) {
  533. return false;
  534. }
  535. return true;
  536. }
  537. /*******************************************************************************
  538. * Ambient light and color sensor controls
  539. ******************************************************************************/
  540. /**
  541. * @brief Reads the ambient (clear) light level as a 16-bit value
  542. *
  543. * @param[out] val value of the light sensor.
  544. * @return True if operation successful. False otherwise.
  545. */
  546. bool SparkFun_APDS9960::readAmbientLight(uint16_t &val)
  547. {
  548. uint8_t val_byte;
  549. val = 0;
  550. /* Read value from clear channel, low byte register */
  551. if( !wireReadDataByte(APDS9960_CDATAL, val_byte) ) {
  552. return false;
  553. }
  554. val = val_byte;
  555. /* Read value from clear channel, high byte register */
  556. if( !wireReadDataByte(APDS9960_CDATAH, val_byte) ) {
  557. return false;
  558. }
  559. val = val + ((uint16_t)val_byte << 8);
  560. return true;
  561. }
  562. /**
  563. * @brief Reads the red light level as a 16-bit value
  564. *
  565. * @param[out] val value of the light sensor.
  566. * @return True if operation successful. False otherwise.
  567. */
  568. bool SparkFun_APDS9960::readRedLight(uint16_t &val)
  569. {
  570. uint8_t val_byte;
  571. val = 0;
  572. /* Read value from clear channel, low byte register */
  573. if( !wireReadDataByte(APDS9960_RDATAL, val_byte) ) {
  574. return false;
  575. }
  576. val = val_byte;
  577. /* Read value from clear channel, high byte register */
  578. if( !wireReadDataByte(APDS9960_RDATAH, val_byte) ) {
  579. return false;
  580. }
  581. val = val + ((uint16_t)val_byte << 8);
  582. return true;
  583. }
  584. /**
  585. * @brief Reads the green light level as a 16-bit value
  586. *
  587. * @param[out] val value of the light sensor.
  588. * @return True if operation successful. False otherwise.
  589. */
  590. bool SparkFun_APDS9960::readGreenLight(uint16_t &val)
  591. {
  592. uint8_t val_byte;
  593. val = 0;
  594. /* Read value from clear channel, low byte register */
  595. if( !wireReadDataByte(APDS9960_GDATAL, val_byte) ) {
  596. return false;
  597. }
  598. val = val_byte;
  599. /* Read value from clear channel, high byte register */
  600. if( !wireReadDataByte(APDS9960_GDATAH, val_byte) ) {
  601. return false;
  602. }
  603. val = val + ((uint16_t)val_byte << 8);
  604. return true;
  605. }
  606. /**
  607. * @brief Reads the red light level as a 16-bit value
  608. *
  609. * @param[out] val value of the light sensor.
  610. * @return True if operation successful. False otherwise.
  611. */
  612. bool SparkFun_APDS9960::readBlueLight(uint16_t &val)
  613. {
  614. uint8_t val_byte;
  615. val = 0;
  616. /* Read value from clear channel, low byte register */
  617. if( !wireReadDataByte(APDS9960_BDATAL, val_byte) ) {
  618. return false;
  619. }
  620. val = val_byte;
  621. /* Read value from clear channel, high byte register */
  622. if( !wireReadDataByte(APDS9960_BDATAH, val_byte) ) {
  623. return false;
  624. }
  625. val = val + ((uint16_t)val_byte << 8);
  626. return true;
  627. }
  628. /*******************************************************************************
  629. * Proximity sensor controls
  630. ******************************************************************************/
  631. /**
  632. * @brief Reads the proximity level as an 8-bit value
  633. *
  634. * @param[out] val value of the proximity sensor.
  635. * @return True if operation successful. False otherwise.
  636. */
  637. bool SparkFun_APDS9960::readProximity(uint8_t &val)
  638. {
  639. val = 0;
  640. /* Read value from proximity data register */
  641. if( !wireReadDataByte(APDS9960_PDATA, val) ) {
  642. return false;
  643. }
  644. return true;
  645. }
  646. /*******************************************************************************
  647. * High-level gesture controls
  648. ******************************************************************************/
  649. /**
  650. * @brief Resets all the parameters in the gesture data member
  651. */
  652. void SparkFun_APDS9960::resetGestureParameters()
  653. {
  654. gesture_data_.index = 0;
  655. gesture_data_.total_gestures = 0;
  656. gesture_ud_delta_ = 0;
  657. gesture_lr_delta_ = 0;
  658. gesture_ud_count_ = 0;
  659. gesture_lr_count_ = 0;
  660. gesture_near_count_ = 0;
  661. gesture_far_count_ = 0;
  662. gesture_state_ = 0;
  663. gesture_motion_ = DIR_NONE;
  664. }
  665. /**
  666. * @brief Processes the raw gesture data to determine swipe direction
  667. *
  668. * @return True if near or far state seen. False otherwise.
  669. */
  670. bool SparkFun_APDS9960::processGestureData()
  671. {
  672. uint8_t u_first = 1;
  673. uint8_t d_first = 1;
  674. uint8_t l_first = 1;
  675. uint8_t r_first = 1;
  676. uint8_t u_last = 1;
  677. uint8_t d_last = 1;
  678. uint8_t l_last = 1;
  679. uint8_t r_last = 1;
  680. int ud_ratio_first;
  681. int lr_ratio_first;
  682. int ud_ratio_last;
  683. int lr_ratio_last;
  684. int ud_delta;
  685. int lr_delta;
  686. int i;
  687. /* If we have less than 4 total gestures, that's not enough */
  688. if( gesture_data_.total_gestures <= 4 ) {
  689. return false;
  690. }
  691. /* Check to make sure our data isn't out of bounds */
  692. if( (gesture_data_.total_gestures <= 32) && \
  693. (gesture_data_.total_gestures > 0) ) {
  694. /* Find the first value in U/D/L/R above the threshold */
  695. for( i = 0; i < gesture_data_.total_gestures; i++ ) {
  696. if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
  697. (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) ||
  698. (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
  699. (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
  700. u_first = gesture_data_.u_data[i];
  701. d_first = gesture_data_.d_data[i];
  702. l_first = gesture_data_.l_data[i];
  703. r_first = gesture_data_.r_data[i];
  704. break;
  705. }
  706. }
  707. /* Find the last value in U/D/L/R above the threshold */
  708. for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) {
  709. #if DEBUG
  710. Serial.print(F("Finding last: "));
  711. Serial.print(F("U:"));
  712. Serial.print(gesture_data_.u_data[i]);
  713. Serial.print(F(" D:"));
  714. Serial.print(gesture_data_.d_data[i]);
  715. Serial.print(F(" L:"));
  716. Serial.print(gesture_data_.l_data[i]);
  717. Serial.print(F(" R:"));
  718. Serial.println(gesture_data_.r_data[i]);
  719. #endif
  720. if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) &&
  721. (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) ||
  722. (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) &&
  723. (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) {
  724. u_last = gesture_data_.u_data[i];
  725. d_last = gesture_data_.d_data[i];
  726. l_last = gesture_data_.l_data[i];
  727. r_last = gesture_data_.r_data[i];
  728. break;
  729. }
  730. }
  731. }
  732. /* Calculate the first vs. last ratio of up/down and left/right */
  733. ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first);
  734. lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first);
  735. ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last);
  736. lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last);
  737. #if DEBUG
  738. Serial.print(F("Last Values: "));
  739. Serial.print(F("U:"));
  740. Serial.print(u_last);
  741. Serial.print(F(" D:"));
  742. Serial.print(d_last);
  743. Serial.print(F(" L:"));
  744. Serial.print(l_last);
  745. Serial.print(F(" R:"));
  746. Serial.println(r_last);
  747. Serial.print(F("Ratios: "));
  748. Serial.print(F("UD Fi: "));
  749. Serial.print(ud_ratio_first);
  750. Serial.print(F(" UD La: "));
  751. Serial.print(ud_ratio_last);
  752. Serial.print(F(" LR Fi: "));
  753. Serial.print(lr_ratio_first);
  754. Serial.print(F(" LR La: "));
  755. Serial.println(lr_ratio_last);
  756. #endif
  757. /* Determine the difference between the first and last ratios */
  758. ud_delta = ud_ratio_last - ud_ratio_first;
  759. lr_delta = lr_ratio_last - lr_ratio_first;
  760. #if DEBUG
  761. Serial.print("Deltas: ");
  762. Serial.print("UD: ");
  763. Serial.print(ud_delta);
  764. Serial.print(" LR: ");
  765. Serial.println(lr_delta);
  766. #endif
  767. /* Accumulate the UD and LR delta values */
  768. gesture_ud_delta_ += ud_delta;
  769. gesture_lr_delta_ += lr_delta;
  770. #if DEBUG
  771. Serial.print("Accumulations: ");
  772. Serial.print("UD: ");
  773. Serial.print(gesture_ud_delta_);
  774. Serial.print(" LR: ");
  775. Serial.println(gesture_lr_delta_);
  776. #endif
  777. /* Determine U/D gesture */
  778. if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) {
  779. gesture_ud_count_ = 1;
  780. } else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) {
  781. gesture_ud_count_ = -1;
  782. } else {
  783. gesture_ud_count_ = 0;
  784. }
  785. /* Determine L/R gesture */
  786. if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) {
  787. gesture_lr_count_ = 1;
  788. } else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) {
  789. gesture_lr_count_ = -1;
  790. } else {
  791. gesture_lr_count_ = 0;
  792. }
  793. /* Determine Near/Far gesture */
  794. if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 0) ) {
  795. if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
  796. (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
  797. if( (ud_delta == 0) && (lr_delta == 0) ) {
  798. gesture_near_count_++;
  799. } else if( (ud_delta != 0) || (lr_delta != 0) ) {
  800. gesture_far_count_++;
  801. }
  802. if( (gesture_near_count_ >= 10) && (gesture_far_count_ >= 2) ) {
  803. if( (ud_delta == 0) && (lr_delta == 0) ) {
  804. gesture_state_ = NEAR_STATE;
  805. } else if( (ud_delta != 0) && (lr_delta != 0) ) {
  806. gesture_state_ = FAR_STATE;
  807. }
  808. return true;
  809. }
  810. }
  811. } else {
  812. if( (abs(ud_delta) < GESTURE_SENSITIVITY_2) && \
  813. (abs(lr_delta) < GESTURE_SENSITIVITY_2) ) {
  814. if( (ud_delta == 0) && (lr_delta == 0) ) {
  815. gesture_near_count_++;
  816. }
  817. if( gesture_near_count_ >= 10 ) {
  818. gesture_ud_count_ = 0;
  819. gesture_lr_count_ = 0;
  820. gesture_ud_delta_ = 0;
  821. gesture_lr_delta_ = 0;
  822. }
  823. }
  824. }
  825. #if DEBUG
  826. Serial.print("UD_CT: ");
  827. Serial.print(gesture_ud_count_);
  828. Serial.print(" LR_CT: ");
  829. Serial.print(gesture_lr_count_);
  830. Serial.print(" NEAR_CT: ");
  831. Serial.print(gesture_near_count_);
  832. Serial.print(" FAR_CT: ");
  833. Serial.println(gesture_far_count_);
  834. Serial.println("----------");
  835. #endif
  836. return false;
  837. }
  838. /**
  839. * @brief Determines swipe direction or near/far state
  840. *
  841. * @return True if near/far event. False otherwise.
  842. */
  843. bool SparkFun_APDS9960::decodeGesture()
  844. {
  845. /* Return if near or far event is detected */
  846. if( gesture_state_ == NEAR_STATE ) {
  847. gesture_motion_ = DIR_NEAR;
  848. return true;
  849. } else if ( gesture_state_ == FAR_STATE ) {
  850. gesture_motion_ = DIR_FAR;
  851. return true;
  852. }
  853. /* Determine swipe direction */
  854. if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) {
  855. gesture_motion_ = DIR_UP;
  856. } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) {
  857. gesture_motion_ = DIR_DOWN;
  858. } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) {
  859. gesture_motion_ = DIR_RIGHT;
  860. } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) {
  861. gesture_motion_ = DIR_LEFT;
  862. } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) {
  863. if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
  864. gesture_motion_ = DIR_UP;
  865. } else {
  866. gesture_motion_ = DIR_RIGHT;
  867. }
  868. } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) {
  869. if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
  870. gesture_motion_ = DIR_DOWN;
  871. } else {
  872. gesture_motion_ = DIR_LEFT;
  873. }
  874. } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) {
  875. if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
  876. gesture_motion_ = DIR_UP;
  877. } else {
  878. gesture_motion_ = DIR_LEFT;
  879. }
  880. } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) {
  881. if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) {
  882. gesture_motion_ = DIR_DOWN;
  883. } else {
  884. gesture_motion_ = DIR_RIGHT;
  885. }
  886. } else {
  887. return false;
  888. }
  889. return true;
  890. }
  891. /*******************************************************************************
  892. * Getters and setters for register values
  893. ******************************************************************************/
  894. /**
  895. * @brief Returns the lower threshold for proximity detection
  896. *
  897. * @return lower threshold
  898. */
  899. uint8_t SparkFun_APDS9960::getProxIntLowThresh()
  900. {
  901. uint8_t val;
  902. /* Read value from PILT register */
  903. if( !wireReadDataByte(APDS9960_PILT, val) ) {
  904. val = 0;
  905. }
  906. return val;
  907. }
  908. /**
  909. * @brief Sets the lower threshold for proximity detection
  910. *
  911. * @param[in] threshold the lower proximity threshold
  912. * @return True if operation successful. False otherwise.
  913. */
  914. bool SparkFun_APDS9960::setProxIntLowThresh(uint8_t threshold)
  915. {
  916. if( !wireWriteDataByte(APDS9960_PILT, threshold) ) {
  917. return false;
  918. }
  919. return true;
  920. }
  921. /**
  922. * @brief Returns the high threshold for proximity detection
  923. *
  924. * @return high threshold
  925. */
  926. uint8_t SparkFun_APDS9960::getProxIntHighThresh()
  927. {
  928. uint8_t val;
  929. /* Read value from PIHT register */
  930. if( !wireReadDataByte(APDS9960_PIHT, val) ) {
  931. val = 0;
  932. }
  933. return val;
  934. }
  935. /**
  936. * @brief Sets the high threshold for proximity detection
  937. *
  938. * @param[in] threshold the high proximity threshold
  939. * @return True if operation successful. False otherwise.
  940. */
  941. bool SparkFun_APDS9960::setProxIntHighThresh(uint8_t threshold)
  942. {
  943. if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) {
  944. return false;
  945. }
  946. return true;
  947. }
  948. /**
  949. * @brief Returns LED drive strength for proximity and ALS
  950. *
  951. * Value LED Current
  952. * 0 100 mA
  953. * 1 50 mA
  954. * 2 25 mA
  955. * 3 12.5 mA
  956. *
  957. * @return the value of the LED drive strength. 0xFF on failure.
  958. */
  959. uint8_t SparkFun_APDS9960::getLEDDrive()
  960. {
  961. uint8_t val;
  962. /* Read value from CONTROL register */
  963. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  964. return ERROR;
  965. }
  966. /* Shift and mask out LED drive bits */
  967. val = (val >> 6) & 0b00000011;
  968. return val;
  969. }
  970. /**
  971. * @brief Sets the LED drive strength for proximity and ALS
  972. *
  973. * Value LED Current
  974. * 0 100 mA
  975. * 1 50 mA
  976. * 2 25 mA
  977. * 3 12.5 mA
  978. *
  979. * @param[in] drive the value (0-3) for the LED drive strength
  980. * @return True if operation successful. False otherwise.
  981. */
  982. bool SparkFun_APDS9960::setLEDDrive(uint8_t drive)
  983. {
  984. uint8_t val;
  985. /* Read value from CONTROL register */
  986. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  987. return false;
  988. }
  989. /* Set bits in register to given value */
  990. drive &= 0b00000011;
  991. drive = drive << 6;
  992. val &= 0b00111111;
  993. val |= drive;
  994. /* Write register value back into CONTROL register */
  995. if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
  996. return false;
  997. }
  998. return true;
  999. }
  1000. /**
  1001. * @brief Returns receiver gain for proximity detection
  1002. *
  1003. * Value Gain
  1004. * 0 1x
  1005. * 1 2x
  1006. * 2 4x
  1007. * 3 8x
  1008. *
  1009. * @return the value of the proximity gain. 0xFF on failure.
  1010. */
  1011. uint8_t SparkFun_APDS9960::getProximityGain()
  1012. {
  1013. uint8_t val;
  1014. /* Read value from CONTROL register */
  1015. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  1016. return ERROR;
  1017. }
  1018. /* Shift and mask out PDRIVE bits */
  1019. val = (val >> 2) & 0b00000011;
  1020. return val;
  1021. }
  1022. /**
  1023. * @brief Sets the receiver gain for proximity detection
  1024. *
  1025. * Value Gain
  1026. * 0 1x
  1027. * 1 2x
  1028. * 2 4x
  1029. * 3 8x
  1030. *
  1031. * @param[in] drive the value (0-3) for the gain
  1032. * @return True if operation successful. False otherwise.
  1033. */
  1034. bool SparkFun_APDS9960::setProximityGain(uint8_t drive)
  1035. {
  1036. uint8_t val;
  1037. /* Read value from CONTROL register */
  1038. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  1039. return false;
  1040. }
  1041. /* Set bits in register to given value */
  1042. drive &= 0b00000011;
  1043. drive = drive << 2;
  1044. val &= 0b11110011;
  1045. val |= drive;
  1046. /* Write register value back into CONTROL register */
  1047. if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
  1048. return false;
  1049. }
  1050. return true;
  1051. }
  1052. /**
  1053. * @brief Returns receiver gain for the ambient light sensor (ALS)
  1054. *
  1055. * Value Gain
  1056. * 0 1x
  1057. * 1 4x
  1058. * 2 16x
  1059. * 3 64x
  1060. *
  1061. * @return the value of the ALS gain. 0xFF on failure.
  1062. */
  1063. uint8_t SparkFun_APDS9960::getAmbientLightGain()
  1064. {
  1065. uint8_t val;
  1066. /* Read value from CONTROL register */
  1067. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  1068. return ERROR;
  1069. }
  1070. /* Shift and mask out ADRIVE bits */
  1071. val &= 0b00000011;
  1072. return val;
  1073. }
  1074. /**
  1075. * @brief Sets the receiver gain for the ambient light sensor (ALS)
  1076. *
  1077. * Value Gain
  1078. * 0 1x
  1079. * 1 4x
  1080. * 2 16x
  1081. * 3 64x
  1082. *
  1083. * @param[in] drive the value (0-3) for the gain
  1084. * @return True if operation successful. False otherwise.
  1085. */
  1086. bool SparkFun_APDS9960::setAmbientLightGain(uint8_t drive)
  1087. {
  1088. uint8_t val;
  1089. /* Read value from CONTROL register */
  1090. if( !wireReadDataByte(APDS9960_CONTROL, val) ) {
  1091. return false;
  1092. }
  1093. /* Set bits in register to given value */
  1094. drive &= 0b00000011;
  1095. val &= 0b11111100;
  1096. val |= drive;
  1097. /* Write register value back into CONTROL register */
  1098. if( !wireWriteDataByte(APDS9960_CONTROL, val) ) {
  1099. return false;
  1100. }
  1101. return true;
  1102. }
  1103. /**
  1104. * @brief Get the current LED boost value
  1105. *
  1106. * Value Boost Current
  1107. * 0 100%
  1108. * 1 150%
  1109. * 2 200%
  1110. * 3 300%
  1111. *
  1112. * @return The LED boost value. 0xFF on failure.
  1113. */
  1114. uint8_t SparkFun_APDS9960::getLEDBoost()
  1115. {
  1116. uint8_t val;
  1117. /* Read value from CONFIG2 register */
  1118. if( !wireReadDataByte(APDS9960_CONFIG2, val) ) {
  1119. return ERROR;
  1120. }
  1121. /* Shift and mask out LED_BOOST bits */
  1122. val = (val >> 4) & 0b00000011;
  1123. return val;
  1124. }
  1125. /**
  1126. * @brief Sets the LED current boost value
  1127. *
  1128. * Value Boost Current
  1129. * 0 100%
  1130. * 1 150%
  1131. * 2 200%
  1132. * 3 300%
  1133. *
  1134. * @param[in] drive the value (0-3) for current boost (100-300%)
  1135. * @return True if operation successful. False otherwise.
  1136. */
  1137. bool SparkFun_APDS9960::setLEDBoost(uint8_t boost)
  1138. {
  1139. uint8_t val;
  1140. /* Read value from CONFIG2 register */
  1141. if( !wireReadDataByte(APDS9960_CONFIG2, val) ) {
  1142. return false;
  1143. }
  1144. /* Set bits in register to given value */
  1145. boost &= 0b00000011;
  1146. boost = boost << 4;
  1147. val &= 0b11001111;
  1148. val |= boost;
  1149. /* Write register value back into CONFIG2 register */
  1150. if( !wireWriteDataByte(APDS9960_CONFIG2, val) ) {
  1151. return false;
  1152. }
  1153. return true;
  1154. }
  1155. /**
  1156. * @brief Gets proximity gain compensation enable
  1157. *
  1158. * @return 1 if compensation is enabled. 0 if not. 0xFF on error.
  1159. */
  1160. uint8_t SparkFun_APDS9960::getProxGainCompEnable()
  1161. {
  1162. uint8_t val;
  1163. /* Read value from CONFIG3 register */
  1164. if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
  1165. return ERROR;
  1166. }
  1167. /* Shift and mask out PCMP bits */
  1168. val = (val >> 5) & 0b00000001;
  1169. return val;
  1170. }
  1171. /**
  1172. * @brief Sets the proximity gain compensation enable
  1173. *
  1174. * @param[in] enable 1 to enable compensation. 0 to disable compensation.
  1175. * @return True if operation successful. False otherwise.
  1176. */
  1177. bool SparkFun_APDS9960::setProxGainCompEnable(uint8_t enable)
  1178. {
  1179. uint8_t val;
  1180. /* Read value from CONFIG3 register */
  1181. if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
  1182. return false;
  1183. }
  1184. /* Set bits in register to given value */
  1185. enable &= 0b00000001;
  1186. enable = enable << 5;
  1187. val &= 0b11011111;
  1188. val |= enable;
  1189. /* Write register value back into CONFIG3 register */
  1190. if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) {
  1191. return false;
  1192. }
  1193. return true;
  1194. }
  1195. /**
  1196. * @brief Gets the current mask for enabled/disabled proximity photodiodes
  1197. *
  1198. * 1 = disabled, 0 = enabled
  1199. * Bit Photodiode
  1200. * 3 UP
  1201. * 2 DOWN
  1202. * 1 LEFT
  1203. * 0 RIGHT
  1204. *
  1205. * @return Current proximity mask for photodiodes. 0xFF on error.
  1206. */
  1207. uint8_t SparkFun_APDS9960::getProxPhotoMask()
  1208. {
  1209. uint8_t val;
  1210. /* Read value from CONFIG3 register */
  1211. if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
  1212. return ERROR;
  1213. }
  1214. /* Mask out photodiode enable mask bits */
  1215. val &= 0b00001111;
  1216. return val;
  1217. }
  1218. /**
  1219. * @brief Sets the mask for enabling/disabling proximity photodiodes
  1220. *
  1221. * 1 = disabled, 0 = enabled
  1222. * Bit Photodiode
  1223. * 3 UP
  1224. * 2 DOWN
  1225. * 1 LEFT
  1226. * 0 RIGHT
  1227. *
  1228. * @param[in] mask 4-bit mask value
  1229. * @return True if operation successful. False otherwise.
  1230. */
  1231. bool SparkFun_APDS9960::setProxPhotoMask(uint8_t mask)
  1232. {
  1233. uint8_t val;
  1234. /* Read value from CONFIG3 register */
  1235. if( !wireReadDataByte(APDS9960_CONFIG3, val) ) {
  1236. return false;
  1237. }
  1238. /* Set bits in register to given value */
  1239. mask &= 0b00001111;
  1240. val &= 0b11110000;
  1241. val |= mask;
  1242. /* Write register value back into CONFIG3 register */
  1243. if( !wireWriteDataByte(APDS9960_CONFIG3, val) ) {
  1244. return false;
  1245. }
  1246. return true;
  1247. }
  1248. /**
  1249. * @brief Gets the entry proximity threshold for gesture sensing
  1250. *
  1251. * @return Current entry proximity threshold.
  1252. */
  1253. uint8_t SparkFun_APDS9960::getGestureEnterThresh()
  1254. {
  1255. uint8_t val;
  1256. /* Read value from GPENTH register */
  1257. if( !wireReadDataByte(APDS9960_GPENTH, val) ) {
  1258. val = 0;
  1259. }
  1260. return val;
  1261. }
  1262. /**
  1263. * @brief Sets the entry proximity threshold for gesture sensing
  1264. *
  1265. * @param[in] threshold proximity value needed to start gesture mode
  1266. * @return True if operation successful. False otherwise.
  1267. */
  1268. bool SparkFun_APDS9960::setGestureEnterThresh(uint8_t threshold)
  1269. {
  1270. if( !wireWriteDataByte(APDS9960_GPENTH, threshold) ) {
  1271. return false;
  1272. }
  1273. return true;
  1274. }
  1275. /**
  1276. * @brief Gets the exit proximity threshold for gesture sensing
  1277. *
  1278. * @return Current exit proximity threshold.
  1279. */
  1280. uint8_t SparkFun_APDS9960::getGestureExitThresh()
  1281. {
  1282. uint8_t val;
  1283. /* Read value from GEXTH register */
  1284. if( !wireReadDataByte(APDS9960_GEXTH, val) ) {
  1285. val = 0;
  1286. }
  1287. return val;
  1288. }
  1289. /**
  1290. * @brief Sets the exit proximity threshold for gesture sensing
  1291. *
  1292. * @param[in] threshold proximity value needed to end gesture mode
  1293. * @return True if operation successful. False otherwise.
  1294. */
  1295. bool SparkFun_APDS9960::setGestureExitThresh(uint8_t threshold)
  1296. {
  1297. if( !wireWriteDataByte(APDS9960_GEXTH, threshold) ) {
  1298. return false;
  1299. }
  1300. return true;
  1301. }
  1302. /**
  1303. * @brief Gets the gain of the photodiode during gesture mode
  1304. *
  1305. * Value Gain
  1306. * 0 1x
  1307. * 1 2x
  1308. * 2 4x
  1309. * 3 8x
  1310. *
  1311. * @return the current photodiode gain. 0xFF on error.
  1312. */
  1313. uint8_t SparkFun_APDS9960::getGestureGain()
  1314. {
  1315. uint8_t val;
  1316. /* Read value from GCONF2 register */
  1317. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1318. return ERROR;
  1319. }
  1320. /* Shift and mask out GGAIN bits */
  1321. val = (val >> 5) & 0b00000011;
  1322. return val;
  1323. }
  1324. /**
  1325. * @brief Sets the gain of the photodiode during gesture mode
  1326. *
  1327. * Value Gain
  1328. * 0 1x
  1329. * 1 2x
  1330. * 2 4x
  1331. * 3 8x
  1332. *
  1333. * @param[in] gain the value for the photodiode gain
  1334. * @return True if operation successful. False otherwise.
  1335. */
  1336. bool SparkFun_APDS9960::setGestureGain(uint8_t gain)
  1337. {
  1338. uint8_t val;
  1339. /* Read value from GCONF2 register */
  1340. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1341. return false;
  1342. }
  1343. /* Set bits in register to given value */
  1344. gain &= 0b00000011;
  1345. gain = gain << 5;
  1346. val &= 0b10011111;
  1347. val |= gain;
  1348. /* Write register value back into GCONF2 register */
  1349. if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
  1350. return false;
  1351. }
  1352. return true;
  1353. }
  1354. /**
  1355. * @brief Gets the drive current of the LED during gesture mode
  1356. *
  1357. * Value LED Current
  1358. * 0 100 mA
  1359. * 1 50 mA
  1360. * 2 25 mA
  1361. * 3 12.5 mA
  1362. *
  1363. * @return the LED drive current value. 0xFF on error.
  1364. */
  1365. uint8_t SparkFun_APDS9960::getGestureLEDDrive()
  1366. {
  1367. uint8_t val;
  1368. /* Read value from GCONF2 register */
  1369. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1370. return ERROR;
  1371. }
  1372. /* Shift and mask out GLDRIVE bits */
  1373. val = (val >> 3) & 0b00000011;
  1374. return val;
  1375. }
  1376. /**
  1377. * @brief Sets the LED drive current during gesture mode
  1378. *
  1379. * Value LED Current
  1380. * 0 100 mA
  1381. * 1 50 mA
  1382. * 2 25 mA
  1383. * 3 12.5 mA
  1384. *
  1385. * @param[in] drive the value for the LED drive current
  1386. * @return True if operation successful. False otherwise.
  1387. */
  1388. bool SparkFun_APDS9960::setGestureLEDDrive(uint8_t drive)
  1389. {
  1390. uint8_t val;
  1391. /* Read value from GCONF2 register */
  1392. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1393. return false;
  1394. }
  1395. /* Set bits in register to given value */
  1396. drive &= 0b00000011;
  1397. drive = drive << 3;
  1398. val &= 0b11100111;
  1399. val |= drive;
  1400. /* Write register value back into GCONF2 register */
  1401. if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
  1402. return false;
  1403. }
  1404. return true;
  1405. }
  1406. /**
  1407. * @brief Gets the time in low power mode between gesture detections
  1408. *
  1409. * Value Wait time
  1410. * 0 0 ms
  1411. * 1 2.8 ms
  1412. * 2 5.6 ms
  1413. * 3 8.4 ms
  1414. * 4 14.0 ms
  1415. * 5 22.4 ms
  1416. * 6 30.8 ms
  1417. * 7 39.2 ms
  1418. *
  1419. * @return the current wait time between gestures. 0xFF on error.
  1420. */
  1421. uint8_t SparkFun_APDS9960::getGestureWaitTime()
  1422. {
  1423. uint8_t val;
  1424. /* Read value from GCONF2 register */
  1425. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1426. return ERROR;
  1427. }
  1428. /* Mask out GWTIME bits */
  1429. val &= 0b00000111;
  1430. return val;
  1431. }
  1432. /**
  1433. * @brief Sets the time in low power mode between gesture detections
  1434. *
  1435. * Value Wait time
  1436. * 0 0 ms
  1437. * 1 2.8 ms
  1438. * 2 5.6 ms
  1439. * 3 8.4 ms
  1440. * 4 14.0 ms
  1441. * 5 22.4 ms
  1442. * 6 30.8 ms
  1443. * 7 39.2 ms
  1444. *
  1445. * @param[in] the value for the wait time
  1446. * @return True if operation successful. False otherwise.
  1447. */
  1448. bool SparkFun_APDS9960::setGestureWaitTime(uint8_t time)
  1449. {
  1450. uint8_t val;
  1451. /* Read value from GCONF2 register */
  1452. if( !wireReadDataByte(APDS9960_GCONF2, val) ) {
  1453. return false;
  1454. }
  1455. /* Set bits in register to given value */
  1456. time &= 0b00000111;
  1457. val &= 0b11111000;
  1458. val |= time;
  1459. /* Write register value back into GCONF2 register */
  1460. if( !wireWriteDataByte(APDS9960_GCONF2, val) ) {
  1461. return false;
  1462. }
  1463. return true;
  1464. }
  1465. /**
  1466. * @brief Gets the low threshold for ambient light interrupts
  1467. *
  1468. * @param[out] threshold current low threshold stored on the APDS-9960
  1469. * @return True if operation successful. False otherwise.
  1470. */
  1471. bool SparkFun_APDS9960::getLightIntLowThreshold(uint16_t &threshold)
  1472. {
  1473. uint8_t val_byte;
  1474. threshold = 0;
  1475. /* Read value from ambient light low threshold, low byte register */
  1476. if( !wireReadDataByte(APDS9960_AILTL, val_byte) ) {
  1477. return false;
  1478. }
  1479. threshold = val_byte;
  1480. /* Read value from ambient light low threshold, high byte register */
  1481. if( !wireReadDataByte(APDS9960_AILTH, val_byte) ) {
  1482. return false;
  1483. }
  1484. threshold = threshold + ((uint16_t)val_byte << 8);
  1485. return true;
  1486. }
  1487. /**
  1488. * @brief Sets the low threshold for ambient light interrupts
  1489. *
  1490. * @param[in] threshold low threshold value for interrupt to trigger
  1491. * @return True if operation successful. False otherwise.
  1492. */
  1493. bool SparkFun_APDS9960::setLightIntLowThreshold(uint16_t threshold)
  1494. {
  1495. uint8_t val_low;
  1496. uint8_t val_high;
  1497. /* Break 16-bit threshold into 2 8-bit values */
  1498. val_low = threshold & 0x00FF;
  1499. val_high = (threshold & 0xFF00) >> 8;
  1500. /* Write low byte */
  1501. if( !wireWriteDataByte(APDS9960_AILTL, val_low) ) {
  1502. return false;
  1503. }
  1504. /* Write high byte */
  1505. if( !wireWriteDataByte(APDS9960_AILTH, val_high) ) {
  1506. return false;
  1507. }
  1508. return true;
  1509. }
  1510. /**
  1511. * @brief Gets the high threshold for ambient light interrupts
  1512. *
  1513. * @param[out] threshold current low threshold stored on the APDS-9960
  1514. * @return True if operation successful. False otherwise.
  1515. */
  1516. bool SparkFun_APDS9960::getLightIntHighThreshold(uint16_t &threshold)
  1517. {
  1518. uint8_t val_byte;
  1519. threshold = 0;
  1520. /* Read value from ambient light high threshold, low byte register */
  1521. if( !wireReadDataByte(APDS9960_AIHTL, val_byte) ) {
  1522. return false;
  1523. }
  1524. threshold = val_byte;
  1525. /* Read value from ambient light high threshold, high byte register */
  1526. if( !wireReadDataByte(APDS9960_AIHTH, val_byte) ) {
  1527. return false;
  1528. }
  1529. threshold = threshold + ((uint16_t)val_byte << 8);
  1530. return true;
  1531. }
  1532. /**
  1533. * @brief Sets the high threshold for ambient light interrupts
  1534. *
  1535. * @param[in] threshold high threshold value for interrupt to trigger
  1536. * @return True if operation successful. False otherwise.
  1537. */
  1538. bool SparkFun_APDS9960::setLightIntHighThreshold(uint16_t threshold)
  1539. {
  1540. uint8_t val_low;
  1541. uint8_t val_high;
  1542. /* Break 16-bit threshold into 2 8-bit values */
  1543. val_low = threshold & 0x00FF;
  1544. val_high = (threshold & 0xFF00) >> 8;
  1545. /* Write low byte */
  1546. if( !wireWriteDataByte(APDS9960_AIHTL, val_low) ) {
  1547. return false;
  1548. }
  1549. /* Write high byte */
  1550. if( !wireWriteDataByte(APDS9960_AIHTH, val_high) ) {
  1551. return false;
  1552. }
  1553. return true;
  1554. }
  1555. /**
  1556. * @brief Gets the low threshold for proximity interrupts
  1557. *
  1558. * @param[out] threshold current low threshold stored on the APDS-9960
  1559. * @return True if operation successful. False otherwise.
  1560. */
  1561. bool SparkFun_APDS9960::getProximityIntLowThreshold(uint8_t &threshold)
  1562. {
  1563. threshold = 0;
  1564. /* Read value from proximity low threshold register */
  1565. if( !wireReadDataByte(APDS9960_PILT, threshold) ) {
  1566. return false;
  1567. }
  1568. return true;
  1569. }
  1570. /**
  1571. * @brief Sets the low threshold for proximity interrupts
  1572. *
  1573. * @param[in] threshold low threshold value for interrupt to trigger
  1574. * @return True if operation successful. False otherwise.
  1575. */
  1576. bool SparkFun_APDS9960::setProximityIntLowThreshold(uint8_t threshold)
  1577. {
  1578. /* Write threshold value to register */
  1579. if( !wireWriteDataByte(APDS9960_PILT, threshold) ) {
  1580. return false;
  1581. }
  1582. return true;
  1583. }
  1584. /**
  1585. * @brief Gets the high threshold for proximity interrupts
  1586. *
  1587. * @param[out] threshold current low threshold stored on the APDS-9960
  1588. * @return True if operation successful. False otherwise.
  1589. */
  1590. bool SparkFun_APDS9960::getProximityIntHighThreshold(uint8_t &threshold)
  1591. {
  1592. threshold = 0;
  1593. /* Read value from proximity low threshold register */
  1594. if( !wireReadDataByte(APDS9960_PIHT, threshold) ) {
  1595. return false;
  1596. }
  1597. return true;
  1598. }
  1599. /**
  1600. * @brief Sets the high threshold for proximity interrupts
  1601. *
  1602. * @param[in] threshold high threshold value for interrupt to trigger
  1603. * @return True if operation successful. False otherwise.
  1604. */
  1605. bool SparkFun_APDS9960::setProximityIntHighThreshold(uint8_t threshold)
  1606. {
  1607. /* Write threshold value to register */
  1608. if( !wireWriteDataByte(APDS9960_PIHT, threshold) ) {
  1609. return false;
  1610. }
  1611. return true;
  1612. }
  1613. /**
  1614. * @brief Gets if ambient light interrupts are enabled or not
  1615. *
  1616. * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
  1617. */
  1618. uint8_t SparkFun_APDS9960::getAmbientLightIntEnable()
  1619. {
  1620. uint8_t val;
  1621. /* Read value from ENABLE register */
  1622. if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
  1623. return ERROR;
  1624. }
  1625. /* Shift and mask out AIEN bit */
  1626. val = (val >> 4) & 0b00000001;
  1627. return val;
  1628. }
  1629. /**
  1630. * @brief Turns ambient light interrupts on or off
  1631. *
  1632. * @param[in] enable 1 to enable interrupts, 0 to turn them off
  1633. * @return True if operation successful. False otherwise.
  1634. */
  1635. bool SparkFun_APDS9960::setAmbientLightIntEnable(uint8_t enable)
  1636. {
  1637. uint8_t val;
  1638. /* Read value from ENABLE register */
  1639. if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
  1640. return false;
  1641. }
  1642. /* Set bits in register to given value */
  1643. enable &= 0b00000001;
  1644. enable = enable << 4;
  1645. val &= 0b11101111;
  1646. val |= enable;
  1647. /* Write register value back into ENABLE register */
  1648. if( !wireWriteDataByte(APDS9960_ENABLE, val) ) {
  1649. return false;
  1650. }
  1651. return true;
  1652. }
  1653. /**
  1654. * @brief Gets if proximity interrupts are enabled or not
  1655. *
  1656. * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
  1657. */
  1658. uint8_t SparkFun_APDS9960::getProximityIntEnable()
  1659. {
  1660. uint8_t val;
  1661. /* Read value from ENABLE register */
  1662. if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
  1663. return ERROR;
  1664. }
  1665. /* Shift and mask out PIEN bit */
  1666. val = (val >> 5) & 0b00000001;
  1667. return val;
  1668. }
  1669. /**
  1670. * @brief Turns proximity interrupts on or off
  1671. *
  1672. * @param[in] enable 1 to enable interrupts, 0 to turn them off
  1673. * @return True if operation successful. False otherwise.
  1674. */
  1675. bool SparkFun_APDS9960::setProximityIntEnable(uint8_t enable)
  1676. {
  1677. uint8_t val;
  1678. /* Read value from ENABLE register */
  1679. if( !wireReadDataByte(APDS9960_ENABLE, val) ) {
  1680. return false;
  1681. }
  1682. /* Set bits in register to given value */
  1683. enable &= 0b00000001;
  1684. enable = enable << 5;
  1685. val &= 0b11011111;
  1686. val |= enable;
  1687. /* Write register value back into ENABLE register */
  1688. if( !wireWriteDataByte(APDS9960_ENABLE, val) ) {
  1689. return false;
  1690. }
  1691. return true;
  1692. }
  1693. /**
  1694. * @brief Gets if gesture interrupts are enabled or not
  1695. *
  1696. * @return 1 if interrupts are enabled, 0 if not. 0xFF on error.
  1697. */
  1698. uint8_t SparkFun_APDS9960::getGestureIntEnable()
  1699. {
  1700. uint8_t val;
  1701. /* Read value from GCONF4 register */
  1702. if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
  1703. return ERROR;
  1704. }
  1705. /* Shift and mask out GIEN bit */
  1706. val = (val >> 1) & 0b00000001;
  1707. return val;
  1708. }
  1709. /**
  1710. * @brief Turns gesture-related interrupts on or off
  1711. *
  1712. * @param[in] enable 1 to enable interrupts, 0 to turn them off
  1713. * @return True if operation successful. False otherwise.
  1714. */
  1715. bool SparkFun_APDS9960::setGestureIntEnable(uint8_t enable)
  1716. {
  1717. uint8_t val;
  1718. /* Read value from GCONF4 register */
  1719. if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
  1720. return false;
  1721. }
  1722. /* Set bits in register to given value */
  1723. enable &= 0b00000001;
  1724. enable = enable << 1;
  1725. val &= 0b11111101;
  1726. val |= enable;
  1727. /* Write register value back into GCONF4 register */
  1728. if( !wireWriteDataByte(APDS9960_GCONF4, val) ) {
  1729. return false;
  1730. }
  1731. return true;
  1732. }
  1733. /**
  1734. * @brief Clears the ambient light interrupt
  1735. *
  1736. * @return True if operation completed successfully. False otherwise.
  1737. */
  1738. bool SparkFun_APDS9960::clearAmbientLightInt()
  1739. {
  1740. uint8_t throwaway;
  1741. if( !wireReadDataByte(APDS9960_AICLEAR, throwaway) ) {
  1742. return false;
  1743. }
  1744. return true;
  1745. }
  1746. /**
  1747. * @brief Clears the proximity interrupt
  1748. *
  1749. * @return True if operation completed successfully. False otherwise.
  1750. */
  1751. bool SparkFun_APDS9960::clearProximityInt()
  1752. {
  1753. uint8_t throwaway;
  1754. if( !wireReadDataByte(APDS9960_PICLEAR, throwaway) ) {
  1755. return false;
  1756. }
  1757. return true;
  1758. }
  1759. /**
  1760. * @brief Tells if the gesture state machine is currently running
  1761. *
  1762. * @return 1 if gesture state machine is running, 0 if not. 0xFF on error.
  1763. */
  1764. uint8_t SparkFun_APDS9960::getGestureMode()
  1765. {
  1766. uint8_t val;
  1767. /* Read value from GCONF4 register */
  1768. if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
  1769. return ERROR;
  1770. }
  1771. /* Mask out GMODE bit */
  1772. val &= 0b00000001;
  1773. return val;
  1774. }
  1775. /**
  1776. * @brief Tells the state machine to either enter or exit gesture state machine
  1777. *
  1778. * @param[in] mode 1 to enter gesture state machine, 0 to exit.
  1779. * @return True if operation successful. False otherwise.
  1780. */
  1781. bool SparkFun_APDS9960::setGestureMode(uint8_t mode)
  1782. {
  1783. uint8_t val;
  1784. /* Read value from GCONF4 register */
  1785. if( !wireReadDataByte(APDS9960_GCONF4, val) ) {
  1786. return false;
  1787. }
  1788. /* Set bits in register to given value */
  1789. mode &= 0b00000001;
  1790. val &= 0b11111110;
  1791. val |= mode;
  1792. /* Write register value back into GCONF4 register */
  1793. if( !wireWriteDataByte(APDS9960_GCONF4, val) ) {
  1794. return false;
  1795. }
  1796. return true;
  1797. }
  1798. /*******************************************************************************
  1799. * Raw I2C Reads and Writes
  1800. ******************************************************************************/
  1801. /**
  1802. * @brief Writes a single byte to the I2C device (no register)
  1803. *
  1804. * @param[in] val the 1-byte value to write to the I2C device
  1805. * @return True if successful write operation. False otherwise.
  1806. */
  1807. bool SparkFun_APDS9960::wireWriteByte(uint8_t val)
  1808. {
  1809. Wire.beginTransmission(APDS9960_I2C_ADDR);
  1810. Wire.write(val);
  1811. if( Wire.endTransmission() != 0 ) {
  1812. return false;
  1813. }
  1814. return true;
  1815. }
  1816. /**
  1817. * @brief Writes a single byte to the I2C device and specified register
  1818. *
  1819. * @param[in] reg the register in the I2C device to write to
  1820. * @param[in] val the 1-byte value to write to the I2C device
  1821. * @return True if successful write operation. False otherwise.
  1822. */
  1823. bool SparkFun_APDS9960::wireWriteDataByte(uint8_t reg, uint8_t val)
  1824. {
  1825. Wire.beginTransmission(APDS9960_I2C_ADDR);
  1826. Wire.write(reg);
  1827. Wire.write(val);
  1828. if( Wire.endTransmission() != 0 ) {
  1829. return false;
  1830. }
  1831. return true;
  1832. }
  1833. /**
  1834. * @brief Writes a block (array) of bytes to the I2C device and register
  1835. *
  1836. * @param[in] reg the register in the I2C device to write to
  1837. * @param[in] val pointer to the beginning of the data byte array
  1838. * @param[in] len the length (in bytes) of the data to write
  1839. * @return True if successful write operation. False otherwise.
  1840. */
  1841. bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg,
  1842. uint8_t *val,
  1843. unsigned int len)
  1844. {
  1845. unsigned int i;
  1846. Wire.beginTransmission(APDS9960_I2C_ADDR);
  1847. Wire.write(reg);
  1848. for(i = 0; i < len; i++) {
  1849. Wire.write(val[i]);
  1850. }
  1851. if( Wire.endTransmission() != 0 ) {
  1852. return false;
  1853. }
  1854. return true;
  1855. }
  1856. /**
  1857. * @brief Reads a single byte from the I2C device and specified register
  1858. *
  1859. * @param[in] reg the register to read from
  1860. * @param[out] the value returned from the register
  1861. * @return True if successful read operation. False otherwise.
  1862. */
  1863. bool SparkFun_APDS9960::wireReadDataByte(uint8_t reg, uint8_t &val)
  1864. {
  1865. /* Indicate which register we want to read from */
  1866. if (!wireWriteByte(reg)) {
  1867. return false;
  1868. }
  1869. /* Read from register */
  1870. Wire.requestFrom(APDS9960_I2C_ADDR, 1);
  1871. while (Wire.available()) {
  1872. val = Wire.read();
  1873. }
  1874. return true;
  1875. }
  1876. /**
  1877. * @brief Reads a block (array) of bytes from the I2C device and register
  1878. *
  1879. * @param[in] reg the register to read from
  1880. * @param[out] val pointer to the beginning of the data
  1881. * @param[in] len number of bytes to read
  1882. * @return Number of bytes read. -1 on read error.
  1883. */
  1884. int SparkFun_APDS9960::wireReadDataBlock( uint8_t reg,
  1885. uint8_t *val,
  1886. unsigned int len)
  1887. {
  1888. unsigned char i = 0;
  1889. /* Indicate which register we want to read from */
  1890. if (!wireWriteByte(reg)) {
  1891. return -1;
  1892. }
  1893. /* Read block data */
  1894. Wire.requestFrom(APDS9960_I2C_ADDR, len);
  1895. while (Wire.available()) {
  1896. if (i >= len) {
  1897. return -1;
  1898. }
  1899. val[i] = Wire.read();
  1900. i++;
  1901. }
  1902. return i;
  1903. }