Gsma Version

Dependents:   GSMACode stripReader

Revision:
0:5e15a306a518
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sfh7779.h	Wed Oct 26 18:39:17 2016 +0000
@@ -0,0 +1,203 @@
+// OSRAM SFH7779: I2C IR-LED, proximity sensor, and ambient light sensor
+
+#define SFH7779_BASE_ADDR_7BIT  0x39
+
+#define SYSTEM_CONTROL_REG  0x40
+
+#define MODE_CONTROL_REG    0x41
+#define   PS_MODE_NORMAL        (0x00<<4)   // default
+#define   PS_MODE_TWO_PULSE     (0x10<<4)
+#define   MRR_ALS0PS0           (0x00<<0)   // default
+#define   MRR_ALS0PS10          (0x01<<0)
+#define   MRR_ALS0PS40          (0x02<<0)
+#define   MRR_ALS0PS100         (0x03<<0)    
+#define   MRR_ALS0PS400         (0x04<<0)
+#define   MRR_ALS100PS0         (0x05<<0)
+#define   MRR_ALS100PS100       (0x06<<0)
+#define   MRR_ALS100PS400       (0x07<<0)
+#define   MRR_ALS401PS0         (0x08<<0)
+#define   MRR_ALS401PS100       (0x09<<0)
+#define   MRR_ALS400PS0         (0x0A<<0)   
+#define   MRR_ALS400PS400       (0x0B<<0)
+#define   MRR_ALS50PS50         (0x0C<<0)
+
+#define ALS_PS_CONTROL_REG  0x42
+#define   PS_OUT_PROXIMITY      (0x00<<6)   // default
+#define   PS_OUT_INFRARED_DC    (0x01<<6)
+#define   ALS_GAIN_ALS1IR1      (0x00<<2)   // default
+#define   ALS_GAIN_ALS2IR1      (0x04<<2)
+#define   ALS_GAIN_ALS2IR2      (0x05<<2)
+#define   ALS_GAIN_ALS64IR64    (0x0A<<2)
+#define   ALS_GAIN_ALS128IR64   (0x0E<<2)
+#define   ALS_GAIN_ALS128IR128  (0x0F<<2)
+#define   LED_CURRENT_25MA      (0x00<<0)
+#define   LED_CURRENT_50MA      (0x01<<0)
+#define   LED_CURRENT_100M      (0x02<<0)
+#define   LED_CURRENT_200MA     (0x03<<0)   // default
+
+#define PERSISTANCE_REG     0x43
+#define   INTR_ON_DATA_AVAIL    (0x00<<0)
+#define   INTR_AFTER_1_VAL      (0x01<<0)   // default
+#define   INTR_AFTER_2_VALS     (0x02<<0)
+#define   INTR_AFTER_3_VALS     (0x03<<0)
+#define   INTR_AFTER_4_VALS     (0x04<<0)
+#define   INTR_AFTER_5_VALS     (0x05<<0)
+#define   INTR_AFTER_6_VALS     (0x06<<0)
+#define   INTR_AFTER_7_VALS     (0x07<<0)
+#define   INTR_AFTER_8_VALS     (0x08<<0)
+#define   INTR_AFTER_9_VALS     (0x09<<0)
+#define   INTR_AFTER_10_VALS    (0x0A<<0)
+#define   INTR_AFTER_11_VALS    (0x0B<<0)
+#define   INTR_AFTER_12_VALS    (0x0C<<0)
+#define   INTR_AFTER_13_VALS    (0x0D<<0)
+#define   INTR_AFTER_14_VALS    (0x0E<<0)
+#define   INTR_AFTER_15_VALS    (0x0F<<0)
+
+#define PS_DATA_LSB_REG         0x44
+#define PS_DATA_MSB_REG         0x45
+#define ALS_VIS_DATA_LSB_REG    0x46
+#define ALS_VIS_DATA_MSB_REG    0x47
+#define ALS_IR_DATA_LSB_REG     0x48
+#define ALS_IR_DATA_MSB_REG     0x49
+
+#define INTERRUPT_CONTROL_REG   0x4A
+#define   PS_INT_ACTIVE             (0x01<<7)
+#define   ALS_INT_ACTIVE            (0x01<<6)
+#define   INT_MODE_PS_HIGH          (0x00<<4)   // default
+#define   INT_MODE_PS_HIGHLOW_HYS   (0x01<<4)
+#define   INT_MODE_PS_HIGHLOW_OD    (0x02<<4)
+#define   INT_ASSERT_LOW_ONLY       (0x00<<3)   // default
+#define   INT_ASSERT_LOW_THEN_HIGH  (0x01<<3)
+#define   INT_LATCHED               (0x00<<2)   // default
+#define   INT_UNLATCHED             (0x01<<2)
+#define   INT_PIN_INACTIVE          (0x00<<0)   // default
+#define   INT_PIN_PS_ONLY           (0x01<<0)   // default
+#define   INT_PIN_ALS_ONLY          (0x02<<0)   // default
+#define   INT_PIN_PS_AND_ALS        (0x03<<0)   // default
+
+typedef struct {
+    short   prox;
+    short   als_vis;
+    short   als_ir;
+} sfh7779_measurements_t;
+
+class SFH7779
+{
+public:
+    /**
+    * Constructor
+    *
+    * @param i2c I2C class servicing the sensor
+    */
+    SFH7779(I2C * i2c) : _i2c(i2c) {};
+
+protected:
+    /**
+    * Write to a sensor register
+    *
+    * @param reg sensor register to write
+    * @param val value to write
+    *
+    * @returns true if successful
+    */
+    bool write_reg(char reg, char val) {
+        char out[2] = {reg, val};
+        return 0 == _i2c->write(SFH7779_BASE_ADDR_7BIT << 1, out, 2);
+    }
+    
+    /**
+    * Read multiple sensor registers
+    *
+    * @param start_reg first sensor register to be read
+    * @param count number of registers to be read
+    * @param buff pointer to buffer where to store the register values
+    *
+    * @returns true if successful
+    */
+    bool read_regs(char start_reg, uint8_t count, void * buff) {
+        bool ok;
+        ok = (0 == _i2c->write(SFH7779_BASE_ADDR_7BIT << 1, &start_reg, 1, true))
+             && (0 == _i2c->read(SFH7779_BASE_ADDR_7BIT << 1, (char *)buff, count));
+        return ok;
+    }
+    
+public:
+    /**
+    * Activate the sensor (begin measurement sampling).  Data samples are
+    * taken 10 times per second.
+    *
+    * @param start_reg first sensor register to be read
+    * @param count number of registers to be read
+    * @param buff pointer to buffer where to store the register values
+    *
+    * @returns true if successful
+    */
+    bool enable(void) {
+        bool ok;
+        ok = write_reg(MODE_CONTROL_REG,        // Start ALS and PS sampling
+                    PS_MODE_NORMAL | MRR_ALS100PS100)
+             && write_reg(ALS_PS_CONTROL_REG,   // set ALS_VIS=ALS_IR GAIN = 64 current 25ma
+                    PS_OUT_PROXIMITY | ALS_GAIN_ALS64IR64 | LED_CURRENT_25MA)
+             && write_reg(PERSISTANCE_REG,      // set interrupt flag upon [any] data available
+                    INTR_ON_DATA_AVAIL);
+        return ok;
+    }
+        
+    /**
+    * Deactivate the sensor (stop measurement sampling and put the sensor in
+    * standby/low-power mode)
+    *
+    * @returns true if successful
+    */
+    bool disable(void) {
+        bool ok;        
+        ok = write_reg(MODE_CONTROL_REG,       // Stop ALS and PS sampling
+                    PS_MODE_NORMAL | MRR_ALS0PS0);
+        return ok;
+    }
+        
+    /**
+    * Wait for and return the next new sensor measurement (proximity,
+    * ambient visual light, and ambient infrared light).
+    *
+    * @param buff pointer to buffer where to store the register values
+    * @param timeout_ms maximum time to wait for a new sample to become
+    *          available.  Time is in milliseconds.  Example timeouts are:
+    *            0 - return a sample if one is available, otherwise don't
+    *                wait.
+    *            n - wait up to n milliseconds for a sample to become
+    *                available.
+    *           -1 - wait forever for a sample to become available
+    *
+    * @returns true if successful 
+    */
+    bool read(sfh7779_measurements_t * buff, int timeout_ms = -1) {
+        Timer timer;
+        timer.start();
+        while (true) {
+            struct PACKED {
+                sfh7779_measurements_t  measurements;
+                char                    stat;
+            } in;
+            if (false == read_regs(PS_DATA_LSB_REG, sizeof(in), &in)) {
+                break;
+            }
+            if (in.stat & PS_INT_ACTIVE) {
+                *buff = in.measurements;
+                return true;
+            }
+            if (timeout_ms != -1 && (timer.read_ms() >= timeout_ms)) {
+                break;
+            }
+#ifdef RTOS_H
+            Thread::wait(5);
+#else
+            wait(0.005);
+#endif
+        }
+        return false;
+    }
+
+protected:
+    I2C *_i2c;
+};