OSRAM SFH7779 device driver: Ambient Light and proximity Sensor with Integrated 940nm IR Emitter Version 1.2
SFH7779.h
- Committer:
- ninensei
- Date:
- 2017-09-14
- Revision:
- 1:fe29e6d3a11e
File content as of revision 1:fe29e6d3a11e:
/* mbed Microcontroller Library
* Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** \addtogroup drivers */
/** Support for the OSRAM SFH7779 I2C IR-LED, proximity and ambient light sensor
*
* Example:
* @code
*
* #include "mbed.h"
* #include "SFH7779.h"
*
* I2C i2c(I2C_SDA, I2C_SCL);
* SFH7779<I2C> sfh7779(&i2c);
*
* int main() {
* sfh7779_measurements_t data;
* bool ok;
*
* ok = sfh7779.enable() &&
* sfh7779.read(&data) &&
* sfh7779.disable();
*
* if (ok) {
* printf("shf7779 proximity reading = %d\r\n", data.prox);
* } else {
* printf("shf7779 error!\r\n");
* }
* }
* @endcode
* @ingroup drivers
*/
#pragma once
#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;
template <class T>
class SFH7779
{
public:
/**
* Constructor
*
* @param i2c I2C class servicing the sensor
*/
SFH7779(T * 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:
T *_i2c;
};