Gsma Version
Dependents: GSMACode stripReader
sfh7779.h@1:fc2dbccffe34, 2017-04-21 (annotated)
- 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?
User | Revision | Line number | New 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 | }; |