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

Committer:
stevew817
Date:
Sun Nov 12 20:18:04 2017 +0100
Revision:
2:1e2dd643afa8
Parent:
1:410f61a3900b
Cosmetic changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stevew817 0:667132a19341 1 /***************************************************************************//**
stevew817 0:667132a19341 2 * @file Si1133.cpp
stevew817 0:667132a19341 3 *******************************************************************************
stevew817 0:667132a19341 4 * @section License
stevew817 0:667132a19341 5 * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
stevew817 0:667132a19341 6 *******************************************************************************
stevew817 0:667132a19341 7 *
stevew817 0:667132a19341 8 * SPDX-License-Identifier: Apache-2.0
stevew817 0:667132a19341 9 *
stevew817 0:667132a19341 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
stevew817 0:667132a19341 11 * not use this file except in compliance with the License.
stevew817 0:667132a19341 12 * You may obtain a copy of the License at
stevew817 0:667132a19341 13 *
stevew817 0:667132a19341 14 * http://www.apache.org/licenses/LICENSE-2.0
stevew817 0:667132a19341 15 *
stevew817 0:667132a19341 16 * Unless required by applicable law or agreed to in writing, software
stevew817 0:667132a19341 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
stevew817 0:667132a19341 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
stevew817 0:667132a19341 19 * See the License for the specific language governing permissions and
stevew817 0:667132a19341 20 * limitations under the License.
stevew817 0:667132a19341 21 *
stevew817 0:667132a19341 22 ******************************************************************************/
stevew817 0:667132a19341 23
stevew817 0:667132a19341 24 #include "Si1133.h"
stevew817 0:667132a19341 25
stevew817 0:667132a19341 26 #define SI1133_I2C_ADDRESS (0xAA) /** Hardcoded address for Si1133 sensor */
stevew817 0:667132a19341 27
stevew817 0:667132a19341 28 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
stevew817 0:667132a19341 29
stevew817 0:667132a19341 30 #define X_ORDER_MASK 0x0070
stevew817 0:667132a19341 31 #define Y_ORDER_MASK 0x0007
stevew817 0:667132a19341 32 #define SIGN_MASK 0x0080
stevew817 0:667132a19341 33 #define GET_X_ORDER(m) ( ((m) & X_ORDER_MASK) >> 4)
stevew817 0:667132a19341 34 #define GET_Y_ORDER(m) ( ((m) & Y_ORDER_MASK) )
stevew817 0:667132a19341 35 #define GET_SIGN(m) ( ((m) & SIGN_MASK) >> 7)
stevew817 0:667132a19341 36
stevew817 0:667132a19341 37 #define UV_INPUT_FRACTION 15
stevew817 0:667132a19341 38 #define UV_OUTPUT_FRACTION 12
stevew817 0:667132a19341 39 #define UV_NUMCOEFF 2
stevew817 0:667132a19341 40
stevew817 0:667132a19341 41 #define ADC_THRESHOLD 16000
stevew817 0:667132a19341 42 #define INPUT_FRACTION_HIGH 7
stevew817 0:667132a19341 43 #define INPUT_FRACTION_LOW 15
stevew817 0:667132a19341 44 #define LUX_OUTPUT_FRACTION 12
stevew817 0:667132a19341 45 #define NUMCOEFF_LOW 9
stevew817 0:667132a19341 46 #define NUMCOEFF_HIGH 4
stevew817 0:667132a19341 47
stevew817 0:667132a19341 48 /** @endcond */
stevew817 0:667132a19341 49
stevew817 0:667132a19341 50 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
stevew817 0:667132a19341 51 /***************************************************************************//**
stevew817 0:667132a19341 52 * @brief
stevew817 0:667132a19341 53 * Coefficients for lux calculation
stevew817 0:667132a19341 54 ******************************************************************************/
stevew817 0:667132a19341 55 const Si1133::LuxCoeff_t Si1133::lk = {
stevew817 0:667132a19341 56 { { 0, 209 }, /**< coeff_high[0] */
stevew817 0:667132a19341 57 { 1665, 93 }, /**< coeff_high[1] */
stevew817 0:667132a19341 58 { 2064, 65 }, /**< coeff_high[2] */
stevew817 0:667132a19341 59 { -2671, 234 } }, /**< coeff_high[3] */
stevew817 0:667132a19341 60 { { 0, 0 }, /**< coeff_low[0] */
stevew817 0:667132a19341 61 { 1921, 29053 }, /**< coeff_low[1] */
stevew817 0:667132a19341 62 { -1022, 36363 }, /**< coeff_low[2] */
stevew817 0:667132a19341 63 { 2320, 20789 }, /**< coeff_low[3] */
stevew817 0:667132a19341 64 { -367, 57909 }, /**< coeff_low[4] */
stevew817 0:667132a19341 65 { -1774, 38240 }, /**< coeff_low[5] */
stevew817 0:667132a19341 66 { -608, 46775 }, /**< coeff_low[6] */
stevew817 0:667132a19341 67 { -1503, 51831 }, /**< coeff_low[7] */
stevew817 0:667132a19341 68 { -1886, 58928 } } /**< coeff_low[8] */
stevew817 0:667132a19341 69 };
stevew817 0:667132a19341 70
stevew817 0:667132a19341 71 /***************************************************************************//**
stevew817 0:667132a19341 72 * @brief
stevew817 0:667132a19341 73 * Coefficients for UV index calculation
stevew817 0:667132a19341 74 ******************************************************************************/
stevew817 0:667132a19341 75 const Si1133::Coeff_t Si1133::uk[2] = {
stevew817 0:667132a19341 76 { 1281, 30902 }, /**< coeff[0] */
stevew817 0:667132a19341 77 { -638, 46301 } /**< coeff[1] */
stevew817 0:667132a19341 78 };
stevew817 0:667132a19341 79
stevew817 0:667132a19341 80 /**************************************************************************//**
stevew817 0:667132a19341 81 * @name Error Codes
stevew817 0:667132a19341 82 * @{
stevew817 0:667132a19341 83 ******************************************************************************/
stevew817 0:667132a19341 84 #define SI1133_OK 0x0000 /**< No errors */
stevew817 0:667132a19341 85 #define SI1133_ERROR_I2C_TRANSACTION_FAILED 0x0001 /**< I2C transaction failed */
stevew817 0:667132a19341 86 #define SI1133_ERROR_SLEEP_FAILED 0x0002 /**< Entering sleep mode failed */
stevew817 0:667132a19341 87 /**@}*/
stevew817 0:667132a19341 88
stevew817 0:667132a19341 89 /** @endcond */
stevew817 0:667132a19341 90
stevew817 0:667132a19341 91 Si1133::Si1133(PinName sda, PinName scl, int hz) : m_I2C(sda, scl)
stevew817 0:667132a19341 92 {
stevew817 0:667132a19341 93 //Set the I2C bus frequency
stevew817 0:667132a19341 94 m_I2C.frequency(hz);
stevew817 0:667132a19341 95 }
stevew817 0:667132a19341 96
stevew817 0:667132a19341 97 Si1133::~Si1133(void)
stevew817 0:667132a19341 98 {
stevew817 0:667132a19341 99 deinit();
stevew817 0:667132a19341 100 }
stevew817 0:667132a19341 101
stevew817 0:667132a19341 102 bool Si1133::open()
stevew817 0:667132a19341 103 {
stevew817 0:667132a19341 104 //Probe for the Si1133 using a Zero Length Transfer
stevew817 0:667132a19341 105 if (m_I2C.write(SI1133_I2C_ADDRESS, NULL, 0)) {
stevew817 0:667132a19341 106 //Return success
stevew817 0:667132a19341 107 return false;
stevew817 0:667132a19341 108 }
stevew817 0:667132a19341 109
stevew817 0:667132a19341 110 // initialize sensor
stevew817 0:667132a19341 111 if (SI1133_OK == init()) {
stevew817 0:667132a19341 112 return true;
stevew817 0:667132a19341 113 }
stevew817 0:667132a19341 114 return false;
stevew817 0:667132a19341 115 }
stevew817 0:667132a19341 116
stevew817 0:667132a19341 117 /** Measure the current light level (in lux) on the Si1133
stevew817 0:667132a19341 118 *
stevew817 0:667132a19341 119 * @returns The current temperature measurement in Lux.
stevew817 0:667132a19341 120 */
stevew817 0:667132a19341 121 float Si1133::get_light_level()
stevew817 0:667132a19341 122 {
stevew817 0:667132a19341 123 float lux, uvi;
stevew817 2:1e2dd643afa8 124 measure_lux_uv(&lux, &uvi);
stevew817 0:667132a19341 125 return lux;
stevew817 0:667132a19341 126 }
stevew817 0:667132a19341 127
stevew817 0:667132a19341 128 /** Measure the current UV Index on the Si1133
stevew817 0:667132a19341 129 *
stevew817 0:667132a19341 130 * @returns The current UV index.
stevew817 0:667132a19341 131 */
stevew817 0:667132a19341 132 float Si1133::get_uv_index()
stevew817 0:667132a19341 133 {
stevew817 0:667132a19341 134 float lux, uvi;
stevew817 2:1e2dd643afa8 135 measure_lux_uv(&lux, &uvi);
stevew817 0:667132a19341 136 return uvi;
stevew817 0:667132a19341 137 }
stevew817 0:667132a19341 138
stevew817 1:410f61a3900b 139 bool Si1133::get_light_and_uv(float *light_level, float *uv_index)
stevew817 1:410f61a3900b 140 {
stevew817 2:1e2dd643afa8 141 if(measure_lux_uv(light_level, uv_index)) {
stevew817 1:410f61a3900b 142 return false;
stevew817 1:410f61a3900b 143 }
stevew817 1:410f61a3900b 144 return true;
stevew817 1:410f61a3900b 145 }
stevew817 1:410f61a3900b 146
stevew817 0:667132a19341 147 /***************************************************************************//**
stevew817 0:667132a19341 148 * @brief
stevew817 0:667132a19341 149 * Reads register from the Si1133 sensor
stevew817 0:667132a19341 150 *
stevew817 0:667132a19341 151 * @param[in] reg
stevew817 0:667132a19341 152 * The register address to read from in the sensor.
stevew817 0:667132a19341 153 *
stevew817 0:667132a19341 154 * @param[out] data
stevew817 0:667132a19341 155 * The data read from the sensor
stevew817 0:667132a19341 156 *
stevew817 0:667132a19341 157 * @return
stevew817 0:667132a19341 158 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 159 ******************************************************************************/
stevew817 0:667132a19341 160 uint32_t Si1133::read_register(enum Si1133::Register reg, uint8_t *data)
stevew817 0:667132a19341 161 {
stevew817 0:667132a19341 162 char buf[1];
stevew817 0:667132a19341 163 buf[0] = (char) reg;
stevew817 0:667132a19341 164
stevew817 0:667132a19341 165 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, 1, true)) {
stevew817 0:667132a19341 166 //Return failure
stevew817 0:667132a19341 167 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 168 }
stevew817 0:667132a19341 169
stevew817 0:667132a19341 170 if (m_I2C.read(SI1133_I2C_ADDRESS, buf, 1)) {
stevew817 0:667132a19341 171 //Return failure
stevew817 0:667132a19341 172 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 173 }
stevew817 0:667132a19341 174
stevew817 0:667132a19341 175 *data = buf[0];
stevew817 0:667132a19341 176
stevew817 0:667132a19341 177 return SI1133_OK;
stevew817 0:667132a19341 178 }
stevew817 0:667132a19341 179
stevew817 0:667132a19341 180 /***************************************************************************//**
stevew817 0:667132a19341 181 * @brief
stevew817 0:667132a19341 182 * Writes register in the Si1133 sensor
stevew817 0:667132a19341 183 *
stevew817 0:667132a19341 184 * @param[in] reg
stevew817 0:667132a19341 185 * The register address to write to in the sensor
stevew817 0:667132a19341 186 *
stevew817 0:667132a19341 187 * @param[in] data
stevew817 0:667132a19341 188 * The data to write to the sensor
stevew817 0:667132a19341 189 *
stevew817 0:667132a19341 190 * @return
stevew817 0:667132a19341 191 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 192 ******************************************************************************/
stevew817 0:667132a19341 193 uint32_t Si1133::write_register(enum Si1133::Register reg, uint8_t data)
stevew817 0:667132a19341 194 {
stevew817 0:667132a19341 195 char buf[2];
stevew817 0:667132a19341 196 buf[0] = (char) reg;
stevew817 0:667132a19341 197 buf[1] = (char) data;
stevew817 0:667132a19341 198
stevew817 0:667132a19341 199 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, 2)) {
stevew817 0:667132a19341 200 //Return failure
stevew817 0:667132a19341 201 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 202 }
stevew817 0:667132a19341 203
stevew817 0:667132a19341 204 return SI1133_OK;
stevew817 0:667132a19341 205 }
stevew817 0:667132a19341 206
stevew817 0:667132a19341 207 /***************************************************************************//**
stevew817 0:667132a19341 208 * @brief
stevew817 0:667132a19341 209 * Writes a block of data to the Si1133 sensor.
stevew817 0:667132a19341 210 *
stevew817 0:667132a19341 211 * @param[in] reg
stevew817 0:667132a19341 212 * The first register to begin writing to
stevew817 0:667132a19341 213 *
stevew817 0:667132a19341 214 * @param[in] length
stevew817 0:667132a19341 215 * The number of bytes to write to the sensor
stevew817 0:667132a19341 216 *
stevew817 0:667132a19341 217 * @param[in] data
stevew817 0:667132a19341 218 * The data to write to the sensor
stevew817 0:667132a19341 219 *
stevew817 0:667132a19341 220 * @return
stevew817 0:667132a19341 221 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 222 ******************************************************************************/
stevew817 0:667132a19341 223 uint32_t Si1133::write_register_block(enum Si1133::Register reg, uint8_t length, uint8_t *data)
stevew817 0:667132a19341 224 {
stevew817 0:667132a19341 225 char buf[length+1];
stevew817 0:667132a19341 226 buf[0] = (char)reg;
stevew817 0:667132a19341 227 memcpy(&buf[1], data, length);
stevew817 0:667132a19341 228
stevew817 0:667132a19341 229 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, length + 1)) {
stevew817 0:667132a19341 230 //Return failure
stevew817 0:667132a19341 231 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 232 }
stevew817 0:667132a19341 233
stevew817 0:667132a19341 234 return SI1133_OK;
stevew817 0:667132a19341 235 }
stevew817 0:667132a19341 236
stevew817 0:667132a19341 237 /***************************************************************************//**
stevew817 0:667132a19341 238 * @brief
stevew817 0:667132a19341 239 * Reads a block of data from the Si1133 sensor.
stevew817 0:667132a19341 240 *
stevew817 0:667132a19341 241 * @param[in] reg
stevew817 0:667132a19341 242 * The first register to begin reading from
stevew817 0:667132a19341 243 *
stevew817 0:667132a19341 244 * @param[in] length
stevew817 0:667132a19341 245 * The number of bytes to write to the sensor
stevew817 0:667132a19341 246 *
stevew817 0:667132a19341 247 * @param[out] data
stevew817 0:667132a19341 248 * The data read from the sensor
stevew817 0:667132a19341 249 *
stevew817 0:667132a19341 250 * @return
stevew817 0:667132a19341 251 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 252 ******************************************************************************/
stevew817 0:667132a19341 253 uint32_t Si1133::read_register_block(enum Si1133::Register reg, uint8_t length, uint8_t *data)
stevew817 0:667132a19341 254 {
stevew817 0:667132a19341 255 char reg_c = (char)reg;
stevew817 0:667132a19341 256 if (m_I2C.write(SI1133_I2C_ADDRESS, &reg_c, 1, true)) {
stevew817 0:667132a19341 257 //Return failure
stevew817 0:667132a19341 258 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 259 }
stevew817 0:667132a19341 260
stevew817 0:667132a19341 261 if (m_I2C.read(SI1133_I2C_ADDRESS, (char*) data, length)) {
stevew817 0:667132a19341 262 //Return failure
stevew817 0:667132a19341 263 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 264 }
stevew817 0:667132a19341 265
stevew817 0:667132a19341 266 return SI1133_OK;
stevew817 0:667132a19341 267 }
stevew817 0:667132a19341 268
stevew817 0:667132a19341 269 /***************************************************************************//**
stevew817 0:667132a19341 270 * @brief
stevew817 0:667132a19341 271 * Reads the interrupt status register of the device
stevew817 0:667132a19341 272 *
stevew817 0:667132a19341 273 * @param[out] irqStatus
stevew817 0:667132a19341 274 * The contentof the IRQ status register
stevew817 0:667132a19341 275 *
stevew817 0:667132a19341 276 * @return
stevew817 0:667132a19341 277 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 278 ******************************************************************************/
stevew817 0:667132a19341 279 uint32_t Si1133::get_irq_status(uint8_t *irq_status)
stevew817 0:667132a19341 280 {
stevew817 0:667132a19341 281 return read_register(REG_IRQ_STATUS, irq_status);
stevew817 0:667132a19341 282 }
stevew817 0:667132a19341 283
stevew817 0:667132a19341 284 /***************************************************************************//**
stevew817 0:667132a19341 285 * @brief
stevew817 0:667132a19341 286 * Waits until the Si1133 is sleeping before proceeding
stevew817 0:667132a19341 287 *
stevew817 0:667132a19341 288 * @return
stevew817 0:667132a19341 289 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 290 ******************************************************************************/
stevew817 0:667132a19341 291 uint32_t Si1133::wait_until_sleep(void)
stevew817 0:667132a19341 292 {
stevew817 0:667132a19341 293 uint32_t ret;
stevew817 0:667132a19341 294 uint8_t response;
stevew817 0:667132a19341 295 size_t count = 0;
stevew817 0:667132a19341 296
stevew817 0:667132a19341 297 /* This loops until the Si1133 is known to be in its sleep state */
stevew817 0:667132a19341 298 /* or if an i2c error occurs */
stevew817 0:667132a19341 299 while ( count < 5 ) {
stevew817 0:667132a19341 300 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 301 if ( (response & (uint8_t)RSP0_CHIPSTAT_MASK) == (uint8_t)RSP0_SLEEP ) {
stevew817 0:667132a19341 302 return SI1133_OK;
stevew817 0:667132a19341 303 }
stevew817 0:667132a19341 304
stevew817 0:667132a19341 305 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 306 return SI1133_ERROR_SLEEP_FAILED;
stevew817 0:667132a19341 307 }
stevew817 0:667132a19341 308
stevew817 0:667132a19341 309 count++;
stevew817 0:667132a19341 310 }
stevew817 0:667132a19341 311
stevew817 0:667132a19341 312 return SI1133_ERROR_SLEEP_FAILED;
stevew817 0:667132a19341 313 }
stevew817 0:667132a19341 314
stevew817 0:667132a19341 315 /***************************************************************************//**
stevew817 0:667132a19341 316 * @brief
stevew817 0:667132a19341 317 * Resets the Si1133
stevew817 0:667132a19341 318 *
stevew817 0:667132a19341 319 * @return
stevew817 0:667132a19341 320 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 321 ******************************************************************************/
stevew817 0:667132a19341 322 uint32_t Si1133::reset(void)
stevew817 0:667132a19341 323 {
stevew817 0:667132a19341 324 uint32_t retval;
stevew817 0:667132a19341 325
stevew817 0:667132a19341 326 /* Do not access the Si1133 earlier than 25 ms from power-up */
stevew817 0:667132a19341 327 wait_ms(30);
stevew817 0:667132a19341 328
stevew817 0:667132a19341 329 /* Perform the Reset Command */
stevew817 0:667132a19341 330 retval = write_register(REG_COMMAND, (uint8_t)CMD_RESET);
stevew817 0:667132a19341 331
stevew817 0:667132a19341 332 /* Delay for 10 ms. This delay is needed to allow the Si1133 */
stevew817 0:667132a19341 333 /* to perform internal reset sequence. */
stevew817 0:667132a19341 334 wait_ms(10);
stevew817 0:667132a19341 335
stevew817 0:667132a19341 336 return retval;
stevew817 0:667132a19341 337 }
stevew817 0:667132a19341 338
stevew817 0:667132a19341 339 /***************************************************************************//**
stevew817 0:667132a19341 340 * @brief
stevew817 0:667132a19341 341 * Helper function to send a command to the Si1133
stevew817 0:667132a19341 342 *
stevew817 0:667132a19341 343 * @param[in] command
stevew817 0:667132a19341 344 * The command to send to the sensor
stevew817 0:667132a19341 345 *
stevew817 0:667132a19341 346 * @return
stevew817 0:667132a19341 347 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 348 ******************************************************************************/
stevew817 0:667132a19341 349 uint32_t Si1133::send_cmd(enum Si1133::Command command)
stevew817 0:667132a19341 350 {
stevew817 0:667132a19341 351 uint8_t response;
stevew817 0:667132a19341 352 uint8_t response_stored;
stevew817 0:667132a19341 353 uint8_t count = 0;
stevew817 0:667132a19341 354 uint32_t ret;
stevew817 0:667132a19341 355
stevew817 0:667132a19341 356 /* Get the response register contents */
stevew817 0:667132a19341 357 ret = read_register(REG_RESPONSE0, &response_stored);
stevew817 0:667132a19341 358 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 359 return ret;
stevew817 0:667132a19341 360 }
stevew817 0:667132a19341 361
stevew817 0:667132a19341 362 response_stored = response_stored & (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 363
stevew817 0:667132a19341 364 /* Double-check the response register is consistent */
stevew817 0:667132a19341 365 while ( count < 5 ) {
stevew817 0:667132a19341 366 ret = wait_until_sleep();
stevew817 0:667132a19341 367 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 368 return ret;
stevew817 0:667132a19341 369 }
stevew817 0:667132a19341 370 /* Skip if the command is RESET COMMAND COUNTER */
stevew817 0:667132a19341 371 if ( command == (uint8_t)CMD_RESET_CMD_CTR ) {
stevew817 0:667132a19341 372 break;
stevew817 0:667132a19341 373 }
stevew817 0:667132a19341 374
stevew817 0:667132a19341 375 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 376
stevew817 0:667132a19341 377 if ( (response & (uint8_t)RSP0_COUNTER_MASK) == response_stored ) {
stevew817 0:667132a19341 378 break;
stevew817 0:667132a19341 379 } else {
stevew817 0:667132a19341 380 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 381 return ret;
stevew817 0:667132a19341 382 } else {
stevew817 0:667132a19341 383 response_stored = response & (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 384 }
stevew817 0:667132a19341 385 }
stevew817 0:667132a19341 386
stevew817 0:667132a19341 387 count++;
stevew817 0:667132a19341 388 }
stevew817 0:667132a19341 389
stevew817 0:667132a19341 390 /* Send the command */
stevew817 0:667132a19341 391 ret = write_register(REG_COMMAND, command);
stevew817 0:667132a19341 392 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 393 return ret;
stevew817 0:667132a19341 394 }
stevew817 0:667132a19341 395
stevew817 0:667132a19341 396 count = 0;
stevew817 0:667132a19341 397 /* Expect a change in the response register */
stevew817 0:667132a19341 398 while ( count < 5 ) {
stevew817 0:667132a19341 399 /* Skip if the command is RESET COMMAND COUNTER */
stevew817 0:667132a19341 400 if ( command == (uint8_t)CMD_RESET_CMD_CTR ) {
stevew817 0:667132a19341 401 break;
stevew817 0:667132a19341 402 }
stevew817 0:667132a19341 403
stevew817 0:667132a19341 404 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 405 if ( (response & (uint8_t)RSP0_COUNTER_MASK) != response_stored ) {
stevew817 0:667132a19341 406 break;
stevew817 0:667132a19341 407 } else {
stevew817 0:667132a19341 408 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 409 return ret;
stevew817 0:667132a19341 410 }
stevew817 0:667132a19341 411 }
stevew817 0:667132a19341 412
stevew817 0:667132a19341 413 count++;
stevew817 0:667132a19341 414 }
stevew817 0:667132a19341 415
stevew817 0:667132a19341 416 return SI1133_OK;
stevew817 0:667132a19341 417 }
stevew817 0:667132a19341 418
stevew817 0:667132a19341 419 /***************************************************************************//**
stevew817 0:667132a19341 420 * @brief
stevew817 0:667132a19341 421 * Sends a RESET COMMAND COUNTER command to the Si1133
stevew817 0:667132a19341 422 *
stevew817 0:667132a19341 423 * @return
stevew817 0:667132a19341 424 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 425 ******************************************************************************/
stevew817 0:667132a19341 426 uint32_t Si1133::reset_cmd_counter(void)
stevew817 0:667132a19341 427 {
stevew817 0:667132a19341 428 return send_cmd(CMD_RESET_CMD_CTR);
stevew817 0:667132a19341 429 }
stevew817 0:667132a19341 430
stevew817 0:667132a19341 431 /***************************************************************************//**
stevew817 0:667132a19341 432 * @brief
stevew817 0:667132a19341 433 * Sends a FORCE command to the Si1133
stevew817 0:667132a19341 434 *
stevew817 0:667132a19341 435 * @return
stevew817 0:667132a19341 436 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 437 ******************************************************************************/
stevew817 0:667132a19341 438 uint32_t Si1133::force_measurement(void)
stevew817 0:667132a19341 439 {
stevew817 0:667132a19341 440 return send_cmd(CMD_FORCE_CH);
stevew817 0:667132a19341 441 }
stevew817 0:667132a19341 442
stevew817 0:667132a19341 443 /***************************************************************************//**
stevew817 0:667132a19341 444 * @brief
stevew817 0:667132a19341 445 * Sends a START command to the Si1133
stevew817 0:667132a19341 446 *
stevew817 0:667132a19341 447 * @return
stevew817 0:667132a19341 448 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 449 ******************************************************************************/
stevew817 0:667132a19341 450 uint32_t Si1133::start_measurement(void)
stevew817 0:667132a19341 451 {
stevew817 0:667132a19341 452 return send_cmd(CMD_START);
stevew817 0:667132a19341 453 }
stevew817 0:667132a19341 454
stevew817 0:667132a19341 455 /***************************************************************************//**
stevew817 0:667132a19341 456 * @brief
stevew817 0:667132a19341 457 * Sends a PAUSE command to the Si1133
stevew817 0:667132a19341 458 *
stevew817 0:667132a19341 459 * @return
stevew817 0:667132a19341 460 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 461 ******************************************************************************/
stevew817 0:667132a19341 462 uint32_t Si1133::pause_measurement(void)
stevew817 0:667132a19341 463 {
stevew817 0:667132a19341 464 return send_cmd(CMD_PAUSE_CH);
stevew817 0:667132a19341 465 }
stevew817 0:667132a19341 466
stevew817 0:667132a19341 467 /***************************************************************************//**
stevew817 0:667132a19341 468 * @brief
stevew817 0:667132a19341 469 * Writes a byte to an Si1133 Parameter
stevew817 0:667132a19341 470 *
stevew817 0:667132a19341 471 * @param[in] address
stevew817 0:667132a19341 472 * The parameter address
stevew817 0:667132a19341 473 *
stevew817 0:667132a19341 474 * @param[in] value
stevew817 0:667132a19341 475 * The byte value to be written to the Si1133 parameter
stevew817 0:667132a19341 476 *
stevew817 0:667132a19341 477 * @return
stevew817 0:667132a19341 478 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 479 *
stevew817 0:667132a19341 480 * @note
stevew817 0:667132a19341 481 * This function ensures that the Si1133 is idle and ready to
stevew817 0:667132a19341 482 * receive a command before writing the parameter. Furthermore,
stevew817 0:667132a19341 483 * command completion is checked. If setting parameter is not done
stevew817 0:667132a19341 484 * properly, no measurements will occur. This is the most common
stevew817 0:667132a19341 485 * error. It is highly recommended that host code make use of this
stevew817 0:667132a19341 486 * function.
stevew817 0:667132a19341 487 ******************************************************************************/
stevew817 0:667132a19341 488 uint32_t Si1133::set_parameter (enum Si1133::Parameter address, uint8_t value)
stevew817 0:667132a19341 489 {
stevew817 0:667132a19341 490 uint32_t retval;
stevew817 0:667132a19341 491 uint8_t buffer[2];
stevew817 0:667132a19341 492 uint8_t response_stored;
stevew817 0:667132a19341 493 uint8_t response;
stevew817 0:667132a19341 494 size_t count;
stevew817 0:667132a19341 495
stevew817 0:667132a19341 496 retval = wait_until_sleep();
stevew817 0:667132a19341 497 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 498 return retval;
stevew817 0:667132a19341 499 }
stevew817 0:667132a19341 500
stevew817 0:667132a19341 501 read_register(REG_RESPONSE0, &response_stored);
stevew817 0:667132a19341 502 response_stored &= (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 503
stevew817 0:667132a19341 504 buffer[0] = value;
stevew817 0:667132a19341 505 buffer[1] = 0x80 + ((uint8_t)address & 0x3F);
stevew817 0:667132a19341 506
stevew817 0:667132a19341 507 retval = write_register_block(REG_HOSTIN0, 2, (uint8_t*) buffer);
stevew817 0:667132a19341 508 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 509 return retval;
stevew817 0:667132a19341 510 }
stevew817 0:667132a19341 511
stevew817 0:667132a19341 512 /* Wait for command to finish */
stevew817 0:667132a19341 513 count = 0;
stevew817 0:667132a19341 514 /* Expect a change in the response register */
stevew817 0:667132a19341 515 while ( count < 5 ) {
stevew817 0:667132a19341 516 retval = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 517 if ( (response & (uint8_t)RSP0_COUNTER_MASK) != response_stored ) {
stevew817 0:667132a19341 518 break;
stevew817 0:667132a19341 519 } else {
stevew817 0:667132a19341 520 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 521 return retval;
stevew817 0:667132a19341 522 }
stevew817 0:667132a19341 523 }
stevew817 0:667132a19341 524
stevew817 0:667132a19341 525 count++;
stevew817 0:667132a19341 526 }
stevew817 0:667132a19341 527
stevew817 0:667132a19341 528 if (count >= 5) {
stevew817 0:667132a19341 529 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 530 }
stevew817 0:667132a19341 531
stevew817 0:667132a19341 532 return SI1133_OK;
stevew817 0:667132a19341 533 }
stevew817 0:667132a19341 534
stevew817 0:667132a19341 535 /***************************************************************************//**
stevew817 0:667132a19341 536 * @brief
stevew817 0:667132a19341 537 * Reads a parameter from the Si1133
stevew817 0:667132a19341 538 *
stevew817 0:667132a19341 539 * @param[in] address
stevew817 0:667132a19341 540 * The address of the parameter.
stevew817 0:667132a19341 541 *
stevew817 0:667132a19341 542 * @return
stevew817 0:667132a19341 543 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 544 ******************************************************************************/
stevew817 0:667132a19341 545 uint32_t Si1133::read_parameter (enum Si1133::Parameter address)
stevew817 0:667132a19341 546 {
stevew817 0:667132a19341 547 uint8_t retval;
stevew817 0:667132a19341 548 uint8_t cmd;
stevew817 0:667132a19341 549
stevew817 0:667132a19341 550 cmd = 0x40 + ((uint8_t)address & 0x3F);
stevew817 0:667132a19341 551
stevew817 0:667132a19341 552 retval = send_cmd((enum Si1133::Command)cmd);
stevew817 0:667132a19341 553 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 554 return retval;
stevew817 0:667132a19341 555 }
stevew817 0:667132a19341 556
stevew817 0:667132a19341 557 read_register(REG_RESPONSE1, &retval);
stevew817 0:667132a19341 558
stevew817 0:667132a19341 559 return retval;
stevew817 0:667132a19341 560 }
stevew817 0:667132a19341 561
stevew817 0:667132a19341 562 /**************************************************************************//**
stevew817 0:667132a19341 563 * @brief
stevew817 0:667132a19341 564 * Initializes the Si1133 chip
stevew817 0:667132a19341 565 *
stevew817 0:667132a19341 566 * @return
stevew817 0:667132a19341 567 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 568 *****************************************************************************/
stevew817 0:667132a19341 569 uint32_t Si1133::init (void)
stevew817 0:667132a19341 570 {
stevew817 0:667132a19341 571 uint32_t retval;
stevew817 0:667132a19341 572
stevew817 0:667132a19341 573 /* Allow some time for the part to power up */
stevew817 0:667132a19341 574 wait_ms(5);
stevew817 0:667132a19341 575
stevew817 0:667132a19341 576 retval = reset();
stevew817 0:667132a19341 577
stevew817 0:667132a19341 578 wait_ms(10);
stevew817 0:667132a19341 579
stevew817 0:667132a19341 580 retval += set_parameter(PARAM_CH_LIST, 0x0f);
stevew817 0:667132a19341 581 retval += set_parameter(PARAM_ADCCONFIG0, 0x78);
stevew817 0:667132a19341 582 retval += set_parameter(PARAM_ADCSENS0, 0x71);
stevew817 0:667132a19341 583 retval += set_parameter(PARAM_ADCPOST0, 0x40);
stevew817 0:667132a19341 584 retval += set_parameter(PARAM_ADCCONFIG1, 0x4d);
stevew817 0:667132a19341 585 retval += set_parameter(PARAM_ADCSENS1, 0xe1);
stevew817 0:667132a19341 586 retval += set_parameter(PARAM_ADCPOST1, 0x40);
stevew817 0:667132a19341 587 retval += set_parameter(PARAM_ADCCONFIG2, 0x41);
stevew817 0:667132a19341 588 retval += set_parameter(PARAM_ADCSENS2, 0xe1);
stevew817 0:667132a19341 589 retval += set_parameter(PARAM_ADCPOST2, 0x50);
stevew817 0:667132a19341 590 retval += set_parameter(PARAM_ADCCONFIG3, 0x4d);
stevew817 0:667132a19341 591 retval += set_parameter(PARAM_ADCSENS3, 0x87);
stevew817 0:667132a19341 592 retval += set_parameter(PARAM_ADCPOST3, 0x40);
stevew817 0:667132a19341 593
stevew817 0:667132a19341 594 retval += write_register(REG_IRQ_ENABLE, 0x0f);
stevew817 0:667132a19341 595
stevew817 0:667132a19341 596 return retval;
stevew817 0:667132a19341 597 }
stevew817 0:667132a19341 598
stevew817 0:667132a19341 599 /***************************************************************************//**
stevew817 0:667132a19341 600 * @brief
stevew817 0:667132a19341 601 * Stops the measurements on all channel and waits until the chip
stevew817 0:667132a19341 602 * goes to sleep state.
stevew817 0:667132a19341 603 *
stevew817 0:667132a19341 604 * @return
stevew817 0:667132a19341 605 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 606 ******************************************************************************/
stevew817 0:667132a19341 607 uint32_t Si1133::deinit (void)
stevew817 0:667132a19341 608 {
stevew817 0:667132a19341 609 uint32_t retval;
stevew817 0:667132a19341 610
stevew817 0:667132a19341 611 retval = set_parameter(PARAM_CH_LIST, 0x3f);
stevew817 0:667132a19341 612 retval += pause_measurement();
stevew817 0:667132a19341 613 retval += wait_until_sleep();
stevew817 0:667132a19341 614
stevew817 0:667132a19341 615 return retval;
stevew817 0:667132a19341 616 }
stevew817 0:667132a19341 617
stevew817 0:667132a19341 618 /***************************************************************************//**
stevew817 0:667132a19341 619 * @brief
stevew817 0:667132a19341 620 * Read samples from the Si1133 chip
stevew817 0:667132a19341 621 *
stevew817 0:667132a19341 622 * @param[out] samples
stevew817 0:667132a19341 623 * Retrieves interrupt status and measurement data for channel 0..3 and
stevew817 0:667132a19341 624 * converts the data to int32_t format
stevew817 0:667132a19341 625 *
stevew817 0:667132a19341 626 * @return
stevew817 0:667132a19341 627 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 628 ******************************************************************************/
stevew817 2:1e2dd643afa8 629 uint32_t Si1133::measure (Si1133::Samples_t *samples)
stevew817 0:667132a19341 630 {
stevew817 0:667132a19341 631 uint8_t buffer[13];
stevew817 0:667132a19341 632 uint32_t retval;
stevew817 0:667132a19341 633
stevew817 0:667132a19341 634 retval = read_register_block(REG_IRQ_STATUS, 13, buffer);
stevew817 0:667132a19341 635
stevew817 0:667132a19341 636 samples->irq_status = buffer[0];
stevew817 0:667132a19341 637
stevew817 0:667132a19341 638 samples->ch0 = buffer[1] << 16;
stevew817 0:667132a19341 639 samples->ch0 |= buffer[2] << 8;
stevew817 0:667132a19341 640 samples->ch0 |= buffer[3];
stevew817 0:667132a19341 641 if ( samples->ch0 & 0x800000 ) {
stevew817 0:667132a19341 642 samples->ch0 |= 0xFF000000;
stevew817 0:667132a19341 643 }
stevew817 0:667132a19341 644
stevew817 0:667132a19341 645 samples->ch1 = buffer[4] << 16;
stevew817 0:667132a19341 646 samples->ch1 |= buffer[5] << 8;
stevew817 0:667132a19341 647 samples->ch1 |= buffer[6];
stevew817 0:667132a19341 648 if ( samples->ch1 & 0x800000 ) {
stevew817 0:667132a19341 649 samples->ch1 |= 0xFF000000;
stevew817 0:667132a19341 650 }
stevew817 0:667132a19341 651
stevew817 0:667132a19341 652 samples->ch2 = buffer[7] << 16;
stevew817 0:667132a19341 653 samples->ch2 |= buffer[8] << 8;
stevew817 0:667132a19341 654 samples->ch2 |= buffer[9];
stevew817 0:667132a19341 655 if ( samples->ch2 & 0x800000 ) {
stevew817 0:667132a19341 656 samples->ch2 |= 0xFF000000;
stevew817 0:667132a19341 657 }
stevew817 0:667132a19341 658
stevew817 0:667132a19341 659 samples->ch3 = buffer[10] << 16;
stevew817 0:667132a19341 660 samples->ch3 |= buffer[11] << 8;
stevew817 0:667132a19341 661 samples->ch3 |= buffer[12];
stevew817 0:667132a19341 662 if ( samples->ch3 & 0x800000 ) {
stevew817 0:667132a19341 663 samples->ch3 |= 0xFF000000;
stevew817 0:667132a19341 664 }
stevew817 0:667132a19341 665
stevew817 0:667132a19341 666 return retval;
stevew817 0:667132a19341 667 }
stevew817 0:667132a19341 668
stevew817 0:667132a19341 669 int32_t Si1133::calculate_polynomial_helper (int32_t input, int8_t fraction, uint16_t mag, int8_t shift)
stevew817 0:667132a19341 670 {
stevew817 0:667132a19341 671 int32_t value;
stevew817 0:667132a19341 672
stevew817 0:667132a19341 673 if ( shift < 0 ) {
stevew817 0:667132a19341 674 value = ( (input << fraction) / mag) >> -shift;
stevew817 0:667132a19341 675 } else {
stevew817 0:667132a19341 676 value = ( (input << fraction) / mag) << shift;
stevew817 0:667132a19341 677 }
stevew817 0:667132a19341 678
stevew817 0:667132a19341 679 return value;
stevew817 0:667132a19341 680 }
stevew817 0:667132a19341 681
stevew817 0:667132a19341 682 int32_t Si1133::calculate_polynomial (int32_t x, int32_t y, uint8_t input_fraction, uint8_t output_fraction, uint8_t num_coeff, const Si1133::Coeff_t *kp)
stevew817 0:667132a19341 683 {
stevew817 0:667132a19341 684 uint8_t info, x_order, y_order, counter;
stevew817 0:667132a19341 685 int8_t sign, shift;
stevew817 0:667132a19341 686 uint16_t mag;
stevew817 0:667132a19341 687 int32_t output = 0, x1, x2, y1, y2;
stevew817 0:667132a19341 688
stevew817 0:667132a19341 689 for ( counter = 0; counter < num_coeff; counter++ ) {
stevew817 0:667132a19341 690 info = kp->info;
stevew817 0:667132a19341 691 x_order = GET_X_ORDER(info);
stevew817 0:667132a19341 692 y_order = GET_Y_ORDER(info);
stevew817 0:667132a19341 693
stevew817 0:667132a19341 694 shift = ( (uint16_t) kp->info & 0xff00) >> 8;
stevew817 0:667132a19341 695 shift ^= 0x00ff;
stevew817 0:667132a19341 696 shift += 1;
stevew817 0:667132a19341 697 shift = -shift;
stevew817 0:667132a19341 698
stevew817 0:667132a19341 699 mag = kp->mag;
stevew817 0:667132a19341 700
stevew817 0:667132a19341 701 if ( GET_SIGN(info) ) {
stevew817 0:667132a19341 702 sign = -1;
stevew817 0:667132a19341 703 } else {
stevew817 0:667132a19341 704 sign = 1;
stevew817 0:667132a19341 705 }
stevew817 0:667132a19341 706
stevew817 0:667132a19341 707 if ( (x_order == 0) && (y_order == 0) ) {
stevew817 0:667132a19341 708 output += sign * mag << output_fraction;
stevew817 0:667132a19341 709 } else {
stevew817 0:667132a19341 710 if ( x_order > 0 ) {
stevew817 0:667132a19341 711 x1 = calculate_polynomial_helper(x, input_fraction, mag, shift);
stevew817 0:667132a19341 712 if ( x_order > 1 ) {
stevew817 0:667132a19341 713 x2 = calculate_polynomial_helper(x, input_fraction, mag, shift);
stevew817 0:667132a19341 714 } else {
stevew817 0:667132a19341 715 x2 = 1;
stevew817 0:667132a19341 716 }
stevew817 0:667132a19341 717 } else {
stevew817 0:667132a19341 718 x1 = 1;
stevew817 0:667132a19341 719 x2 = 1;
stevew817 0:667132a19341 720 }
stevew817 0:667132a19341 721
stevew817 0:667132a19341 722 if ( y_order > 0 ) {
stevew817 0:667132a19341 723 y1 = calculate_polynomial_helper(y, input_fraction, mag, shift);
stevew817 0:667132a19341 724 if ( y_order > 1 ) {
stevew817 0:667132a19341 725 y2 = calculate_polynomial_helper(y, input_fraction, mag, shift);
stevew817 0:667132a19341 726 } else {
stevew817 0:667132a19341 727 y2 = 1;
stevew817 0:667132a19341 728 }
stevew817 0:667132a19341 729 } else {
stevew817 0:667132a19341 730 y1 = 1;
stevew817 0:667132a19341 731 y2 = 1;
stevew817 0:667132a19341 732 }
stevew817 0:667132a19341 733
stevew817 0:667132a19341 734 output += sign * x1 * x2 * y1 * y2;
stevew817 0:667132a19341 735 }
stevew817 0:667132a19341 736
stevew817 0:667132a19341 737 kp++;
stevew817 0:667132a19341 738 }
stevew817 0:667132a19341 739
stevew817 0:667132a19341 740 if ( output < 0 ) {
stevew817 0:667132a19341 741 output = -output;
stevew817 0:667132a19341 742 }
stevew817 0:667132a19341 743
stevew817 0:667132a19341 744 return output;
stevew817 0:667132a19341 745 }
stevew817 0:667132a19341 746
stevew817 0:667132a19341 747 /***************************************************************************//**
stevew817 0:667132a19341 748 * @brief
stevew817 0:667132a19341 749 * Compute UV index
stevew817 0:667132a19341 750 *
stevew817 0:667132a19341 751 * @param[in] uv
stevew817 0:667132a19341 752 * UV sensor raw data
stevew817 0:667132a19341 753 *
stevew817 0:667132a19341 754 * @param[in] uk
stevew817 0:667132a19341 755 * UV calculation coefficients
stevew817 0:667132a19341 756 *
stevew817 0:667132a19341 757 * @return
stevew817 0:667132a19341 758 * UV index scaled by UV_OUPTUT_FRACTION
stevew817 0:667132a19341 759 ******************************************************************************/
stevew817 2:1e2dd643afa8 760 int32_t Si1133::get_uv (int32_t uv)
stevew817 0:667132a19341 761 {
stevew817 0:667132a19341 762 int32_t uvi;
stevew817 0:667132a19341 763
stevew817 0:667132a19341 764 uvi = calculate_polynomial(0, uv, UV_INPUT_FRACTION, UV_OUTPUT_FRACTION, UV_NUMCOEFF, uk);
stevew817 0:667132a19341 765
stevew817 0:667132a19341 766 return uvi;
stevew817 0:667132a19341 767 }
stevew817 0:667132a19341 768
stevew817 0:667132a19341 769 /***************************************************************************//**
stevew817 0:667132a19341 770 * @brief
stevew817 0:667132a19341 771 * Compute lux value
stevew817 0:667132a19341 772 *
stevew817 0:667132a19341 773 * @param[in] vis_high
stevew817 0:667132a19341 774 * Visible light sensor raw data
stevew817 0:667132a19341 775 *
stevew817 0:667132a19341 776 * @param[in] vis_low
stevew817 0:667132a19341 777 * Visible light sensor raw data
stevew817 0:667132a19341 778 *
stevew817 0:667132a19341 779 * @param[in] ir
stevew817 0:667132a19341 780 * Infrared sensor raw data
stevew817 0:667132a19341 781 *
stevew817 0:667132a19341 782 * @param[in] lk
stevew817 0:667132a19341 783 * Lux calculation coefficients
stevew817 0:667132a19341 784 *
stevew817 0:667132a19341 785 * @return
stevew817 0:667132a19341 786 * Lux value scaled by LUX_OUPTUT_FRACTION
stevew817 0:667132a19341 787 ******************************************************************************/
stevew817 2:1e2dd643afa8 788 int32_t Si1133::get_lux (int32_t vis_high, int32_t vis_low, int32_t ir)
stevew817 0:667132a19341 789 {
stevew817 0:667132a19341 790 int32_t lux;
stevew817 0:667132a19341 791
stevew817 0:667132a19341 792 if ( (vis_high > ADC_THRESHOLD) || (ir > ADC_THRESHOLD) ) {
stevew817 0:667132a19341 793 lux = calculate_polynomial(vis_high,
stevew817 0:667132a19341 794 ir,
stevew817 0:667132a19341 795 INPUT_FRACTION_HIGH,
stevew817 0:667132a19341 796 LUX_OUTPUT_FRACTION,
stevew817 0:667132a19341 797 NUMCOEFF_HIGH,
stevew817 0:667132a19341 798 &(lk.coeff_high[0]) );
stevew817 0:667132a19341 799 } else {
stevew817 0:667132a19341 800 lux = calculate_polynomial(vis_low,
stevew817 0:667132a19341 801 ir,
stevew817 0:667132a19341 802 INPUT_FRACTION_LOW,
stevew817 0:667132a19341 803 LUX_OUTPUT_FRACTION,
stevew817 0:667132a19341 804 NUMCOEFF_LOW,
stevew817 0:667132a19341 805 &(lk.coeff_low[0]) );
stevew817 0:667132a19341 806 }
stevew817 0:667132a19341 807
stevew817 0:667132a19341 808 return lux;
stevew817 0:667132a19341 809 }
stevew817 0:667132a19341 810
stevew817 0:667132a19341 811 /***************************************************************************//**
stevew817 0:667132a19341 812 * @brief
stevew817 0:667132a19341 813 * Measure lux and UV index using the Si1133 sensor
stevew817 0:667132a19341 814 *
stevew817 0:667132a19341 815 * @param[out] lux
stevew817 0:667132a19341 816 * The measured ambient light illuminace in lux
stevew817 0:667132a19341 817 *
stevew817 0:667132a19341 818 * @param[out] uvi
stevew817 0:667132a19341 819 * UV index
stevew817 0:667132a19341 820 *
stevew817 0:667132a19341 821 * @return
stevew817 0:667132a19341 822 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 823 ******************************************************************************/
stevew817 2:1e2dd643afa8 824 uint32_t Si1133::measure_lux_uv (float *lux, float *uvi)
stevew817 0:667132a19341 825 {
stevew817 0:667132a19341 826 Si1133::Samples_t samples;
stevew817 0:667132a19341 827 uint32_t retval;
stevew817 0:667132a19341 828 uint8_t response;
stevew817 0:667132a19341 829
stevew817 0:667132a19341 830 /* Force measurement */
stevew817 0:667132a19341 831 retval = force_measurement();
stevew817 0:667132a19341 832
stevew817 0:667132a19341 833 /* Go to sleep while the sensor does the conversion */
stevew817 0:667132a19341 834 wait_ms(200);
stevew817 0:667132a19341 835
stevew817 0:667132a19341 836 /* Check if the measurement finished, if not then wait */
stevew817 0:667132a19341 837 retval += read_register(REG_IRQ_STATUS, &response);
stevew817 0:667132a19341 838 while ( response != 0x0F ) {
stevew817 0:667132a19341 839 wait_ms(5);
stevew817 0:667132a19341 840 retval += read_register(REG_IRQ_STATUS, &response);
stevew817 0:667132a19341 841 }
stevew817 0:667132a19341 842
stevew817 0:667132a19341 843 /* Get the results */
stevew817 2:1e2dd643afa8 844 measure(&samples);
stevew817 0:667132a19341 845
stevew817 0:667132a19341 846 /* Convert the readings to lux */
stevew817 2:1e2dd643afa8 847 *lux = (float) get_lux(samples.ch1, samples.ch3, samples.ch2);
stevew817 0:667132a19341 848 *lux = *lux / (1 << LUX_OUTPUT_FRACTION);
stevew817 0:667132a19341 849
stevew817 0:667132a19341 850 /* Convert the readings to UV index */
stevew817 2:1e2dd643afa8 851 *uvi = (float) get_uv(samples.ch0);
stevew817 0:667132a19341 852 *uvi = *uvi / (1 << UV_OUTPUT_FRACTION);
stevew817 0:667132a19341 853
stevew817 0:667132a19341 854 return retval;
stevew817 0:667132a19341 855 }
stevew817 0:667132a19341 856
stevew817 0:667132a19341 857 /***************************************************************************//**
stevew817 0:667132a19341 858 * @brief
stevew817 0:667132a19341 859 * Reads Hardware ID from the SI1133 sensor
stevew817 0:667132a19341 860 *
stevew817 0:667132a19341 861 * @param[out] hardwareID
stevew817 0:667132a19341 862 * The Hardware ID of the chip (should be 0x33)
stevew817 0:667132a19341 863 *
stevew817 0:667132a19341 864 * @return
stevew817 0:667132a19341 865 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 866 ******************************************************************************/
stevew817 2:1e2dd643afa8 867 uint32_t Si1133::get_hardware_id (uint8_t *hardware_id)
stevew817 0:667132a19341 868 {
stevew817 0:667132a19341 869 uint32_t retval;
stevew817 0:667132a19341 870
stevew817 2:1e2dd643afa8 871 retval = read_register(REG_PART_ID, hardware_id);
stevew817 0:667132a19341 872
stevew817 0:667132a19341 873 return retval;
stevew817 0:667132a19341 874 }
stevew817 0:667132a19341 875
stevew817 0:667132a19341 876 /***************************************************************************//**
stevew817 0:667132a19341 877 * @brief
stevew817 0:667132a19341 878 * Retrieve the sample values from the chip and convert them
stevew817 0:667132a19341 879 * to lux and UV index values
stevew817 0:667132a19341 880 *
stevew817 0:667132a19341 881 * @param[out] lux
stevew817 0:667132a19341 882 * The measured ambient light illuminace in lux
stevew817 0:667132a19341 883 *
stevew817 0:667132a19341 884 * @param[out] uvi
stevew817 0:667132a19341 885 * UV index
stevew817 0:667132a19341 886 *
stevew817 0:667132a19341 887 * @return
stevew817 0:667132a19341 888 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 889 ******************************************************************************/
stevew817 2:1e2dd643afa8 890 uint32_t Si1133::get_measurement (float *lux, float *uvi)
stevew817 0:667132a19341 891 {
stevew817 0:667132a19341 892 Si1133::Samples_t samples;
stevew817 0:667132a19341 893 uint32_t retval;
stevew817 0:667132a19341 894
stevew817 0:667132a19341 895 /* Get the results */
stevew817 2:1e2dd643afa8 896 retval = measure(&samples);
stevew817 0:667132a19341 897
stevew817 0:667132a19341 898 /* Convert the readings to lux */
stevew817 2:1e2dd643afa8 899 *lux = (float) get_lux(samples.ch1, samples.ch3, samples.ch2);
stevew817 0:667132a19341 900 *lux = *lux / (1 << LUX_OUTPUT_FRACTION);
stevew817 0:667132a19341 901
stevew817 0:667132a19341 902 /* Convert the readings to UV index */
stevew817 2:1e2dd643afa8 903 *uvi = (float) get_uv(samples.ch0);
stevew817 0:667132a19341 904 *uvi = *uvi / (1 << UV_OUTPUT_FRACTION);
stevew817 0:667132a19341 905
stevew817 0:667132a19341 906 return retval;
stevew817 0:667132a19341 907 }