Sebastien Luzy / Mbed OS Code_capteur-APDS9960_ecran-STM32F746G-DISCO

Dependencies:   TS_DISCO_F746NG LCD_DISCO_F746NG BSP_DISCO_F746NG BUTTON_GROUP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_APDS9960.cpp Source File

Adafruit_APDS9960.cpp

Go to the documentation of this file.
00001 /*!
00002  *  @file Adafruit_APDS9960.cpp
00003  *
00004  *  @mainpage Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor
00005  *
00006  *  @section author Author
00007  *
00008  *  Ladyada, Dean Miller (Adafruit Industries)
00009  *
00010  *  @section license License
00011  *
00012  *  Software License Agreement (BSD License)
00013  *
00014  *  Copyright (c) 2017, Adafruit Industries
00015  *  All rights reserved.
00016  *
00017  *  Redistribution and use in source and binary forms, with or without
00018  *  modification, are permitted provided that the following conditions are met:
00019  *  1. Redistributions of source code must retain the above copyright
00020  *  notice, this list of conditions and the following disclaimer.
00021  *  2. Redistributions in binary form must reproduce the above copyright
00022  *  notice, this list of conditions and the following disclaimer in the
00023  *  documentation and/or other materials provided with the distribution.
00024  *  3. Neither the name of the copyright holders nor the
00025  *  names of its contributors may be used to endorse or promote products
00026  *  derived from this software without specific prior written permission.
00027  *
00028  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
00029  *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00030  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00031  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00032  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00033  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00034  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00035  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00036  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00037  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 #ifdef __AVR
00041 #include <avr/pgmspace.h>
00042 #elif defined(ESP8266)
00043 #include <pgmspace.h>
00044 #endif
00045 #include <math.h>
00046 #include <stdlib.h>
00047 
00048 #include "Adafruit_APDS9960.h "
00049 
00050 /*!
00051  *  @brief  Implements missing powf function
00052  *  @param  x
00053  *          Base number
00054  *  @param  y
00055  *          Exponent
00056  *  @return x raised to the power of y
00057  */
00058  /*
00059 float powf(const float x, const float y) {
00060   return (float)(pow((double)x, (double)y));
00061 }
00062 */
00063 
00064 /*!
00065  *  @brief  Enables the device
00066  *          Disables the device (putting it in lower power sleep mode)
00067  *  @param  en
00068  *          Enable (True/False)
00069  */
00070 void Adafruit_APDS9960::enable(boolean en) {
00071   _enable.PON = en;
00072   this->write8(APDS9960_ENABLE, _enable.get());
00073 }
00074 
00075 /*!
00076  *  @brief  Initializes I2C and configures the sensor
00077  *  @param  iTimeMS
00078  *          Integration time
00079  *  @param  aGain
00080  *          Gain
00081  *  @param  addr
00082  *          I2C address
00083  *  @param  *theWire
00084  *          Wire object
00085  *  @return True if initialization was successful, otherwise false.
00086  */
00087 boolean Adafruit_APDS9960::begin(I2C *theWire, uint16_t iTimeMS, apds9960AGain_t aGain,
00088                                  uint8_t addr) {
00089   _wire = theWire;
00090   _i2c_init();
00091   _i2caddr = addr;
00092 
00093   /* Make sure we're actually connected */
00094   uint8_t x = read8(APDS9960_ID);
00095   if (x != 0xAB) {
00096     return false;
00097     _pc->printf("TESTCPP %d", x);
00098   }
00099 
00100   /* Set default integration time and gain */
00101   setADCIntegrationTime(iTimeMS);
00102   setADCGain(aGain);
00103 
00104   // disable everything to start
00105   enableGesture(false);
00106   enableProximity(false);
00107   enableColor(false);
00108 
00109   disableColorInterrupt();
00110   disableProximityInterrupt();
00111   clearInterrupt();
00112 
00113   /* Note: by default, the device is in power down mode on bootup */
00114   enable(false);
00115   wait_us(10000);
00116   enable(true);
00117   wait_us(10000);
00118 
00119   // default to all gesture dimensions
00120   setGestureDimensions(APDS9960_DIMENSIONS_ALL);
00121   setGestureFIFOThreshold(APDS9960_GFIFO_4);
00122   setGestureGain(APDS9960_GGAIN_4);
00123   setGestureProximityThreshold(50);
00124   resetCounts();
00125 
00126   _gpulse.GPLEN = APDS9960_GPULSE_32US;
00127   _gpulse.GPULSE = 9; // 10 pulses
00128   this->write8(APDS9960_GPULSE, _gpulse.get());
00129 
00130   return true;
00131 }
00132 
00133 /*!
00134  *  @brief  Sets the integration time for the ADC of the APDS9960, in millis
00135  *  @param  iTimeMS
00136  *          Integration time
00137  */
00138 void Adafruit_APDS9960::setADCIntegrationTime(uint16_t iTimeMS) {
00139   float temp;
00140 
00141   // convert ms into 2.78ms increments
00142   temp = iTimeMS;
00143   temp /= 2.78;
00144   temp = 256 - temp;
00145   if (temp > 255)
00146     temp = 255;
00147   if (temp < 0)
00148     temp = 0;
00149 
00150   /* Update the timing register */
00151   write8(APDS9960_ATIME, (uint8_t)temp);
00152 }
00153 
00154 /*!
00155  *  @brief  Returns the integration time for the ADC of the APDS9960, in millis
00156  *  @return Integration time
00157  */
00158 float Adafruit_APDS9960::getADCIntegrationTime() {
00159   float temp;
00160 
00161   temp = read8(APDS9960_ATIME);
00162 
00163   // convert to units of 2.78 ms
00164   temp = 256 - temp;
00165   temp *= 2.78;
00166   return temp;
00167 }
00168 
00169 /*!
00170  *  @brief  Adjusts the color/ALS gain on the APDS9960 (adjusts the sensitivity
00171  *          to light)
00172  *  @param  aGain
00173  *          Gain
00174  */
00175 void Adafruit_APDS9960::setADCGain(apds9960AGain_t aGain) {
00176   _control.AGAIN = aGain;
00177 
00178   /* Update the timing register */
00179   write8(APDS9960_CONTROL, _control.get());
00180 }
00181 
00182 /*!
00183  *  @brief  Returns the ADC gain
00184  *  @return ADC gain
00185  */
00186 apds9960AGain_t Adafruit_APDS9960::getADCGain() {
00187   return (apds9960AGain_t)(read8(APDS9960_CONTROL) & 0x03);
00188 }
00189 
00190 /*!
00191  *  @brief  Adjusts the Proximity gain on the APDS9960
00192  *  @param  pGain
00193  *          Gain
00194  */
00195 void Adafruit_APDS9960::setProxGain(apds9960PGain_t pGain) {
00196   _control.PGAIN = pGain;
00197 
00198   /* Update the timing register */
00199   write8(APDS9960_CONTROL, _control.get());
00200 }
00201 
00202 /*!
00203  *  @brief  Returns the Proximity gain on the APDS9960
00204  *  @return Proxmity gain
00205  */
00206 apds9960PGain_t Adafruit_APDS9960::getProxGain() {
00207   return (apds9960PGain_t)(read8(APDS9960_CONTROL) & 0x0C);
00208 }
00209 
00210 /*!
00211  *  @brief  Sets number of proxmity pulses
00212  *  @param  pLen
00213  *          Pulse Length
00214  *  @param  pulses
00215  *          Number of pulses
00216  */
00217 void Adafruit_APDS9960::setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses) {
00218   if (pulses < 1)
00219     pulses = 1;
00220   if (pulses > 64)
00221     pulses = 64;
00222   pulses--;
00223 
00224   _ppulse.PPLEN = pLen;
00225   _ppulse.PPULSE = pulses;
00226 
00227   write8(APDS9960_PPULSE, _ppulse.get());
00228 }
00229 
00230 /*!
00231  *  @brief  Enable proximity readings on APDS9960
00232  *  @param  en
00233  *          Enable (True/False)
00234  */
00235 void Adafruit_APDS9960::enableProximity(boolean en) {
00236   _enable.PEN = en;
00237 
00238   write8(APDS9960_ENABLE, _enable.get());
00239 }
00240 
00241 /*!
00242  *  @brief  Enable proximity interrupts
00243  */
00244 void Adafruit_APDS9960::enableProximityInterrupt() {
00245   _enable.PIEN = 1;
00246   write8(APDS9960_ENABLE, _enable.get());
00247   clearInterrupt();
00248 }
00249 
00250 /*!
00251  *  @brief  Disable proximity interrupts
00252  */
00253 void Adafruit_APDS9960::disableProximityInterrupt() {
00254   _enable.PIEN = 0;
00255   write8(APDS9960_ENABLE, _enable.get());
00256 }
00257 
00258 /*!
00259  *  @brief  Set proxmity interrupt thresholds
00260  *  @param  low
00261  *          Low threshold
00262  *  @param  high
00263  *          High threshold
00264  *  @param  persistance
00265  *          Persistance
00266  */
00267 void Adafruit_APDS9960::setProximityInterruptThreshold(uint8_t low,
00268                                                        uint8_t high,
00269                                                        uint8_t persistance) {
00270   write8(APDS9960_PILT, low);
00271   write8(APDS9960_PIHT, high);
00272 
00273   if (persistance > 7)
00274     persistance = 7;
00275   _pers.PPERS = persistance;
00276   write8(APDS9960_PERS, _pers.get());
00277 }
00278 
00279 /*!
00280  *  @brief  Returns proxmity interrupt status
00281  *  @return True if enabled, false otherwise.
00282  */
00283 bool Adafruit_APDS9960::getProximityInterrupt() {
00284   _status.set(this->read8(APDS9960_STATUS));
00285   return _status.PINT;
00286 };
00287 
00288 /*!
00289  *  @brief  Read proximity data
00290  *  @return Proximity
00291  */
00292 uint8_t Adafruit_APDS9960::readProximity() { return read8(APDS9960_PDATA); }
00293 
00294 /*!
00295  *  @brief  Returns validity status of a gesture
00296  *  @return Status (True/False)
00297  */
00298 bool Adafruit_APDS9960::gestureValid() {
00299   _gstatus.set(this->read8(APDS9960_GSTATUS));
00300   return _gstatus.GVALID;
00301 }
00302 
00303 /*!
00304  *  @brief  Sets gesture dimensions
00305  *  @param  dims
00306  *          Dimensions (APDS9960_DIMENSIONS_ALL, APDS9960_DIMENSIONS_UP_DOWM,
00307  *          APDS9960_DIMENSIONS_UP_DOWN, APGS9960_DIMENSIONS_LEFT_RIGHT)
00308  */
00309 void Adafruit_APDS9960::setGestureDimensions(uint8_t dims) {
00310   _gconf3.GDIMS = dims;
00311   this->write8(APDS9960_GCONF3, _gconf3.get());
00312 }
00313 
00314 /*!
00315  *  @brief  Sets gesture FIFO Threshold
00316  *  @param  thresh
00317  *          Threshold (APDS9960_GFIFO_1, APDS9960_GFIFO_4, APDS9960_GFIFO_8,
00318  *          APDS9960_GFIFO_16)
00319  */
00320 void Adafruit_APDS9960::setGestureFIFOThreshold(uint8_t thresh) {
00321   _gconf1.GFIFOTH = thresh;
00322   this->write8(APDS9960_GCONF1, _gconf1.get());
00323 }
00324 
00325 /*!
00326  *  @brief  Sets gesture sensor gain
00327  *  @param  gain
00328  *          Gain (APDS9960_GAIN_1, APDS9960_GAIN_2, APDS9960_GAIN_4,
00329  *          APDS9960_GAIN_8)
00330  */
00331 void Adafruit_APDS9960::setGestureGain(uint8_t gain) {
00332   _gconf2.GGAIN = gain;
00333   this->write8(APDS9960_GCONF2, _gconf2.get());
00334 }
00335 
00336 /*!
00337  *  @brief  Sets gesture sensor threshold
00338  *  @param  thresh
00339  *          Threshold
00340  */
00341 void Adafruit_APDS9960::setGestureProximityThreshold(uint8_t thresh) {
00342   this->write8(APDS9960_GPENTH, thresh);
00343 }
00344 
00345 /*!
00346  *  @brief  Sets gesture sensor offset
00347  *  @param  offset_up
00348  *          Up offset
00349  *  @param  offset_down
00350  *          Down offset
00351  *  @param  offset_left
00352  *          Left offset
00353  *  @param  offset_right
00354  *          Right offset
00355  */
00356 void Adafruit_APDS9960::setGestureOffset(uint8_t offset_up, uint8_t offset_down,
00357                                          uint8_t offset_left,
00358                                          uint8_t offset_right) {
00359   this->write8(APDS9960_GOFFSET_U, offset_up);
00360   this->write8(APDS9960_GOFFSET_D, offset_down);
00361   this->write8(APDS9960_GOFFSET_L, offset_left);
00362   this->write8(APDS9960_GOFFSET_R, offset_right);
00363 }
00364 
00365 /*!
00366  *  @brief  Enable gesture readings on APDS9960
00367  *  @param  en
00368  *          Enable (True/False)
00369  */
00370 void Adafruit_APDS9960::enableGesture(boolean en) {
00371   if (!en) {
00372     _gconf4.GMODE = 0;
00373     write8(APDS9960_GCONF4, _gconf4.get());
00374   }
00375   _enable.GEN = en;
00376   write8(APDS9960_ENABLE, _enable.get());
00377   resetCounts();
00378 }
00379 
00380 /*!
00381  *  @brief  Resets gesture counts
00382  */
00383 void Adafruit_APDS9960::resetCounts() {
00384   gestCnt = 0;
00385   UCount = 0;
00386   DCount = 0;
00387   LCount = 0;
00388   RCount = 0;
00389 }
00390 
00391 /*!
00392  *  @brief  Reads gesture
00393  *  @return Received gesture (APDS9960_DOWN APDS9960_UP, APDS9960_LEFT
00394  *          APDS9960_RIGHT)
00395  */
00396 uint8_t Adafruit_APDS9960::readGesture() {
00397   uint8_t toRead;
00398   uint8_t buf[256];
00399   unsigned long t = 0;
00400   uint8_t gestureReceived;
00401   while (1) {
00402     int up_down_diff = 0;
00403     int left_right_diff = 0;
00404     gestureReceived = 0;
00405     if (!gestureValid())
00406       return 0;
00407 
00408     wait_us(30000);
00409     toRead = this->read8(APDS9960_GFLVL);
00410 
00411     // produces sideffects needed for readGesture to work
00412     this->read(APDS9960_GFIFO_U, buf, toRead);
00413 
00414     if (abs((int)buf[0] - (int)buf[1]) > 13)
00415       up_down_diff += (int)buf[0] - (int)buf[1];
00416 
00417     if (abs((int)buf[2] - (int)buf[3]) > 13)
00418       left_right_diff += (int)buf[2] - (int)buf[3];
00419 
00420     if (up_down_diff != 0) {
00421       if (up_down_diff < 0) {
00422         if (DCount > 0) {
00423           gestureReceived = APDS9960_UP;
00424         } else
00425           UCount++;
00426       } else if (up_down_diff > 0) {
00427         if (UCount > 0) {
00428           gestureReceived = APDS9960_DOWN;
00429         } else
00430           DCount++;
00431       }
00432     }
00433 
00434     if (left_right_diff != 0) {
00435       if (left_right_diff < 0) {
00436         if (RCount > 0) {
00437           gestureReceived = APDS9960_LEFT;
00438         } else
00439           LCount++;
00440       } else if (left_right_diff > 0) {
00441         if (LCount > 0) {
00442           gestureReceived = APDS9960_RIGHT;
00443         } else
00444           RCount++;
00445       }
00446     }
00447 
00448 
00449     if (up_down_diff != 0 || left_right_diff != 0){
00450       t = clock_ms(); 
00451       }
00452 
00453     if (gestureReceived || clock_ms() - t > 300) {
00454       resetCounts();
00455       return gestureReceived;
00456     }
00457     
00458   }
00459 }
00460 
00461 /*!
00462  *  @brief  Set LED brightness for proximity/gesture
00463  *  @param  drive
00464  *          LED Drive
00465  *  @param  boost
00466  *          LED Boost
00467  */
00468 void Adafruit_APDS9960::setLED(apds9960LedDrive_t drive,
00469                                apds9960LedBoost_t boost) {
00470   // set BOOST
00471   _config2.LED_BOOST = boost;
00472   write8(APDS9960_CONFIG2, _config2.get());
00473 
00474   _control.LDRIVE = drive;
00475   write8(APDS9960_CONTROL, _control.get());
00476 }
00477 
00478 /*!
00479  *  @brief  Enable color readings on APDS9960
00480  *  @param  en
00481  *          Enable (True/False)
00482  */
00483 void Adafruit_APDS9960::enableColor(boolean en) {
00484   _enable.AEN = en;
00485   write8(APDS9960_ENABLE, _enable.get());
00486 }
00487 
00488 /*!
00489  *  @brief  Returns status of color data
00490  *  @return True if color data ready, False otherwise
00491  */
00492 bool Adafruit_APDS9960::colorDataReady() {
00493   _status.set(this->read8(APDS9960_STATUS));
00494   return _status.AVALID;
00495 }
00496 
00497 /*!
00498  *  @brief  Reads the raw red, green, blue and clear channel values
00499  *  @param  *r
00500  *          Red value
00501  *  @param  *g
00502  *          Green value
00503  *  @param  *b
00504  *          Blue value
00505  *  @param  *c
00506  *          Clear channel value
00507  */
00508 void Adafruit_APDS9960::getColorData(uint16_t *r, uint16_t *g, uint16_t *b,
00509                                      uint16_t *c) {
00510 
00511   *c = read16R(APDS9960_CDATAL);
00512   *r = read16R(APDS9960_RDATAL);
00513   *g = read16R(APDS9960_GDATAL);
00514   *b = read16R(APDS9960_BDATAL);
00515 }
00516 
00517 /*!
00518  *  @brief  Converts the raw R/G/B values to color temperature in degrees Kelvin
00519  *  @param  r
00520  *          Red value
00521  *  @param  g
00522  *          Green value
00523  *  @param  b
00524  *          Blue value
00525  *  @return Color temperature
00526  */
00527 uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g,
00528                                                       uint16_t b) {
00529   float X, Y, Z; /* RGB to XYZ correlation      */
00530   float xc, yc;  /* Chromaticity co-ordinates   */
00531   float n;       /* McCamy's formula            */
00532   float cct;
00533 
00534   /* 1. Map RGB values to their XYZ counterparts.    */
00535   /* Based on 6500K fluorescent, 3000K fluorescent   */
00536   /* and 60W incandescent values for a wide range.   */
00537   /* Note: Y = Illuminance or lux                    */
00538   X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
00539   Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
00540   Z = (-0.68202F * r) + (0.77073F * g) + (0.56332F * b);
00541 
00542   /* 2. Calculate the chromaticity co-ordinates      */
00543   xc = (X) / (X + Y + Z);
00544   yc = (Y) / (X + Y + Z);
00545 
00546   /* 3. Use McCamy's formula to determine the CCT    */
00547   n = (xc - 0.3320F) / (0.1858F - yc);
00548 
00549   /* Calculate the final CCT */
00550   cct =
00551       (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
00552 
00553   /* Return the results in degrees Kelvin */
00554   return (uint16_t)cct;
00555 }
00556 
00557 /*!
00558  *  @brief  Calculate ambient light values
00559  *  @param  r
00560  *          Red value
00561  *  @param  g
00562  *          Green value
00563  *  @param  b
00564  *          Blue value
00565  *  @return LUX value
00566  */
00567 uint16_t Adafruit_APDS9960::calculateLux(uint16_t r, uint16_t g, uint16_t b) {
00568   float illuminance;
00569 
00570   /* This only uses RGB ... how can we integrate clear or calculate lux */
00571   /* based exclusively on clear since this might be more reliable?      */
00572   illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
00573 
00574   return (uint16_t)illuminance;
00575 }
00576 
00577 /*!
00578  *  @brief  Enables color interrupt
00579  */
00580 void Adafruit_APDS9960::enableColorInterrupt() {
00581   _enable.AIEN = 1;
00582   write8(APDS9960_ENABLE, _enable.get());
00583 }
00584 
00585 /*!
00586  *  @brief  Disables color interrupt
00587  */
00588 void Adafruit_APDS9960::disableColorInterrupt() {
00589   _enable.AIEN = 0;
00590   write8(APDS9960_ENABLE, _enable.get());
00591 }
00592 
00593 /*!
00594  *  @brief  Clears interrupt
00595  */
00596 void Adafruit_APDS9960::clearInterrupt() {
00597   this->write(APDS9960_AICLEAR, NULL, 0);
00598 }
00599 
00600 /*!
00601  *  @brief  Sets interrupt limits
00602  *  @param  low
00603  *          Low limit
00604  *  @param  high
00605  *          High limit
00606  */
00607 void Adafruit_APDS9960::setIntLimits(uint16_t low, uint16_t high) {
00608   write8(APDS9960_AILTIL, low & 0xFF);
00609   write8(APDS9960_AILTH, low >> 8);
00610   write8(APDS9960_AIHTL, high & 0xFF);
00611   write8(APDS9960_AIHTH, high >> 8);
00612 }
00613 
00614 /*!
00615  *  @brief  Writes specified value to given register
00616  *  @param  reg
00617  *          Register to write to
00618  *  @param  value
00619  *          Value to write
00620  */
00621 void Adafruit_APDS9960::write8(byte reg, byte value) {
00622   this->write(reg, &value, 1);
00623 }
00624 
00625 /*!
00626  *  @brief  Reads 8 bits from specified register
00627  *  @param  reg
00628  *          Register to write to
00629  *  @return Value in register
00630  */
00631 uint8_t Adafruit_APDS9960::read8(byte reg) {
00632   uint8_t ret;
00633   this->read(reg, &ret, 1);
00634 
00635   return ret;
00636 }
00637 
00638 /*!
00639  *  @brief  Reads 32 bits from specified register
00640  *  @param  reg
00641  *          Register to write to
00642  *  @return Value in register
00643  */
00644 uint32_t Adafruit_APDS9960::read32(uint8_t reg) {
00645   uint8_t ret[4];
00646   uint32_t ret32;
00647   this->read(reg, ret, 4);
00648   ret32 = ret[3];
00649   ret32 |= (uint32_t)ret[2] << 8;
00650   ret32 |= (uint32_t)ret[1] << 16;
00651   ret32 |= (uint32_t)ret[0] << 24;
00652   return ret32;
00653 }
00654 
00655 /*!
00656  *  @brief  Reads 16 bites from specified register
00657  *  @param  reg
00658  *          Register to write to
00659  *  @return Value in register
00660  */
00661 uint16_t Adafruit_APDS9960::read16(uint8_t reg) {
00662   uint8_t ret[2];
00663   this->read(reg, ret, 2);
00664 
00665   return (ret[0] << 8) | ret[1];
00666 }
00667 
00668 /*!
00669  *  @brief  Reads 16 bites from specified register
00670  *  @param  reg
00671  *          Register to write to
00672  *  @return Value in register
00673  */
00674 uint16_t Adafruit_APDS9960::read16R(uint8_t reg) {
00675   uint8_t ret[2];
00676   this->read(reg, ret, 2);
00677 
00678   return (ret[1] << 8) | ret[0];
00679 }
00680 
00681 /*!
00682  *  @brief  Begins I2C communication
00683  */
00684 void Adafruit_APDS9960::_i2c_init() {
00685     //_wire->begin();  // on mbed, we are already master if using the I2C class instead of I2CSlave class
00686 }
00687 
00688 /*!
00689  *  @brief  Reads num bytes from specified register into a given buffer
00690  *  @param  reg
00691  *          Register
00692  *  @param  *buf
00693  *          Buffer
00694  *  @param  num
00695  *          Number of bytes
00696  *  @return Position after reading
00697  */
00698 uint8_t Adafruit_APDS9960::read(uint8_t reg, uint8_t *buf, uint8_t num) {
00699   uint8_t pos = 0;
00700   bool eof = false;
00701 
00702   // on arduino we need to read in 32 byte chunks
00703   //while (pos < num && !eof) {
00704 
00705     //uint8_t read_now = min(32, num - pos);
00706     /*
00707     _wire->beginTransmission((uint8_t)_i2caddr);
00708     _wire->write((uint8_t)reg + pos);
00709     _wire->endTransmission();
00710 
00711     _wire->requestFrom((uint8_t)_i2caddr, read_now);
00712     */
00713     
00714     //_wire->start();
00715     //_wire->write((uint8_t)_i2caddr);
00716     //_wire->write((uint8_t)reg);
00717     //_wire->stop();
00718     
00719     _wire->write((uint8_t)_i2caddr, (char *)&reg, 1, true);
00720     
00721     _wire->read((uint8_t)_i2caddr, (char *) buf, num);
00722     
00723     
00724 /*
00725     for (int i = 0; i < read_now; i++) {
00726       if (!_wire->available()) {
00727         eof = true;
00728         break;
00729       }
00730       buf[pos] = _wire->read();
00731       pos++;
00732     }
00733     */
00734   //}
00735   
00736   return num;
00737 }
00738 
00739 /*!
00740  *  @brief  Writes num bytes from specified buffer into a given register
00741  *  @param  reg
00742  *          Register
00743  *  @param  *buf
00744  *          Buffer
00745  *  @param  num
00746  *          Number of bytes
00747  */
00748 void Adafruit_APDS9960::write(uint8_t reg, uint8_t *buf, uint8_t num) {
00749   /*
00750   _wire->beginTransmission((uint8_t)_i2caddr);
00751   _wire->write((uint8_t)reg);
00752   _wire->write((uint8_t *)buf, num);
00753   _wire->endTransmission();
00754   */
00755   
00756   _wire->start();
00757   _wire->write((uint8_t)_i2caddr);
00758   _wire->write((uint8_t)reg);
00759   
00760   for(int i=0; i < num; i++){ // on parcours le "tableau" buf
00761     uint8_t value = *(buf+i); // on récupere la valeur à l'emplacement "i" du tableau
00762     _wire->write(value); // j'écris la valeur du tableau à l'emplacement "i" sur le bus i2c.
00763   }
00764   
00765   _wire->stop();
00766   
00767   
00768 }