SI1133 light sensor
Si1133.h
- Committer:
- brunnobbco
- Date:
- 2019-11-06
- Revision:
- 0:fe6c4edd0ecc
File content as of revision 0:fe6c4edd0ecc:
/***************************************************************************//** * @file Si1133.h ******************************************************************************* * @section License * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b> ******************************************************************************* * * SPDX-License-Identifier: Apache-2.0 * * 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. * ******************************************************************************/ #ifndef SI1133_H #define SI1133_H #include "mbed.h" /** Si1133 class. * Used for taking Light level and UV index measurements. * * Example: * @code * #include "mbed.h" * #include "Si1133.h" * * //Create an Si1133 object * Si1133 sensor(PC4, PC5); * * int main() * { * //Try to open the Si1133 * if (sensor.open()) { * printf("Device detected!\n"); * * while (1) { * //Print the current light level * printf("Lux = %.3f\n", (float)sensor.get_light_level()); * //Print the current UV index * printf("UV index = %.3f\n", (float)sensor.get_uv_index()); * * //Sleep for 0.5 seconds * wait(0.5); * } * } else { * error("Device not detected!\n"); * } * } * @endcode */ class Si1133 { public: /** Create an Si1133 object connected to the specified I2C pins with the specified I2C slave address * * @param sda The I2C data pin. * @param scl The I2C clock pin. * @param hz The I2C bus frequency (defaults to 400kHz). */ Si1133(PinName sda, PinName scl, int hz = 400000); /** * Si1133 destructor */ ~Si1133(void); /** Probe for the Si1133 and try to initialize the sensor * * @returns * 'true' if the device exists on the bus, * 'false' if the device doesn't exist on the bus. */ bool open(); /** Measure the current light level (in lux) on the Si1133 * * @returns The current temperature measurement in Lux. */ float get_light_level(); /** Measure the current UV Index on the Si1133 * * @returns The current UV index measurement. */ float get_uv_index(); /** Do a combined measurement and return both the light level and UV index * * @param[out] light_level Measured light level in Lux * @param[out] uv_index Measured UV index * * @returns true if measurement was successful */ bool get_light_and_uv(float *light_level, float *uv_index); #ifdef MBED_OPERATORS /** A shorthand for get_light_level() * * @returns The current temperature measurement in Lux. */ operator float(); #endif private: /** * @name I2C Registers * @{ */ enum Register { REG_PART_ID = 0x00, /**< Part ID */ REG_HW_ID = 0x01, /**< Hardware ID */ REG_REV_ID = 0x02, /**< Hardware revision */ REG_HOSTIN0 = 0x0A, /**< Data for parameter table on PARAM_SET write to COMMAND register */ REG_COMMAND = 0x0B, /**< Initiated action in Sensor when specific codes written here */ REG_IRQ_ENABLE = 0x0F, /**< Interrupt enable */ REG_RESPONSE1 = 0x10, /**< Contains the readback value from a query or a set command */ REG_RESPONSE0 = 0x11, /**< Chip state and error status */ REG_IRQ_STATUS = 0x12, /**< Interrupt status */ REG_HOSTOUT0 = 0x13, /**< Captured Sensor Data */ REG_HOSTOUT1 = 0x14, /**< Captured Sensor Data */ REG_HOSTOUT2 = 0x15, /**< Captured Sensor Data */ REG_HOSTOUT3 = 0x16, /**< Captured Sensor Data */ REG_HOSTOUT4 = 0x17, /**< Captured Sensor Data */ REG_HOSTOUT5 = 0x18, /**< Captured Sensor Data */ REG_HOSTOUT6 = 0x19, /**< Captured Sensor Data */ REG_HOSTOUT7 = 0x1A, /**< Captured Sensor Data */ REG_HOSTOUT8 = 0x1B, /**< Captured Sensor Data */ REG_HOSTOUT9 = 0x1C, /**< Captured Sensor Data */ REG_HOSTOUT10 = 0x1D, /**< Captured Sensor Data */ REG_HOSTOUT11 = 0x1E, /**< Captured Sensor Data */ REG_HOSTOUT12 = 0x1F, /**< Captured Sensor Data */ REG_HOSTOUT13 = 0x20, /**< Captured Sensor Data */ REG_HOSTOUT14 = 0x21, /**< Captured Sensor Data */ REG_HOSTOUT15 = 0x22, /**< Captured Sensor Data */ REG_HOSTOUT16 = 0x23, /**< Captured Sensor Data */ REG_HOSTOUT17 = 0x24, /**< Captured Sensor Data */ REG_HOSTOUT18 = 0x25, /**< Captured Sensor Data */ REG_HOSTOUT19 = 0x26, /**< Captured Sensor Data */ REG_HOSTOUT20 = 0x27, /**< Captured Sensor Data */ REG_HOSTOUT21 = 0x28, /**< Captured Sensor Data */ REG_HOSTOUT22 = 0x29, /**< Captured Sensor Data */ REG_HOSTOUT23 = 0x2A, /**< Captured Sensor Data */ REG_HOSTOUT24 = 0x2B, /**< Captured Sensor Data */ REG_HOSTOUT25 = 0x2C, /**< Captured Sensor Data */ }; /**@}*/ /** * @name Parameters * @{ */ enum Parameter { PARAM_I2C_ADDR = 0x00, /**< I2C address */ PARAM_CH_LIST = 0x01, /**< Channel list */ PARAM_ADCCONFIG0 = 0x02, /**< ADC config for Channel 0 */ PARAM_ADCSENS0 = 0x03, /**< ADC sensitivity setting for Channel 0 */ PARAM_ADCPOST0 = 0x04, /**< ADC resolution, shift and threshold settings for Channel 0 */ PARAM_MEASCONFIG0 = 0x05, /**< ADC measurement counter selection for Channel 0 */ PARAM_ADCCONFIG1 = 0x06, /**< ADC config for Channel 1 */ PARAM_ADCSENS1 = 0x07, /**< ADC sensitivity setting for Channel 1 */ PARAM_ADCPOST1 = 0x08, /**< ADC resolution, shift and threshold settings for Channel 1 */ PARAM_MEASCONFIG1 = 0x09, /**< ADC measurement counter selection for Channel 1 */ PARAM_ADCCONFIG2 = 0x0A, /**< ADC config for Channel 2 */ PARAM_ADCSENS2 = 0x0B, /**< ADC sensitivity setting for Channel 2 */ PARAM_ADCPOST2 = 0x0C, /**< ADC resolution, shift and threshold settings for Channel 2 */ PARAM_MEASCONFIG2 = 0x0D, /**< ADC measurement counter selection for Channel 2 */ PARAM_ADCCONFIG3 = 0x0E, /**< ADC config for Channel 3 */ PARAM_ADCSENS3 = 0x0F, /**< ADC sensitivity setting for Channel 3 */ PARAM_ADCPOST3 = 0x10, /**< ADC resolution, shift and threshold settings for Channel 3 */ PARAM_MEASCONFIG3 = 0x11, /**< ADC measurement counter selection for Channel 3 */ PARAM_ADCCONFIG4 = 0x12, /**< ADC config for Channel 4 */ PARAM_ADCSENS4 = 0x13, /**< ADC sensitivity setting for Channel 4 */ PARAM_ADCPOST4 = 0x14, /**< ADC resolution, shift and threshold settings for Channel 4 */ PARAM_MEASCONFIG4 = 0x15, /**< ADC measurement counter selection for Channel 4 */ PARAM_ADCCONFIG5 = 0x16, /**< ADC config for Channel 5 */ PARAM_ADCSENS5 = 0x17, /**< ADC sensitivity setting for Channel 5 */ PARAM_ADCPOST5 = 0x18, /**< ADC resolution, shift and threshold settings for Channel 5 */ PARAM_MEASCONFIG5 = 0x19, /**< ADC measurement counter selection for Channel 5 */ PARAM_MEASRATE_H = 0x1A, /**< Main measurement rate counter MSB */ PARAM_MEASRATE_L = 0x1B, /**< Main measurement rate counter LSB */ PARAM_MEASCOUNT0 = 0x1C, /**< Measurement rate extension counter 0 */ PARAM_MEASCOUNT1 = 0x1D, /**< Measurement rate extension counter 1 */ PARAM_MEASCOUNT2 = 0x1E, /**< Measurement rate extension counter 2 */ PARAM_THRESHOLD0_H = 0x25, /**< Threshold level 0 MSB */ PARAM_THRESHOLD0_L = 0x26, /**< Threshold level 0 LSB */ PARAM_THRESHOLD1_H = 0x27, /**< Threshold level 1 MSB */ PARAM_THRESHOLD1_L = 0x28, /**< Threshold level 1 LSB */ PARAM_THRESHOLD2_H = 0x29, /**< Threshold level 2 MSB */ PARAM_THRESHOLD2_L = 0x2A, /**< Threshold level 2 LSB */ PARAM_BURST = 0x2B, /**< Burst enable and burst count */ }; /**@}*/ /** * @name Commands * @{ */ enum Command { CMD_RESET_CMD_CTR = 0x00, /**< Resets the command counter */ CMD_RESET = 0x01, /**< Forces a Reset */ CMD_NEW_ADDR = 0x02, /**< Stores the new I2C address */ CMD_FORCE_CH = 0x11, /**< Initiates a set of measurements specified in CHAN_LIST parameter */ CMD_PAUSE_CH = 0x12, /**< Pauses autonomous measurements */ CMD_START = 0x13, /**< Starts autonomous measurements */ CMD_PARAM_SET = 0x80, /**< Sets a parameter */ CMD_PARAM_QUERY = 0x40, /**< Reads a parameter */ }; /**@}*/ /** * @name Responses * @{ */ enum Response { RSP0_CHIPSTAT_MASK = 0xE0, /**< Chip state mask in Response0 register */ RSP0_COUNTER_MASK = 0x1F, /**< Command counter and error indicator mask in Response0 register */ RSP0_SLEEP = 0x20, /**< Sleep state indicator bit mask in Response0 register */ }; /**@}*/ /** * @brief * Structure to store the data measured by the Si1133 */ typedef struct { uint8_t irq_status; /**< Interrupt status of the device */ int32_t ch0; /**< Channel 0 measurement data */ int32_t ch1; /**< Channel 1 measurement data */ int32_t ch2; /**< Channel 2 measurement data */ int32_t ch3; /**< Channel 3 measurement data */ } Samples_t; /** * @brief * Structure to store the calculation coefficients */ typedef struct { int16_t info; /**< Info */ uint16_t mag; /**< Magnitude */ } Coeff_t; /** * @brief * Structure to store the coefficients used for Lux calculation */ typedef struct { Coeff_t coeff_high[4]; /**< High amplitude coeffs */ Coeff_t coeff_low[9]; /**< Low amplitude coeffs */ } LuxCoeff_t; /* Forward-declare constant coefficient table */ static const LuxCoeff_t lk; static const Coeff_t uk[]; /* Private functions */ uint32_t read_register(enum Register reg, uint8_t *data); uint32_t write_register(enum Register reg, uint8_t data); uint32_t write_register_block(enum Register reg, uint8_t length, uint8_t *data); uint32_t read_register_block(enum Register reg, uint8_t length, uint8_t *data); uint32_t get_irq_status(uint8_t *irq_status); uint32_t wait_until_sleep(void); uint32_t reset(void); uint32_t reset_cmd_counter (void); uint32_t send_cmd(enum Command command); uint32_t force_measurement (void); uint32_t pause_measurement (void); uint32_t start_measurement (void); uint32_t set_parameter (enum Parameter address, uint8_t value); uint32_t read_parameter (enum Parameter address); uint32_t init (void); uint32_t deinit (void); uint32_t measure (Samples_t *samples); int32_t get_uv (int32_t uv); int32_t get_lux (int32_t vis_high, int32_t vis_low, int32_t ir); uint32_t measure_lux_uv (float *lux, float *uvi); uint32_t get_measurement (float *lux, float *uvi); uint32_t get_hardware_id (uint8_t *hardware_id); int32_t calculate_polynomial_helper (int32_t input, int8_t fraction, uint16_t mag, int8_t shift); int32_t calculate_polynomial (int32_t x, int32_t y, uint8_t input_fraction, uint8_t output_fraction, uint8_t num_coeff, const Coeff_t *kp); /* Member variables */ I2C m_I2C; }; #endif