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.h Source File

Adafruit_APDS9960.h

Go to the documentation of this file.
00001 /*!
00002  *  @file Adafruit_APDS9960.h
00003  *
00004  *  Software License Agreement (BSD License)
00005  *
00006  *  Copyright (c) 2017, Adafruit Industries
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions are met:
00011  *  1. Redistributions of source code must retain the above copyright
00012  *  notice, this list of conditions and the following disclaimer.
00013  *  2. Redistributions in binary form must reproduce the above copyright
00014  *  notice, this list of conditions and the following disclaimer in the
00015  *  documentation and/or other materials provided with the distribution.
00016  *  3. Neither the name of the copyright holders nor the
00017  *  names of its contributors may be used to endorse or promote products
00018  *  derived from this software without specific prior written permission.
00019  *
00020  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
00021  *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00024  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00027  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00029  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  */
00031 #ifndef _APDS9960_H_
00032 #define _APDS9960_H_
00033 
00034 #include "mbed.h"
00035 #include "Clock.h"
00036 
00037 typedef bool boolean;
00038 typedef uint8_t byte;
00039 
00040 #define APDS9960_ADDRESS (0x39<<1) /**< I2C Address */
00041 
00042 /** I2C Registers */
00043 enum {
00044   APDS9960_RAM = 0x00,
00045   APDS9960_ENABLE = 0x80,
00046   APDS9960_ATIME = 0x81,
00047   APDS9960_WTIME = 0x83,
00048   APDS9960_AILTIL = 0x84,
00049   APDS9960_AILTH = 0x85,
00050   APDS9960_AIHTL = 0x86,
00051   APDS9960_AIHTH = 0x87,
00052   APDS9960_PILT = 0x89,
00053   APDS9960_PIHT = 0x8B,
00054   APDS9960_PERS = 0x8C,
00055   APDS9960_CONFIG1 = 0x8D,
00056   APDS9960_PPULSE = 0x8E,
00057   APDS9960_CONTROL = 0x8F,
00058   APDS9960_CONFIG2 = 0x90,
00059   APDS9960_ID = 0x92,
00060   APDS9960_STATUS = 0x93,
00061   APDS9960_CDATAL = 0x94,
00062   APDS9960_CDATAH = 0x95,
00063   APDS9960_RDATAL = 0x96,
00064   APDS9960_RDATAH = 0x97,
00065   APDS9960_GDATAL = 0x98,
00066   APDS9960_GDATAH = 0x99,
00067   APDS9960_BDATAL = 0x9A,
00068   APDS9960_BDATAH = 0x9B,
00069   APDS9960_PDATA = 0x9C,
00070   APDS9960_POFFSET_UR = 0x9D,
00071   APDS9960_POFFSET_DL = 0x9E,
00072   APDS9960_CONFIG3 = 0x9F,
00073   APDS9960_GPENTH = 0xA0,
00074   APDS9960_GEXTH = 0xA1,
00075   APDS9960_GCONF1 = 0xA2,
00076   APDS9960_GCONF2 = 0xA3,
00077   APDS9960_GOFFSET_U = 0xA4,
00078   APDS9960_GOFFSET_D = 0xA5,
00079   APDS9960_GOFFSET_L = 0xA7,
00080   APDS9960_GOFFSET_R = 0xA9,
00081   APDS9960_GPULSE = 0xA6,
00082   APDS9960_GCONF3 = 0xAA,
00083   APDS9960_GCONF4 = 0xAB,
00084   APDS9960_GFLVL = 0xAE,
00085   APDS9960_GSTATUS = 0xAF,
00086   APDS9960_IFORCE = 0xE4,
00087   APDS9960_PICLEAR = 0xE5,
00088   APDS9960_CICLEAR = 0xE6,
00089   APDS9960_AICLEAR = 0xE7,
00090   APDS9960_GFIFO_U = 0xFC,
00091   APDS9960_GFIFO_D = 0xFD,
00092   APDS9960_GFIFO_L = 0xFE,
00093   APDS9960_GFIFO_R = 0xFF,
00094 };
00095 
00096 /** ADC gain settings */
00097 typedef enum {
00098   APDS9960_AGAIN_1X = 0x00,  /**< No gain */
00099   APDS9960_AGAIN_4X = 0x01,  /**< 2x gain */
00100   APDS9960_AGAIN_16X = 0x02, /**< 16x gain */
00101   APDS9960_AGAIN_64X = 0x03  /**< 64x gain */
00102 } apds9960AGain_t;
00103 
00104 /** Proxmity gain settings */
00105 typedef enum {
00106   APDS9960_PGAIN_1X = 0x00, /**< 1x gain */
00107   APDS9960_PGAIN_2X = 0x04, /**< 2x gain */
00108   APDS9960_PGAIN_4X = 0x08, /**< 4x gain */
00109   APDS9960_PGAIN_8X = 0x0C  /**< 8x gain */
00110 } apds9960PGain_t;
00111 
00112 /** Pulse length settings */
00113 typedef enum {
00114   APDS9960_PPULSELEN_4US = 0x00,  /**< 4uS */
00115   APDS9960_PPULSELEN_8US = 0x40,  /**< 8uS */
00116   APDS9960_PPULSELEN_16US = 0x80, /**< 16uS */
00117   APDS9960_PPULSELEN_32US = 0xC0  /**< 32uS */
00118 } apds9960PPulseLen_t;
00119 
00120 /** LED drive settings */
00121 typedef enum {
00122   APDS9960_LEDDRIVE_100MA = 0x00, /**< 100mA */
00123   APDS9960_LEDDRIVE_50MA = 0x40,  /**< 50mA */
00124   APDS9960_LEDDRIVE_25MA = 0x80,  /**< 25mA */
00125   APDS9960_LEDDRIVE_12MA = 0xC0   /**< 12.5mA */
00126 } apds9960LedDrive_t;
00127 
00128 /** LED boost settings */
00129 typedef enum {
00130   APDS9960_LEDBOOST_100PCNT = 0x00, /**< 100% */
00131   APDS9960_LEDBOOST_150PCNT = 0x10, /**< 150% */
00132   APDS9960_LEDBOOST_200PCNT = 0x20, /**< 200% */
00133   APDS9960_LEDBOOST_300PCNT = 0x30  /**< 300% */
00134 } apds9960LedBoost_t;
00135 
00136 /** Dimensions */
00137 enum {
00138   APDS9960_DIMENSIONS_ALL = 0x00,        // All dimensions
00139   APDS9960_DIMENSIONS_UP_DOWN = 0x01,    // Up/Down dimensions
00140   APGS9960_DIMENSIONS_LEFT_RIGHT = 0x02, // Left/Right dimensions
00141 };
00142 
00143 /** FIFO Interrupts */
00144 enum {
00145   APDS9960_GFIFO_1 = 0x00,  // Generate interrupt after 1 dataset in FIFO
00146   APDS9960_GFIFO_4 = 0x01,  // Generate interrupt after 2 datasets in FIFO
00147   APDS9960_GFIFO_8 = 0x02,  // Generate interrupt after 3 datasets in FIFO
00148   APDS9960_GFIFO_16 = 0x03, // Generate interrupt after 4 datasets in FIFO
00149 };
00150 
00151 /** Gesture Gain */
00152 enum {
00153   APDS9960_GGAIN_1 = 0x00, // Gain 1x
00154   APDS9960_GGAIN_2 = 0x01, // Gain 2x
00155   APDS9960_GGAIN_4 = 0x02, // Gain 4x
00156   APDS9960_GGAIN_8 = 0x03, // Gain 8x
00157 };
00158 
00159 /** Pulse Lenghts */
00160 enum {
00161   APDS9960_GPULSE_4US = 0x00,  // Pulse 4us
00162   APDS9960_GPULSE_8US = 0x01,  // Pulse 8us
00163   APDS9960_GPULSE_16US = 0x02, // Pulse 16us
00164   APDS9960_GPULSE_32US = 0x03, // Pulse 32us
00165 };
00166 
00167 #define APDS9960_UP 0x01    /**< Gesture Up */
00168 #define APDS9960_DOWN 0x02  /**< Gesture Down */
00169 #define APDS9960_LEFT 0x03  /**< Gesture Left */
00170 #define APDS9960_RIGHT 0x04 /**< Gesture Right */
00171 
00172 /*!
00173  *  @brief  Class that stores state and functions for interacting with
00174  *          APDS9960 Sensor
00175  */
00176 class Adafruit_APDS9960 {
00177 public:
00178   Adafruit_APDS9960(Serial *serial){_pc=serial;};
00179   ~Adafruit_APDS9960(){};
00180 
00181   boolean begin(I2C *theWire, uint16_t iTimeMS = 10, apds9960AGain_t = APDS9960_AGAIN_4X,
00182                 uint8_t addr = APDS9960_ADDRESS);
00183   void setADCIntegrationTime(uint16_t iTimeMS);
00184   float getADCIntegrationTime();
00185   void setADCGain(apds9960AGain_t gain);
00186   apds9960AGain_t getADCGain();
00187   void setLED(apds9960LedDrive_t drive, apds9960LedBoost_t boost);
00188 
00189   // proximity
00190   void enableProximity(boolean en = true);
00191   void setProxGain(apds9960PGain_t gain);
00192   apds9960PGain_t getProxGain();
00193   void setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses);
00194   void enableProximityInterrupt();
00195   void disableProximityInterrupt();
00196   uint8_t readProximity();
00197   void setProximityInterruptThreshold(uint8_t low, uint8_t high,
00198                                       uint8_t persistance = 4);
00199   bool getProximityInterrupt();
00200 
00201   // gesture
00202   void enableGesture(boolean en = true);
00203   bool gestureValid();
00204   void setGestureDimensions(uint8_t dims);
00205   void setGestureFIFOThreshold(uint8_t thresh);
00206   void setGestureGain(uint8_t gain);
00207   void setGestureProximityThreshold(uint8_t thresh);
00208   void setGestureOffset(uint8_t offset_up, uint8_t offset_down,
00209                         uint8_t offset_left, uint8_t offset_right);
00210   uint8_t readGesture();
00211   void resetCounts();
00212 
00213   // light & color
00214   void enableColor(boolean en = true);
00215   bool colorDataReady();
00216   void getColorData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
00217   uint16_t calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b);
00218   uint16_t calculateLux(uint16_t r, uint16_t g, uint16_t b);
00219   void enableColorInterrupt();
00220   void disableColorInterrupt();
00221   void clearInterrupt();
00222   void setIntLimits(uint16_t l, uint16_t h);
00223 
00224   // turn on/off elements
00225   void enable(boolean en = true);
00226 
00227 private:
00228   uint8_t _i2caddr;
00229   I2C *_wire;
00230   Serial *_pc;
00231 
00232   uint32_t read32(uint8_t reg);
00233   uint16_t read16(uint8_t reg);
00234   uint16_t read16R(uint8_t reg);
00235 
00236   void write8(byte reg, byte value);
00237   uint8_t read8(byte reg);
00238 
00239   uint8_t gestCnt;
00240 
00241   uint8_t UCount;
00242   uint8_t DCount;
00243 
00244   uint8_t LCount;
00245   uint8_t RCount;
00246 
00247   uint8_t read(uint8_t reg, uint8_t *buf, uint8_t num);
00248   void write(uint8_t reg, uint8_t *buf, uint8_t num);
00249   void _i2c_init();
00250 
00251   struct enable {
00252 
00253     // power on
00254     uint8_t PON : 1;
00255 
00256     // ALS enable
00257     uint8_t AEN : 1;
00258 
00259     // Proximity detect enable
00260     uint8_t PEN : 1;
00261 
00262     // wait timer enable
00263     uint8_t WEN : 1;
00264 
00265     // ALS interrupt enable
00266     uint8_t AIEN : 1;
00267 
00268     // proximity interrupt enable
00269     uint8_t PIEN : 1;
00270 
00271     // gesture enable
00272     uint8_t GEN : 1;
00273 
00274     uint8_t get() {
00275       return (GEN << 6) | (PIEN << 5) | (AIEN << 4) | (WEN << 3) | (PEN << 2) |
00276              (AEN << 1) | PON;
00277     };
00278   };
00279   struct enable _enable;
00280 
00281   struct pers {
00282     // ALS Interrupt Persistence. Controls rate of Clear channel interrupt to
00283     // the host processor
00284     uint8_t APERS : 4;
00285 
00286     // proximity interrupt persistence, controls rate of prox interrupt to host
00287     // processor
00288     uint8_t PPERS : 4;
00289 
00290     uint8_t get() { return (PPERS << 4) | APERS; };
00291   };
00292   pers _pers;
00293 
00294   struct config1 {
00295     uint8_t WLONG : 1;
00296 
00297     uint8_t get() { return WLONG << 1; };
00298   };
00299   config1 _config1;
00300 
00301   struct ppulse {
00302 
00303     /*Proximity Pulse Count. Specifies the number of proximity pulses to be
00304     generated on LDR. Number of pulses is set by PPULSE value plus 1.
00305     */
00306     uint8_t PPULSE : 6;
00307 
00308     // Proximity Pulse Length. Sets the LED-ON pulse width during a proximity
00309     // LDR pulse.
00310     uint8_t PPLEN : 2;
00311 
00312     uint8_t get() { return (PPLEN << 6) | PPULSE; }
00313   };
00314   ppulse _ppulse;
00315 
00316   struct control {
00317     // ALS and Color gain control
00318     uint8_t AGAIN : 2;
00319 
00320     // proximity gain control
00321     uint8_t PGAIN : 2;
00322 
00323     // led drive strength
00324     uint8_t LDRIVE : 2;
00325 
00326     uint8_t get() { return (LDRIVE << 6) | (PGAIN << 2) | AGAIN; }
00327   };
00328   control _control;
00329 
00330   struct config2 {
00331     /* Additional LDR current during proximity and gesture LED pulses. Current
00332     value, set by LDRIVE, is increased by the percentage of LED_BOOST.
00333     */
00334     uint8_t LED_BOOST : 2;
00335 
00336     // clear photodiode saturation int enable
00337     uint8_t CPSIEN : 1;
00338 
00339     // proximity saturation interrupt enable
00340     uint8_t PSIEN : 1;
00341 
00342     uint8_t get() {
00343       return (PSIEN << 7) | (CPSIEN << 6) | (LED_BOOST << 4) | 1;
00344     }
00345   };
00346   config2 _config2;
00347 
00348   struct status {
00349     /* ALS Valid. Indicates that an ALS cycle has completed since AEN was
00350     asserted or since a read from any of the ALS/Color data registers.
00351     */
00352     uint8_t AVALID : 1;
00353 
00354     /* Proximity Valid. Indicates that a proximity cycle has completed since PEN
00355     was asserted or since PDATA was last read. A read of PDATA automatically
00356     clears PVALID.
00357     */
00358     uint8_t PVALID : 1;
00359 
00360     /* Gesture Interrupt. GINT is asserted when GFVLV becomes greater than
00361     GFIFOTH or if GVALID has become asserted when GMODE transitioned to zero.
00362     The bit is reset when FIFO is completely emptied (read).
00363     */
00364     uint8_t GINT : 1;
00365 
00366     // ALS Interrupt. This bit triggers an interrupt if AIEN in ENABLE is set.
00367     uint8_t AINT : 1;
00368 
00369     // Proximity Interrupt. This bit triggers an interrupt if PIEN in ENABLE is
00370     // set.
00371     uint8_t PINT : 1;
00372 
00373     /* Indicates that an analog saturation event occurred during a previous
00374     proximity or gesture cycle. Once set, this bit remains set until cleared by
00375     clear proximity interrupt special function command (0xE5 PICLEAR) or by
00376     disabling Prox (PEN=0). This bit triggers an interrupt if PSIEN is set.
00377     */
00378     uint8_t PGSAT : 1;
00379 
00380     /* Clear Photodiode Saturation. When asserted, the analog sensor was at the
00381     upper end of its dynamic range. The bit can be de-asserted by sending a
00382     Clear channel interrupt command (0xE6 CICLEAR) or by disabling the ADC
00383     (AEN=0). This bit triggers an interrupt if CPSIEN is set.
00384     */
00385     uint8_t CPSAT : 1;
00386 
00387     void set(uint8_t data) {
00388       AVALID = data & 0x01;
00389       PVALID = (data >> 1) & 0x01;
00390       GINT = (data >> 2) & 0x01;
00391       AINT = (data >> 4) & 0x01;
00392       PINT = (data >> 5) & 0x01;
00393       PGSAT = (data >> 6) & 0x01;
00394       CPSAT = (data >> 7) & 0x01;
00395     }
00396   };
00397   status _status;
00398 
00399   struct config3 {
00400     // proximity mask
00401     uint8_t PMASK_R : 1;
00402     uint8_t PMASK_L : 1;
00403     uint8_t PMASK_D : 1;
00404     uint8_t PMASK_U : 1;
00405 
00406     /* Sleep After Interrupt. When enabled, the device will automatically enter
00407     low power mode when the INT pin is asserted and the state machine has
00408     progressed to the SAI decision block. Normal operation is resumed when INT
00409     pin is cleared over I2C.
00410     */
00411     uint8_t SAI : 1;
00412 
00413     /* Proximity Gain Compensation Enable. This bit provides gain compensation
00414     when proximity photodiode signal is reduced as a result of sensor masking.
00415     If only one diode of the diode pair is contributing, then only half of the
00416     signal is available at the ADC; this results in a maximum ADC value of 127.
00417     Enabling PCMP enables an additional gain of 2X, resulting in a maximum ADC
00418     value of 255.
00419     */
00420     uint8_t PCMP : 1;
00421 
00422     uint8_t get() {
00423       return (PCMP << 5) | (SAI << 4) | (PMASK_U << 3) | (PMASK_D << 2) |
00424              (PMASK_L << 1) | PMASK_R;
00425     }
00426   };
00427   config3 _config3;
00428 
00429   struct gconf1 {
00430     /* Gesture Exit Persistence. When a number of consecutive “gesture end”
00431     occurrences become equal or greater to the GEPERS value, the Gesture state
00432     machine is exited.
00433     */
00434     uint8_t GEXPERS : 2;
00435 
00436     /* Gesture Exit Mask. Controls which of the gesture detector photodiodes
00437     (UDLR) will be included to determine a “gesture end” and subsequent exit
00438     of the gesture state machine. Unmasked UDLR data will be compared with the
00439     value in GTHR_OUT. Field value bits correspond to UDLR detectors.
00440     */
00441     uint8_t GEXMSK : 4;
00442 
00443     /* Gesture FIFO Threshold. This value is compared with the FIFO Level (i.e.
00444     the number of UDLR datasets) to generate an interrupt (if enabled).
00445     */
00446     uint8_t GFIFOTH : 2;
00447 
00448     uint8_t get() { return (GFIFOTH << 6) | (GEXMSK << 2) | GEXPERS; }
00449   };
00450   gconf1 _gconf1;
00451 
00452   struct gconf2 {
00453     /* Gesture Wait Time. The GWTIME controls the amount of time in a low power
00454     mode between gesture detection cycles.
00455     */
00456     uint8_t GWTIME : 3;
00457 
00458     // Gesture LED Drive Strength. Sets LED Drive Strength in gesture mode.
00459     uint8_t GLDRIVE : 2;
00460 
00461     // Gesture Gain Control. Sets the gain of the proximity receiver in gesture
00462     // mode.
00463     uint8_t GGAIN : 2;
00464 
00465     uint8_t get() { return (GGAIN << 5) | (GLDRIVE << 3) | GWTIME; }
00466   };
00467   gconf2 _gconf2;
00468 
00469   struct gpulse {
00470     /* Number of Gesture Pulses. Specifies the number of pulses to be generated
00471     on LDR. Number of pulses is set by GPULSE value plus 1.
00472     */
00473     uint8_t GPULSE : 6;
00474 
00475     // Gesture Pulse Length. Sets the LED_ON pulse width during a Gesture LDR
00476     // Pulse.
00477     uint8_t GPLEN : 2;
00478 
00479     uint8_t get() { return (GPLEN << 6) | GPULSE; }
00480   };
00481   gpulse _gpulse;
00482 
00483   struct gconf3 {
00484     /* Gesture Dimension Select. Selects which gesture photodiode pairs are
00485     enabled to gather results during gesture.
00486     */
00487     uint8_t GDIMS : 2;
00488 
00489     uint8_t get() { return GDIMS; }
00490   };
00491   gconf3 _gconf3;
00492 
00493   struct gconf4 {
00494     /* Gesture Mode. Reading this bit reports if the gesture state machine is
00495     actively running, 1 = Gesture, 0= ALS, Proximity, Color. Writing a 1 to this
00496     bit causes immediate entry in to the gesture state machine (as if GPENTH had
00497     been exceeded). Writing a 0 to this bit causes exit of gesture when current
00498     analog conversion has finished (as if GEXTH had been exceeded).
00499     */
00500     uint8_t GMODE : 1;
00501 
00502     /* Gesture interrupt enable. Gesture Interrupt Enable. When asserted, all
00503     gesture related interrupts are unmasked.
00504     */
00505     uint8_t GIEN : 2;
00506 
00507     uint8_t get() { return (GIEN << 1) | GMODE; }
00508     void set(uint8_t data) {
00509       GIEN = (data >> 1) & 0x01;
00510       GMODE = data & 0x01;
00511     }
00512   };
00513   gconf4 _gconf4;
00514 
00515   struct gstatus {
00516     /* Gesture FIFO Data. GVALID bit is sent when GFLVL becomes greater than
00517     GFIFOTH (i.e. FIFO has enough data to set GINT). GFIFOD is reset when GMODE
00518     = 0 and the GFLVL=0 (i.e. All FIFO data has been read).
00519     */
00520     uint8_t GVALID : 1;
00521 
00522     /* Gesture FIFO Overflow. A setting of 1 indicates that the FIFO has filled
00523     to capacity and that new gesture detector data has been lost.
00524     */
00525     uint8_t GFOV : 1;
00526 
00527     void set(uint8_t data) {
00528       GFOV = (data >> 1) & 0x01;
00529       GVALID = data & 0x01;
00530     }
00531   };
00532   gstatus _gstatus;
00533 };
00534 
00535 #endif