Forked so that I can make it take I2C as a parameter; on a bus with other I2C things.

Fork of Si1133 by Silicon Labs

Revision:
0:667132a19341
Child:
2:1e2dd643afa8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Si1133.h	Sun Nov 12 15:58:26 2017 +0100
@@ -0,0 +1,297 @@
+/***************************************************************************//**
+ * @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 measurementGet (Samples_t *samples);
+    int32_t  getUv (int32_t uv);
+    int32_t  getLux (int32_t vis_high, int32_t vis_low, int32_t ir);
+    uint32_t measureLuxUvi (float *lux, float *uvi);
+    uint32_t getMeasurement (float *lux, float *uvi);
+    uint32_t getHardwareID (uint8_t *hardwareID);
+
+    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
\ No newline at end of file