Gsma Version
Dependents: GSMACode stripReader
sfh7779.h
- Committer:
- elmkom
- Date:
- 2017-04-21
- Revision:
- 1:fc2dbccffe34
- Parent:
- 0:5e15a306a518
File content as of revision 1:fc2dbccffe34:
// 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; };