Gsma Version

Dependents:   GSMACode stripReader

Committer:
elmkom
Date:
Fri Apr 21 17:58:08 2017 +0000
Revision:
1:fc2dbccffe34
Parent:
0:5e15a306a518
Proximity strip reader

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmkom 0:5e15a306a518 1 // OSRAM SFH7779: I2C IR-LED, proximity sensor, and ambient light sensor
elmkom 0:5e15a306a518 2
elmkom 0:5e15a306a518 3 #define SFH7779_BASE_ADDR_7BIT 0x39
elmkom 0:5e15a306a518 4
elmkom 0:5e15a306a518 5 #define SYSTEM_CONTROL_REG 0x40
elmkom 0:5e15a306a518 6
elmkom 0:5e15a306a518 7 #define MODE_CONTROL_REG 0x41
elmkom 0:5e15a306a518 8 #define PS_MODE_NORMAL (0x00<<4) // default
elmkom 0:5e15a306a518 9 #define PS_MODE_TWO_PULSE (0x10<<4)
elmkom 0:5e15a306a518 10 #define MRR_ALS0PS0 (0x00<<0) // default
elmkom 0:5e15a306a518 11 #define MRR_ALS0PS10 (0x01<<0)
elmkom 0:5e15a306a518 12 #define MRR_ALS0PS40 (0x02<<0)
elmkom 0:5e15a306a518 13 #define MRR_ALS0PS100 (0x03<<0)
elmkom 0:5e15a306a518 14 #define MRR_ALS0PS400 (0x04<<0)
elmkom 0:5e15a306a518 15 #define MRR_ALS100PS0 (0x05<<0)
elmkom 0:5e15a306a518 16 #define MRR_ALS100PS100 (0x06<<0)
elmkom 0:5e15a306a518 17 #define MRR_ALS100PS400 (0x07<<0)
elmkom 0:5e15a306a518 18 #define MRR_ALS401PS0 (0x08<<0)
elmkom 0:5e15a306a518 19 #define MRR_ALS401PS100 (0x09<<0)
elmkom 0:5e15a306a518 20 #define MRR_ALS400PS0 (0x0A<<0)
elmkom 0:5e15a306a518 21 #define MRR_ALS400PS400 (0x0B<<0)
elmkom 0:5e15a306a518 22 #define MRR_ALS50PS50 (0x0C<<0)
elmkom 0:5e15a306a518 23
elmkom 0:5e15a306a518 24 #define ALS_PS_CONTROL_REG 0x42
elmkom 0:5e15a306a518 25 #define PS_OUT_PROXIMITY (0x00<<6) // default
elmkom 0:5e15a306a518 26 #define PS_OUT_INFRARED_DC (0x01<<6)
elmkom 0:5e15a306a518 27 #define ALS_GAIN_ALS1IR1 (0x00<<2) // default
elmkom 0:5e15a306a518 28 #define ALS_GAIN_ALS2IR1 (0x04<<2)
elmkom 0:5e15a306a518 29 #define ALS_GAIN_ALS2IR2 (0x05<<2)
elmkom 0:5e15a306a518 30 #define ALS_GAIN_ALS64IR64 (0x0A<<2)
elmkom 0:5e15a306a518 31 #define ALS_GAIN_ALS128IR64 (0x0E<<2)
elmkom 0:5e15a306a518 32 #define ALS_GAIN_ALS128IR128 (0x0F<<2)
elmkom 0:5e15a306a518 33 #define LED_CURRENT_25MA (0x00<<0)
elmkom 0:5e15a306a518 34 #define LED_CURRENT_50MA (0x01<<0)
elmkom 0:5e15a306a518 35 #define LED_CURRENT_100M (0x02<<0)
elmkom 0:5e15a306a518 36 #define LED_CURRENT_200MA (0x03<<0) // default
elmkom 0:5e15a306a518 37
elmkom 0:5e15a306a518 38 #define PERSISTANCE_REG 0x43
elmkom 0:5e15a306a518 39 #define INTR_ON_DATA_AVAIL (0x00<<0)
elmkom 0:5e15a306a518 40 #define INTR_AFTER_1_VAL (0x01<<0) // default
elmkom 0:5e15a306a518 41 #define INTR_AFTER_2_VALS (0x02<<0)
elmkom 0:5e15a306a518 42 #define INTR_AFTER_3_VALS (0x03<<0)
elmkom 0:5e15a306a518 43 #define INTR_AFTER_4_VALS (0x04<<0)
elmkom 0:5e15a306a518 44 #define INTR_AFTER_5_VALS (0x05<<0)
elmkom 0:5e15a306a518 45 #define INTR_AFTER_6_VALS (0x06<<0)
elmkom 0:5e15a306a518 46 #define INTR_AFTER_7_VALS (0x07<<0)
elmkom 0:5e15a306a518 47 #define INTR_AFTER_8_VALS (0x08<<0)
elmkom 0:5e15a306a518 48 #define INTR_AFTER_9_VALS (0x09<<0)
elmkom 0:5e15a306a518 49 #define INTR_AFTER_10_VALS (0x0A<<0)
elmkom 0:5e15a306a518 50 #define INTR_AFTER_11_VALS (0x0B<<0)
elmkom 0:5e15a306a518 51 #define INTR_AFTER_12_VALS (0x0C<<0)
elmkom 0:5e15a306a518 52 #define INTR_AFTER_13_VALS (0x0D<<0)
elmkom 0:5e15a306a518 53 #define INTR_AFTER_14_VALS (0x0E<<0)
elmkom 0:5e15a306a518 54 #define INTR_AFTER_15_VALS (0x0F<<0)
elmkom 0:5e15a306a518 55
elmkom 0:5e15a306a518 56 #define PS_DATA_LSB_REG 0x44
elmkom 0:5e15a306a518 57 #define PS_DATA_MSB_REG 0x45
elmkom 0:5e15a306a518 58 #define ALS_VIS_DATA_LSB_REG 0x46
elmkom 0:5e15a306a518 59 #define ALS_VIS_DATA_MSB_REG 0x47
elmkom 0:5e15a306a518 60 #define ALS_IR_DATA_LSB_REG 0x48
elmkom 0:5e15a306a518 61 #define ALS_IR_DATA_MSB_REG 0x49
elmkom 0:5e15a306a518 62
elmkom 0:5e15a306a518 63 #define INTERRUPT_CONTROL_REG 0x4A
elmkom 0:5e15a306a518 64 #define PS_INT_ACTIVE (0x01<<7)
elmkom 0:5e15a306a518 65 #define ALS_INT_ACTIVE (0x01<<6)
elmkom 0:5e15a306a518 66 #define INT_MODE_PS_HIGH (0x00<<4) // default
elmkom 0:5e15a306a518 67 #define INT_MODE_PS_HIGHLOW_HYS (0x01<<4)
elmkom 0:5e15a306a518 68 #define INT_MODE_PS_HIGHLOW_OD (0x02<<4)
elmkom 0:5e15a306a518 69 #define INT_ASSERT_LOW_ONLY (0x00<<3) // default
elmkom 0:5e15a306a518 70 #define INT_ASSERT_LOW_THEN_HIGH (0x01<<3)
elmkom 0:5e15a306a518 71 #define INT_LATCHED (0x00<<2) // default
elmkom 0:5e15a306a518 72 #define INT_UNLATCHED (0x01<<2)
elmkom 0:5e15a306a518 73 #define INT_PIN_INACTIVE (0x00<<0) // default
elmkom 0:5e15a306a518 74 #define INT_PIN_PS_ONLY (0x01<<0) // default
elmkom 0:5e15a306a518 75 #define INT_PIN_ALS_ONLY (0x02<<0) // default
elmkom 0:5e15a306a518 76 #define INT_PIN_PS_AND_ALS (0x03<<0) // default
elmkom 0:5e15a306a518 77
elmkom 0:5e15a306a518 78 typedef struct {
elmkom 0:5e15a306a518 79 short prox;
elmkom 0:5e15a306a518 80 short als_vis;
elmkom 0:5e15a306a518 81 short als_ir;
elmkom 0:5e15a306a518 82 } sfh7779_measurements_t;
elmkom 0:5e15a306a518 83
elmkom 0:5e15a306a518 84 class SFH7779
elmkom 0:5e15a306a518 85 {
elmkom 0:5e15a306a518 86 public:
elmkom 0:5e15a306a518 87 /**
elmkom 0:5e15a306a518 88 * Constructor
elmkom 0:5e15a306a518 89 *
elmkom 0:5e15a306a518 90 * @param i2c I2C class servicing the sensor
elmkom 0:5e15a306a518 91 */
elmkom 0:5e15a306a518 92 SFH7779(I2C * i2c) : _i2c(i2c) {};
elmkom 0:5e15a306a518 93
elmkom 0:5e15a306a518 94 protected:
elmkom 0:5e15a306a518 95 /**
elmkom 0:5e15a306a518 96 * Write to a sensor register
elmkom 0:5e15a306a518 97 *
elmkom 0:5e15a306a518 98 * @param reg sensor register to write
elmkom 0:5e15a306a518 99 * @param val value to write
elmkom 0:5e15a306a518 100 *
elmkom 0:5e15a306a518 101 * @returns true if successful
elmkom 0:5e15a306a518 102 */
elmkom 0:5e15a306a518 103 bool write_reg(char reg, char val) {
elmkom 0:5e15a306a518 104 char out[2] = {reg, val};
elmkom 0:5e15a306a518 105 return 0 == _i2c->write(SFH7779_BASE_ADDR_7BIT << 1, out, 2);
elmkom 0:5e15a306a518 106 }
elmkom 0:5e15a306a518 107
elmkom 0:5e15a306a518 108 /**
elmkom 0:5e15a306a518 109 * Read multiple sensor registers
elmkom 0:5e15a306a518 110 *
elmkom 0:5e15a306a518 111 * @param start_reg first sensor register to be read
elmkom 0:5e15a306a518 112 * @param count number of registers to be read
elmkom 0:5e15a306a518 113 * @param buff pointer to buffer where to store the register values
elmkom 0:5e15a306a518 114 *
elmkom 0:5e15a306a518 115 * @returns true if successful
elmkom 0:5e15a306a518 116 */
elmkom 0:5e15a306a518 117 bool read_regs(char start_reg, uint8_t count, void * buff) {
elmkom 0:5e15a306a518 118 bool ok;
elmkom 0:5e15a306a518 119 ok = (0 == _i2c->write(SFH7779_BASE_ADDR_7BIT << 1, &start_reg, 1, true))
elmkom 0:5e15a306a518 120 && (0 == _i2c->read(SFH7779_BASE_ADDR_7BIT << 1, (char *)buff, count));
elmkom 0:5e15a306a518 121 return ok;
elmkom 0:5e15a306a518 122 }
elmkom 0:5e15a306a518 123
elmkom 0:5e15a306a518 124 public:
elmkom 0:5e15a306a518 125 /**
elmkom 0:5e15a306a518 126 * Activate the sensor (begin measurement sampling). Data samples are
elmkom 0:5e15a306a518 127 * taken 10 times per second.
elmkom 0:5e15a306a518 128 *
elmkom 0:5e15a306a518 129 * @param start_reg first sensor register to be read
elmkom 0:5e15a306a518 130 * @param count number of registers to be read
elmkom 0:5e15a306a518 131 * @param buff pointer to buffer where to store the register values
elmkom 0:5e15a306a518 132 *
elmkom 0:5e15a306a518 133 * @returns true if successful
elmkom 0:5e15a306a518 134 */
elmkom 0:5e15a306a518 135 bool enable(void) {
elmkom 0:5e15a306a518 136 bool ok;
elmkom 0:5e15a306a518 137 ok = write_reg(MODE_CONTROL_REG, // Start ALS and PS sampling
elmkom 0:5e15a306a518 138 PS_MODE_NORMAL | MRR_ALS100PS100)
elmkom 0:5e15a306a518 139 && write_reg(ALS_PS_CONTROL_REG, // set ALS_VIS=ALS_IR GAIN = 64 current 25ma
elmkom 0:5e15a306a518 140 PS_OUT_PROXIMITY | ALS_GAIN_ALS64IR64 | LED_CURRENT_25MA)
elmkom 0:5e15a306a518 141 && write_reg(PERSISTANCE_REG, // set interrupt flag upon [any] data available
elmkom 0:5e15a306a518 142 INTR_ON_DATA_AVAIL);
elmkom 0:5e15a306a518 143 return ok;
elmkom 0:5e15a306a518 144 }
elmkom 0:5e15a306a518 145
elmkom 0:5e15a306a518 146 /**
elmkom 0:5e15a306a518 147 * Deactivate the sensor (stop measurement sampling and put the sensor in
elmkom 0:5e15a306a518 148 * standby/low-power mode)
elmkom 0:5e15a306a518 149 *
elmkom 0:5e15a306a518 150 * @returns true if successful
elmkom 0:5e15a306a518 151 */
elmkom 0:5e15a306a518 152 bool disable(void) {
elmkom 0:5e15a306a518 153 bool ok;
elmkom 0:5e15a306a518 154 ok = write_reg(MODE_CONTROL_REG, // Stop ALS and PS sampling
elmkom 0:5e15a306a518 155 PS_MODE_NORMAL | MRR_ALS0PS0);
elmkom 0:5e15a306a518 156 return ok;
elmkom 0:5e15a306a518 157 }
elmkom 0:5e15a306a518 158
elmkom 0:5e15a306a518 159 /**
elmkom 0:5e15a306a518 160 * Wait for and return the next new sensor measurement (proximity,
elmkom 0:5e15a306a518 161 * ambient visual light, and ambient infrared light).
elmkom 0:5e15a306a518 162 *
elmkom 0:5e15a306a518 163 * @param buff pointer to buffer where to store the register values
elmkom 0:5e15a306a518 164 * @param timeout_ms maximum time to wait for a new sample to become
elmkom 0:5e15a306a518 165 * available. Time is in milliseconds. Example timeouts are:
elmkom 0:5e15a306a518 166 * 0 - return a sample if one is available, otherwise don't
elmkom 0:5e15a306a518 167 * wait.
elmkom 0:5e15a306a518 168 * n - wait up to n milliseconds for a sample to become
elmkom 0:5e15a306a518 169 * available.
elmkom 0:5e15a306a518 170 * -1 - wait forever for a sample to become available
elmkom 0:5e15a306a518 171 *
elmkom 0:5e15a306a518 172 * @returns true if successful
elmkom 0:5e15a306a518 173 */
elmkom 0:5e15a306a518 174 bool read(sfh7779_measurements_t * buff, int timeout_ms = -1) {
elmkom 0:5e15a306a518 175 Timer timer;
elmkom 0:5e15a306a518 176 timer.start();
elmkom 0:5e15a306a518 177 while (true) {
elmkom 0:5e15a306a518 178 struct PACKED {
elmkom 0:5e15a306a518 179 sfh7779_measurements_t measurements;
elmkom 0:5e15a306a518 180 char stat;
elmkom 0:5e15a306a518 181 } in;
elmkom 0:5e15a306a518 182 if (false == read_regs(PS_DATA_LSB_REG, sizeof(in), &in)) {
elmkom 0:5e15a306a518 183 break;
elmkom 0:5e15a306a518 184 }
elmkom 0:5e15a306a518 185 if (in.stat & PS_INT_ACTIVE) {
elmkom 0:5e15a306a518 186 *buff = in.measurements;
elmkom 0:5e15a306a518 187 return true;
elmkom 0:5e15a306a518 188 }
elmkom 0:5e15a306a518 189 if (timeout_ms != -1 && (timer.read_ms() >= timeout_ms)) {
elmkom 0:5e15a306a518 190 break;
elmkom 0:5e15a306a518 191 }
elmkom 0:5e15a306a518 192 #ifdef RTOS_H
elmkom 0:5e15a306a518 193 Thread::wait(5);
elmkom 0:5e15a306a518 194 #else
elmkom 0:5e15a306a518 195 wait(0.005);
elmkom 0:5e15a306a518 196 #endif
elmkom 0:5e15a306a518 197 }
elmkom 0:5e15a306a518 198 return false;
elmkom 0:5e15a306a518 199 }
elmkom 0:5e15a306a518 200
elmkom 0:5e15a306a518 201 protected:
elmkom 0:5e15a306a518 202 I2C *_i2c;
elmkom 0:5e15a306a518 203 };