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 15:58:26 2017 +0100
Revision:
0:667132a19341
Child:
1:410f61a3900b
Initial commit

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 0:667132a19341 124 measureLuxUvi(&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 0:667132a19341 135 measureLuxUvi(&lux, &uvi);
stevew817 0:667132a19341 136 return uvi;
stevew817 0:667132a19341 137 }
stevew817 0:667132a19341 138
stevew817 0:667132a19341 139 /***************************************************************************//**
stevew817 0:667132a19341 140 * @brief
stevew817 0:667132a19341 141 * Reads register from the Si1133 sensor
stevew817 0:667132a19341 142 *
stevew817 0:667132a19341 143 * @param[in] reg
stevew817 0:667132a19341 144 * The register address to read from in the sensor.
stevew817 0:667132a19341 145 *
stevew817 0:667132a19341 146 * @param[out] data
stevew817 0:667132a19341 147 * The data read from the sensor
stevew817 0:667132a19341 148 *
stevew817 0:667132a19341 149 * @return
stevew817 0:667132a19341 150 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 151 ******************************************************************************/
stevew817 0:667132a19341 152 uint32_t Si1133::read_register(enum Si1133::Register reg, uint8_t *data)
stevew817 0:667132a19341 153 {
stevew817 0:667132a19341 154 char buf[1];
stevew817 0:667132a19341 155 buf[0] = (char) reg;
stevew817 0:667132a19341 156
stevew817 0:667132a19341 157 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, 1, true)) {
stevew817 0:667132a19341 158 //Return failure
stevew817 0:667132a19341 159 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 160 }
stevew817 0:667132a19341 161
stevew817 0:667132a19341 162 if (m_I2C.read(SI1133_I2C_ADDRESS, buf, 1)) {
stevew817 0:667132a19341 163 //Return failure
stevew817 0:667132a19341 164 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 165 }
stevew817 0:667132a19341 166
stevew817 0:667132a19341 167 *data = buf[0];
stevew817 0:667132a19341 168
stevew817 0:667132a19341 169 return SI1133_OK;
stevew817 0:667132a19341 170 }
stevew817 0:667132a19341 171
stevew817 0:667132a19341 172 /***************************************************************************//**
stevew817 0:667132a19341 173 * @brief
stevew817 0:667132a19341 174 * Writes register in the Si1133 sensor
stevew817 0:667132a19341 175 *
stevew817 0:667132a19341 176 * @param[in] reg
stevew817 0:667132a19341 177 * The register address to write to in the sensor
stevew817 0:667132a19341 178 *
stevew817 0:667132a19341 179 * @param[in] data
stevew817 0:667132a19341 180 * The data to write to the sensor
stevew817 0:667132a19341 181 *
stevew817 0:667132a19341 182 * @return
stevew817 0:667132a19341 183 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 184 ******************************************************************************/
stevew817 0:667132a19341 185 uint32_t Si1133::write_register(enum Si1133::Register reg, uint8_t data)
stevew817 0:667132a19341 186 {
stevew817 0:667132a19341 187 char buf[2];
stevew817 0:667132a19341 188 buf[0] = (char) reg;
stevew817 0:667132a19341 189 buf[1] = (char) data;
stevew817 0:667132a19341 190
stevew817 0:667132a19341 191 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, 2)) {
stevew817 0:667132a19341 192 //Return failure
stevew817 0:667132a19341 193 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 194 }
stevew817 0:667132a19341 195
stevew817 0:667132a19341 196 return SI1133_OK;
stevew817 0:667132a19341 197 }
stevew817 0:667132a19341 198
stevew817 0:667132a19341 199 /***************************************************************************//**
stevew817 0:667132a19341 200 * @brief
stevew817 0:667132a19341 201 * Writes a block of data to the Si1133 sensor.
stevew817 0:667132a19341 202 *
stevew817 0:667132a19341 203 * @param[in] reg
stevew817 0:667132a19341 204 * The first register to begin writing to
stevew817 0:667132a19341 205 *
stevew817 0:667132a19341 206 * @param[in] length
stevew817 0:667132a19341 207 * The number of bytes to write to the sensor
stevew817 0:667132a19341 208 *
stevew817 0:667132a19341 209 * @param[in] data
stevew817 0:667132a19341 210 * The data to write to the sensor
stevew817 0:667132a19341 211 *
stevew817 0:667132a19341 212 * @return
stevew817 0:667132a19341 213 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 214 ******************************************************************************/
stevew817 0:667132a19341 215 uint32_t Si1133::write_register_block(enum Si1133::Register reg, uint8_t length, uint8_t *data)
stevew817 0:667132a19341 216 {
stevew817 0:667132a19341 217 char buf[length+1];
stevew817 0:667132a19341 218 buf[0] = (char)reg;
stevew817 0:667132a19341 219 memcpy(&buf[1], data, length);
stevew817 0:667132a19341 220
stevew817 0:667132a19341 221 if (m_I2C.write(SI1133_I2C_ADDRESS, buf, length + 1)) {
stevew817 0:667132a19341 222 //Return failure
stevew817 0:667132a19341 223 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 224 }
stevew817 0:667132a19341 225
stevew817 0:667132a19341 226 return SI1133_OK;
stevew817 0:667132a19341 227 }
stevew817 0:667132a19341 228
stevew817 0:667132a19341 229 /***************************************************************************//**
stevew817 0:667132a19341 230 * @brief
stevew817 0:667132a19341 231 * Reads a block of data from the Si1133 sensor.
stevew817 0:667132a19341 232 *
stevew817 0:667132a19341 233 * @param[in] reg
stevew817 0:667132a19341 234 * The first register to begin reading from
stevew817 0:667132a19341 235 *
stevew817 0:667132a19341 236 * @param[in] length
stevew817 0:667132a19341 237 * The number of bytes to write to the sensor
stevew817 0:667132a19341 238 *
stevew817 0:667132a19341 239 * @param[out] data
stevew817 0:667132a19341 240 * The data read from the sensor
stevew817 0:667132a19341 241 *
stevew817 0:667132a19341 242 * @return
stevew817 0:667132a19341 243 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 244 ******************************************************************************/
stevew817 0:667132a19341 245 uint32_t Si1133::read_register_block(enum Si1133::Register reg, uint8_t length, uint8_t *data)
stevew817 0:667132a19341 246 {
stevew817 0:667132a19341 247 char reg_c = (char)reg;
stevew817 0:667132a19341 248 if (m_I2C.write(SI1133_I2C_ADDRESS, &reg_c, 1, true)) {
stevew817 0:667132a19341 249 //Return failure
stevew817 0:667132a19341 250 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 251 }
stevew817 0:667132a19341 252
stevew817 0:667132a19341 253 if (m_I2C.read(SI1133_I2C_ADDRESS, (char*) data, length)) {
stevew817 0:667132a19341 254 //Return failure
stevew817 0:667132a19341 255 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 256 }
stevew817 0:667132a19341 257
stevew817 0:667132a19341 258 return SI1133_OK;
stevew817 0:667132a19341 259 }
stevew817 0:667132a19341 260
stevew817 0:667132a19341 261 /***************************************************************************//**
stevew817 0:667132a19341 262 * @brief
stevew817 0:667132a19341 263 * Reads the interrupt status register of the device
stevew817 0:667132a19341 264 *
stevew817 0:667132a19341 265 * @param[out] irqStatus
stevew817 0:667132a19341 266 * The contentof the IRQ status register
stevew817 0:667132a19341 267 *
stevew817 0:667132a19341 268 * @return
stevew817 0:667132a19341 269 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 270 ******************************************************************************/
stevew817 0:667132a19341 271 uint32_t Si1133::get_irq_status(uint8_t *irq_status)
stevew817 0:667132a19341 272 {
stevew817 0:667132a19341 273 return read_register(REG_IRQ_STATUS, irq_status);
stevew817 0:667132a19341 274 }
stevew817 0:667132a19341 275
stevew817 0:667132a19341 276 /***************************************************************************//**
stevew817 0:667132a19341 277 * @brief
stevew817 0:667132a19341 278 * Waits until the Si1133 is sleeping before proceeding
stevew817 0:667132a19341 279 *
stevew817 0:667132a19341 280 * @return
stevew817 0:667132a19341 281 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 282 ******************************************************************************/
stevew817 0:667132a19341 283 uint32_t Si1133::wait_until_sleep(void)
stevew817 0:667132a19341 284 {
stevew817 0:667132a19341 285 uint32_t ret;
stevew817 0:667132a19341 286 uint8_t response;
stevew817 0:667132a19341 287 size_t count = 0;
stevew817 0:667132a19341 288
stevew817 0:667132a19341 289 /* This loops until the Si1133 is known to be in its sleep state */
stevew817 0:667132a19341 290 /* or if an i2c error occurs */
stevew817 0:667132a19341 291 while ( count < 5 ) {
stevew817 0:667132a19341 292 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 293 if ( (response & (uint8_t)RSP0_CHIPSTAT_MASK) == (uint8_t)RSP0_SLEEP ) {
stevew817 0:667132a19341 294 return SI1133_OK;
stevew817 0:667132a19341 295 }
stevew817 0:667132a19341 296
stevew817 0:667132a19341 297 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 298 return SI1133_ERROR_SLEEP_FAILED;
stevew817 0:667132a19341 299 }
stevew817 0:667132a19341 300
stevew817 0:667132a19341 301 count++;
stevew817 0:667132a19341 302 }
stevew817 0:667132a19341 303
stevew817 0:667132a19341 304 return SI1133_ERROR_SLEEP_FAILED;
stevew817 0:667132a19341 305 }
stevew817 0:667132a19341 306
stevew817 0:667132a19341 307 /***************************************************************************//**
stevew817 0:667132a19341 308 * @brief
stevew817 0:667132a19341 309 * Resets the Si1133
stevew817 0:667132a19341 310 *
stevew817 0:667132a19341 311 * @return
stevew817 0:667132a19341 312 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 313 ******************************************************************************/
stevew817 0:667132a19341 314 uint32_t Si1133::reset(void)
stevew817 0:667132a19341 315 {
stevew817 0:667132a19341 316 uint32_t retval;
stevew817 0:667132a19341 317
stevew817 0:667132a19341 318 /* Do not access the Si1133 earlier than 25 ms from power-up */
stevew817 0:667132a19341 319 wait_ms(30);
stevew817 0:667132a19341 320
stevew817 0:667132a19341 321 /* Perform the Reset Command */
stevew817 0:667132a19341 322 retval = write_register(REG_COMMAND, (uint8_t)CMD_RESET);
stevew817 0:667132a19341 323
stevew817 0:667132a19341 324 /* Delay for 10 ms. This delay is needed to allow the Si1133 */
stevew817 0:667132a19341 325 /* to perform internal reset sequence. */
stevew817 0:667132a19341 326 wait_ms(10);
stevew817 0:667132a19341 327
stevew817 0:667132a19341 328 return retval;
stevew817 0:667132a19341 329 }
stevew817 0:667132a19341 330
stevew817 0:667132a19341 331 /***************************************************************************//**
stevew817 0:667132a19341 332 * @brief
stevew817 0:667132a19341 333 * Helper function to send a command to the Si1133
stevew817 0:667132a19341 334 *
stevew817 0:667132a19341 335 * @param[in] command
stevew817 0:667132a19341 336 * The command to send to the sensor
stevew817 0:667132a19341 337 *
stevew817 0:667132a19341 338 * @return
stevew817 0:667132a19341 339 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 340 ******************************************************************************/
stevew817 0:667132a19341 341 uint32_t Si1133::send_cmd(enum Si1133::Command command)
stevew817 0:667132a19341 342 {
stevew817 0:667132a19341 343 uint8_t response;
stevew817 0:667132a19341 344 uint8_t response_stored;
stevew817 0:667132a19341 345 uint8_t count = 0;
stevew817 0:667132a19341 346 uint32_t ret;
stevew817 0:667132a19341 347
stevew817 0:667132a19341 348 /* Get the response register contents */
stevew817 0:667132a19341 349 ret = read_register(REG_RESPONSE0, &response_stored);
stevew817 0:667132a19341 350 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 351 return ret;
stevew817 0:667132a19341 352 }
stevew817 0:667132a19341 353
stevew817 0:667132a19341 354 response_stored = response_stored & (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 355
stevew817 0:667132a19341 356 /* Double-check the response register is consistent */
stevew817 0:667132a19341 357 while ( count < 5 ) {
stevew817 0:667132a19341 358 ret = wait_until_sleep();
stevew817 0:667132a19341 359 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 360 return ret;
stevew817 0:667132a19341 361 }
stevew817 0:667132a19341 362 /* Skip if the command is RESET COMMAND COUNTER */
stevew817 0:667132a19341 363 if ( command == (uint8_t)CMD_RESET_CMD_CTR ) {
stevew817 0:667132a19341 364 break;
stevew817 0:667132a19341 365 }
stevew817 0:667132a19341 366
stevew817 0:667132a19341 367 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 368
stevew817 0:667132a19341 369 if ( (response & (uint8_t)RSP0_COUNTER_MASK) == response_stored ) {
stevew817 0:667132a19341 370 break;
stevew817 0:667132a19341 371 } else {
stevew817 0:667132a19341 372 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 373 return ret;
stevew817 0:667132a19341 374 } else {
stevew817 0:667132a19341 375 response_stored = response & (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 376 }
stevew817 0:667132a19341 377 }
stevew817 0:667132a19341 378
stevew817 0:667132a19341 379 count++;
stevew817 0:667132a19341 380 }
stevew817 0:667132a19341 381
stevew817 0:667132a19341 382 /* Send the command */
stevew817 0:667132a19341 383 ret = write_register(REG_COMMAND, command);
stevew817 0:667132a19341 384 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 385 return ret;
stevew817 0:667132a19341 386 }
stevew817 0:667132a19341 387
stevew817 0:667132a19341 388 count = 0;
stevew817 0:667132a19341 389 /* Expect a change in the response register */
stevew817 0:667132a19341 390 while ( count < 5 ) {
stevew817 0:667132a19341 391 /* Skip if the command is RESET COMMAND COUNTER */
stevew817 0:667132a19341 392 if ( command == (uint8_t)CMD_RESET_CMD_CTR ) {
stevew817 0:667132a19341 393 break;
stevew817 0:667132a19341 394 }
stevew817 0:667132a19341 395
stevew817 0:667132a19341 396 ret = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 397 if ( (response & (uint8_t)RSP0_COUNTER_MASK) != response_stored ) {
stevew817 0:667132a19341 398 break;
stevew817 0:667132a19341 399 } else {
stevew817 0:667132a19341 400 if ( ret != SI1133_OK ) {
stevew817 0:667132a19341 401 return ret;
stevew817 0:667132a19341 402 }
stevew817 0:667132a19341 403 }
stevew817 0:667132a19341 404
stevew817 0:667132a19341 405 count++;
stevew817 0:667132a19341 406 }
stevew817 0:667132a19341 407
stevew817 0:667132a19341 408 return SI1133_OK;
stevew817 0:667132a19341 409 }
stevew817 0:667132a19341 410
stevew817 0:667132a19341 411 /***************************************************************************//**
stevew817 0:667132a19341 412 * @brief
stevew817 0:667132a19341 413 * Sends a RESET COMMAND COUNTER command to the Si1133
stevew817 0:667132a19341 414 *
stevew817 0:667132a19341 415 * @return
stevew817 0:667132a19341 416 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 417 ******************************************************************************/
stevew817 0:667132a19341 418 uint32_t Si1133::reset_cmd_counter(void)
stevew817 0:667132a19341 419 {
stevew817 0:667132a19341 420 return send_cmd(CMD_RESET_CMD_CTR);
stevew817 0:667132a19341 421 }
stevew817 0:667132a19341 422
stevew817 0:667132a19341 423 /***************************************************************************//**
stevew817 0:667132a19341 424 * @brief
stevew817 0:667132a19341 425 * Sends a FORCE command to the Si1133
stevew817 0:667132a19341 426 *
stevew817 0:667132a19341 427 * @return
stevew817 0:667132a19341 428 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 429 ******************************************************************************/
stevew817 0:667132a19341 430 uint32_t Si1133::force_measurement(void)
stevew817 0:667132a19341 431 {
stevew817 0:667132a19341 432 return send_cmd(CMD_FORCE_CH);
stevew817 0:667132a19341 433 }
stevew817 0:667132a19341 434
stevew817 0:667132a19341 435 /***************************************************************************//**
stevew817 0:667132a19341 436 * @brief
stevew817 0:667132a19341 437 * Sends a START command to the Si1133
stevew817 0:667132a19341 438 *
stevew817 0:667132a19341 439 * @return
stevew817 0:667132a19341 440 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 441 ******************************************************************************/
stevew817 0:667132a19341 442 uint32_t Si1133::start_measurement(void)
stevew817 0:667132a19341 443 {
stevew817 0:667132a19341 444 return send_cmd(CMD_START);
stevew817 0:667132a19341 445 }
stevew817 0:667132a19341 446
stevew817 0:667132a19341 447 /***************************************************************************//**
stevew817 0:667132a19341 448 * @brief
stevew817 0:667132a19341 449 * Sends a PAUSE command to the Si1133
stevew817 0:667132a19341 450 *
stevew817 0:667132a19341 451 * @return
stevew817 0:667132a19341 452 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 453 ******************************************************************************/
stevew817 0:667132a19341 454 uint32_t Si1133::pause_measurement(void)
stevew817 0:667132a19341 455 {
stevew817 0:667132a19341 456 return send_cmd(CMD_PAUSE_CH);
stevew817 0:667132a19341 457 }
stevew817 0:667132a19341 458
stevew817 0:667132a19341 459 /***************************************************************************//**
stevew817 0:667132a19341 460 * @brief
stevew817 0:667132a19341 461 * Writes a byte to an Si1133 Parameter
stevew817 0:667132a19341 462 *
stevew817 0:667132a19341 463 * @param[in] address
stevew817 0:667132a19341 464 * The parameter address
stevew817 0:667132a19341 465 *
stevew817 0:667132a19341 466 * @param[in] value
stevew817 0:667132a19341 467 * The byte value to be written to the Si1133 parameter
stevew817 0:667132a19341 468 *
stevew817 0:667132a19341 469 * @return
stevew817 0:667132a19341 470 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 471 *
stevew817 0:667132a19341 472 * @note
stevew817 0:667132a19341 473 * This function ensures that the Si1133 is idle and ready to
stevew817 0:667132a19341 474 * receive a command before writing the parameter. Furthermore,
stevew817 0:667132a19341 475 * command completion is checked. If setting parameter is not done
stevew817 0:667132a19341 476 * properly, no measurements will occur. This is the most common
stevew817 0:667132a19341 477 * error. It is highly recommended that host code make use of this
stevew817 0:667132a19341 478 * function.
stevew817 0:667132a19341 479 ******************************************************************************/
stevew817 0:667132a19341 480 uint32_t Si1133::set_parameter (enum Si1133::Parameter address, uint8_t value)
stevew817 0:667132a19341 481 {
stevew817 0:667132a19341 482 uint32_t retval;
stevew817 0:667132a19341 483 uint8_t buffer[2];
stevew817 0:667132a19341 484 uint8_t response_stored;
stevew817 0:667132a19341 485 uint8_t response;
stevew817 0:667132a19341 486 size_t count;
stevew817 0:667132a19341 487
stevew817 0:667132a19341 488 retval = wait_until_sleep();
stevew817 0:667132a19341 489 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 490 return retval;
stevew817 0:667132a19341 491 }
stevew817 0:667132a19341 492
stevew817 0:667132a19341 493 read_register(REG_RESPONSE0, &response_stored);
stevew817 0:667132a19341 494 response_stored &= (uint8_t)RSP0_COUNTER_MASK;
stevew817 0:667132a19341 495
stevew817 0:667132a19341 496 buffer[0] = value;
stevew817 0:667132a19341 497 buffer[1] = 0x80 + ((uint8_t)address & 0x3F);
stevew817 0:667132a19341 498
stevew817 0:667132a19341 499 retval = write_register_block(REG_HOSTIN0, 2, (uint8_t*) buffer);
stevew817 0:667132a19341 500 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 501 return retval;
stevew817 0:667132a19341 502 }
stevew817 0:667132a19341 503
stevew817 0:667132a19341 504 /* Wait for command to finish */
stevew817 0:667132a19341 505 count = 0;
stevew817 0:667132a19341 506 /* Expect a change in the response register */
stevew817 0:667132a19341 507 while ( count < 5 ) {
stevew817 0:667132a19341 508 retval = read_register(REG_RESPONSE0, &response);
stevew817 0:667132a19341 509 if ( (response & (uint8_t)RSP0_COUNTER_MASK) != response_stored ) {
stevew817 0:667132a19341 510 break;
stevew817 0:667132a19341 511 } else {
stevew817 0:667132a19341 512 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 513 return retval;
stevew817 0:667132a19341 514 }
stevew817 0:667132a19341 515 }
stevew817 0:667132a19341 516
stevew817 0:667132a19341 517 count++;
stevew817 0:667132a19341 518 }
stevew817 0:667132a19341 519
stevew817 0:667132a19341 520 if (count >= 5) {
stevew817 0:667132a19341 521 return SI1133_ERROR_I2C_TRANSACTION_FAILED;
stevew817 0:667132a19341 522 }
stevew817 0:667132a19341 523
stevew817 0:667132a19341 524 return SI1133_OK;
stevew817 0:667132a19341 525 }
stevew817 0:667132a19341 526
stevew817 0:667132a19341 527 /***************************************************************************//**
stevew817 0:667132a19341 528 * @brief
stevew817 0:667132a19341 529 * Reads a parameter from the Si1133
stevew817 0:667132a19341 530 *
stevew817 0:667132a19341 531 * @param[in] address
stevew817 0:667132a19341 532 * The address of the parameter.
stevew817 0:667132a19341 533 *
stevew817 0:667132a19341 534 * @return
stevew817 0:667132a19341 535 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 536 ******************************************************************************/
stevew817 0:667132a19341 537 uint32_t Si1133::read_parameter (enum Si1133::Parameter address)
stevew817 0:667132a19341 538 {
stevew817 0:667132a19341 539 uint8_t retval;
stevew817 0:667132a19341 540 uint8_t cmd;
stevew817 0:667132a19341 541
stevew817 0:667132a19341 542 cmd = 0x40 + ((uint8_t)address & 0x3F);
stevew817 0:667132a19341 543
stevew817 0:667132a19341 544 retval = send_cmd((enum Si1133::Command)cmd);
stevew817 0:667132a19341 545 if ( retval != SI1133_OK ) {
stevew817 0:667132a19341 546 return retval;
stevew817 0:667132a19341 547 }
stevew817 0:667132a19341 548
stevew817 0:667132a19341 549 read_register(REG_RESPONSE1, &retval);
stevew817 0:667132a19341 550
stevew817 0:667132a19341 551 return retval;
stevew817 0:667132a19341 552 }
stevew817 0:667132a19341 553
stevew817 0:667132a19341 554 /**************************************************************************//**
stevew817 0:667132a19341 555 * @brief
stevew817 0:667132a19341 556 * Initializes the Si1133 chip
stevew817 0:667132a19341 557 *
stevew817 0:667132a19341 558 * @return
stevew817 0:667132a19341 559 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 560 *****************************************************************************/
stevew817 0:667132a19341 561 uint32_t Si1133::init (void)
stevew817 0:667132a19341 562 {
stevew817 0:667132a19341 563 uint32_t retval;
stevew817 0:667132a19341 564
stevew817 0:667132a19341 565 /* Allow some time for the part to power up */
stevew817 0:667132a19341 566 wait_ms(5);
stevew817 0:667132a19341 567
stevew817 0:667132a19341 568 retval = reset();
stevew817 0:667132a19341 569
stevew817 0:667132a19341 570 wait_ms(10);
stevew817 0:667132a19341 571
stevew817 0:667132a19341 572 retval += set_parameter(PARAM_CH_LIST, 0x0f);
stevew817 0:667132a19341 573 retval += set_parameter(PARAM_ADCCONFIG0, 0x78);
stevew817 0:667132a19341 574 retval += set_parameter(PARAM_ADCSENS0, 0x71);
stevew817 0:667132a19341 575 retval += set_parameter(PARAM_ADCPOST0, 0x40);
stevew817 0:667132a19341 576 retval += set_parameter(PARAM_ADCCONFIG1, 0x4d);
stevew817 0:667132a19341 577 retval += set_parameter(PARAM_ADCSENS1, 0xe1);
stevew817 0:667132a19341 578 retval += set_parameter(PARAM_ADCPOST1, 0x40);
stevew817 0:667132a19341 579 retval += set_parameter(PARAM_ADCCONFIG2, 0x41);
stevew817 0:667132a19341 580 retval += set_parameter(PARAM_ADCSENS2, 0xe1);
stevew817 0:667132a19341 581 retval += set_parameter(PARAM_ADCPOST2, 0x50);
stevew817 0:667132a19341 582 retval += set_parameter(PARAM_ADCCONFIG3, 0x4d);
stevew817 0:667132a19341 583 retval += set_parameter(PARAM_ADCSENS3, 0x87);
stevew817 0:667132a19341 584 retval += set_parameter(PARAM_ADCPOST3, 0x40);
stevew817 0:667132a19341 585
stevew817 0:667132a19341 586 retval += write_register(REG_IRQ_ENABLE, 0x0f);
stevew817 0:667132a19341 587
stevew817 0:667132a19341 588 return retval;
stevew817 0:667132a19341 589 }
stevew817 0:667132a19341 590
stevew817 0:667132a19341 591 /***************************************************************************//**
stevew817 0:667132a19341 592 * @brief
stevew817 0:667132a19341 593 * Stops the measurements on all channel and waits until the chip
stevew817 0:667132a19341 594 * goes to sleep state.
stevew817 0:667132a19341 595 *
stevew817 0:667132a19341 596 * @return
stevew817 0:667132a19341 597 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 598 ******************************************************************************/
stevew817 0:667132a19341 599 uint32_t Si1133::deinit (void)
stevew817 0:667132a19341 600 {
stevew817 0:667132a19341 601 uint32_t retval;
stevew817 0:667132a19341 602
stevew817 0:667132a19341 603 retval = set_parameter(PARAM_CH_LIST, 0x3f);
stevew817 0:667132a19341 604 retval += pause_measurement();
stevew817 0:667132a19341 605 retval += wait_until_sleep();
stevew817 0:667132a19341 606
stevew817 0:667132a19341 607 return retval;
stevew817 0:667132a19341 608 }
stevew817 0:667132a19341 609
stevew817 0:667132a19341 610 /***************************************************************************//**
stevew817 0:667132a19341 611 * @brief
stevew817 0:667132a19341 612 * Read samples from the Si1133 chip
stevew817 0:667132a19341 613 *
stevew817 0:667132a19341 614 * @param[out] samples
stevew817 0:667132a19341 615 * Retrieves interrupt status and measurement data for channel 0..3 and
stevew817 0:667132a19341 616 * converts the data to int32_t format
stevew817 0:667132a19341 617 *
stevew817 0:667132a19341 618 * @return
stevew817 0:667132a19341 619 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 620 ******************************************************************************/
stevew817 0:667132a19341 621 uint32_t Si1133::measurementGet (Si1133::Samples_t *samples)
stevew817 0:667132a19341 622 {
stevew817 0:667132a19341 623 uint8_t buffer[13];
stevew817 0:667132a19341 624 uint32_t retval;
stevew817 0:667132a19341 625
stevew817 0:667132a19341 626 retval = read_register_block(REG_IRQ_STATUS, 13, buffer);
stevew817 0:667132a19341 627
stevew817 0:667132a19341 628 samples->irq_status = buffer[0];
stevew817 0:667132a19341 629
stevew817 0:667132a19341 630 samples->ch0 = buffer[1] << 16;
stevew817 0:667132a19341 631 samples->ch0 |= buffer[2] << 8;
stevew817 0:667132a19341 632 samples->ch0 |= buffer[3];
stevew817 0:667132a19341 633 if ( samples->ch0 & 0x800000 ) {
stevew817 0:667132a19341 634 samples->ch0 |= 0xFF000000;
stevew817 0:667132a19341 635 }
stevew817 0:667132a19341 636
stevew817 0:667132a19341 637 samples->ch1 = buffer[4] << 16;
stevew817 0:667132a19341 638 samples->ch1 |= buffer[5] << 8;
stevew817 0:667132a19341 639 samples->ch1 |= buffer[6];
stevew817 0:667132a19341 640 if ( samples->ch1 & 0x800000 ) {
stevew817 0:667132a19341 641 samples->ch1 |= 0xFF000000;
stevew817 0:667132a19341 642 }
stevew817 0:667132a19341 643
stevew817 0:667132a19341 644 samples->ch2 = buffer[7] << 16;
stevew817 0:667132a19341 645 samples->ch2 |= buffer[8] << 8;
stevew817 0:667132a19341 646 samples->ch2 |= buffer[9];
stevew817 0:667132a19341 647 if ( samples->ch2 & 0x800000 ) {
stevew817 0:667132a19341 648 samples->ch2 |= 0xFF000000;
stevew817 0:667132a19341 649 }
stevew817 0:667132a19341 650
stevew817 0:667132a19341 651 samples->ch3 = buffer[10] << 16;
stevew817 0:667132a19341 652 samples->ch3 |= buffer[11] << 8;
stevew817 0:667132a19341 653 samples->ch3 |= buffer[12];
stevew817 0:667132a19341 654 if ( samples->ch3 & 0x800000 ) {
stevew817 0:667132a19341 655 samples->ch3 |= 0xFF000000;
stevew817 0:667132a19341 656 }
stevew817 0:667132a19341 657
stevew817 0:667132a19341 658 return retval;
stevew817 0:667132a19341 659 }
stevew817 0:667132a19341 660
stevew817 0:667132a19341 661 int32_t Si1133::calculate_polynomial_helper (int32_t input, int8_t fraction, uint16_t mag, int8_t shift)
stevew817 0:667132a19341 662 {
stevew817 0:667132a19341 663 int32_t value;
stevew817 0:667132a19341 664
stevew817 0:667132a19341 665 if ( shift < 0 ) {
stevew817 0:667132a19341 666 value = ( (input << fraction) / mag) >> -shift;
stevew817 0:667132a19341 667 } else {
stevew817 0:667132a19341 668 value = ( (input << fraction) / mag) << shift;
stevew817 0:667132a19341 669 }
stevew817 0:667132a19341 670
stevew817 0:667132a19341 671 return value;
stevew817 0:667132a19341 672 }
stevew817 0:667132a19341 673
stevew817 0:667132a19341 674 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 675 {
stevew817 0:667132a19341 676 uint8_t info, x_order, y_order, counter;
stevew817 0:667132a19341 677 int8_t sign, shift;
stevew817 0:667132a19341 678 uint16_t mag;
stevew817 0:667132a19341 679 int32_t output = 0, x1, x2, y1, y2;
stevew817 0:667132a19341 680
stevew817 0:667132a19341 681 for ( counter = 0; counter < num_coeff; counter++ ) {
stevew817 0:667132a19341 682 info = kp->info;
stevew817 0:667132a19341 683 x_order = GET_X_ORDER(info);
stevew817 0:667132a19341 684 y_order = GET_Y_ORDER(info);
stevew817 0:667132a19341 685
stevew817 0:667132a19341 686 shift = ( (uint16_t) kp->info & 0xff00) >> 8;
stevew817 0:667132a19341 687 shift ^= 0x00ff;
stevew817 0:667132a19341 688 shift += 1;
stevew817 0:667132a19341 689 shift = -shift;
stevew817 0:667132a19341 690
stevew817 0:667132a19341 691 mag = kp->mag;
stevew817 0:667132a19341 692
stevew817 0:667132a19341 693 if ( GET_SIGN(info) ) {
stevew817 0:667132a19341 694 sign = -1;
stevew817 0:667132a19341 695 } else {
stevew817 0:667132a19341 696 sign = 1;
stevew817 0:667132a19341 697 }
stevew817 0:667132a19341 698
stevew817 0:667132a19341 699 if ( (x_order == 0) && (y_order == 0) ) {
stevew817 0:667132a19341 700 output += sign * mag << output_fraction;
stevew817 0:667132a19341 701 } else {
stevew817 0:667132a19341 702 if ( x_order > 0 ) {
stevew817 0:667132a19341 703 x1 = calculate_polynomial_helper(x, input_fraction, mag, shift);
stevew817 0:667132a19341 704 if ( x_order > 1 ) {
stevew817 0:667132a19341 705 x2 = calculate_polynomial_helper(x, input_fraction, mag, shift);
stevew817 0:667132a19341 706 } else {
stevew817 0:667132a19341 707 x2 = 1;
stevew817 0:667132a19341 708 }
stevew817 0:667132a19341 709 } else {
stevew817 0:667132a19341 710 x1 = 1;
stevew817 0:667132a19341 711 x2 = 1;
stevew817 0:667132a19341 712 }
stevew817 0:667132a19341 713
stevew817 0:667132a19341 714 if ( y_order > 0 ) {
stevew817 0:667132a19341 715 y1 = calculate_polynomial_helper(y, input_fraction, mag, shift);
stevew817 0:667132a19341 716 if ( y_order > 1 ) {
stevew817 0:667132a19341 717 y2 = calculate_polynomial_helper(y, input_fraction, mag, shift);
stevew817 0:667132a19341 718 } else {
stevew817 0:667132a19341 719 y2 = 1;
stevew817 0:667132a19341 720 }
stevew817 0:667132a19341 721 } else {
stevew817 0:667132a19341 722 y1 = 1;
stevew817 0:667132a19341 723 y2 = 1;
stevew817 0:667132a19341 724 }
stevew817 0:667132a19341 725
stevew817 0:667132a19341 726 output += sign * x1 * x2 * y1 * y2;
stevew817 0:667132a19341 727 }
stevew817 0:667132a19341 728
stevew817 0:667132a19341 729 kp++;
stevew817 0:667132a19341 730 }
stevew817 0:667132a19341 731
stevew817 0:667132a19341 732 if ( output < 0 ) {
stevew817 0:667132a19341 733 output = -output;
stevew817 0:667132a19341 734 }
stevew817 0:667132a19341 735
stevew817 0:667132a19341 736 return output;
stevew817 0:667132a19341 737 }
stevew817 0:667132a19341 738
stevew817 0:667132a19341 739 /***************************************************************************//**
stevew817 0:667132a19341 740 * @brief
stevew817 0:667132a19341 741 * Compute UV index
stevew817 0:667132a19341 742 *
stevew817 0:667132a19341 743 * @param[in] uv
stevew817 0:667132a19341 744 * UV sensor raw data
stevew817 0:667132a19341 745 *
stevew817 0:667132a19341 746 * @param[in] uk
stevew817 0:667132a19341 747 * UV calculation coefficients
stevew817 0:667132a19341 748 *
stevew817 0:667132a19341 749 * @return
stevew817 0:667132a19341 750 * UV index scaled by UV_OUPTUT_FRACTION
stevew817 0:667132a19341 751 ******************************************************************************/
stevew817 0:667132a19341 752 int32_t Si1133::getUv (int32_t uv)
stevew817 0:667132a19341 753 {
stevew817 0:667132a19341 754 int32_t uvi;
stevew817 0:667132a19341 755
stevew817 0:667132a19341 756 uvi = calculate_polynomial(0, uv, UV_INPUT_FRACTION, UV_OUTPUT_FRACTION, UV_NUMCOEFF, uk);
stevew817 0:667132a19341 757
stevew817 0:667132a19341 758 return uvi;
stevew817 0:667132a19341 759 }
stevew817 0:667132a19341 760
stevew817 0:667132a19341 761 /***************************************************************************//**
stevew817 0:667132a19341 762 * @brief
stevew817 0:667132a19341 763 * Compute lux value
stevew817 0:667132a19341 764 *
stevew817 0:667132a19341 765 * @param[in] vis_high
stevew817 0:667132a19341 766 * Visible light sensor raw data
stevew817 0:667132a19341 767 *
stevew817 0:667132a19341 768 * @param[in] vis_low
stevew817 0:667132a19341 769 * Visible light sensor raw data
stevew817 0:667132a19341 770 *
stevew817 0:667132a19341 771 * @param[in] ir
stevew817 0:667132a19341 772 * Infrared sensor raw data
stevew817 0:667132a19341 773 *
stevew817 0:667132a19341 774 * @param[in] lk
stevew817 0:667132a19341 775 * Lux calculation coefficients
stevew817 0:667132a19341 776 *
stevew817 0:667132a19341 777 * @return
stevew817 0:667132a19341 778 * Lux value scaled by LUX_OUPTUT_FRACTION
stevew817 0:667132a19341 779 ******************************************************************************/
stevew817 0:667132a19341 780 int32_t Si1133::getLux (int32_t vis_high, int32_t vis_low, int32_t ir)
stevew817 0:667132a19341 781 {
stevew817 0:667132a19341 782 int32_t lux;
stevew817 0:667132a19341 783
stevew817 0:667132a19341 784 if ( (vis_high > ADC_THRESHOLD) || (ir > ADC_THRESHOLD) ) {
stevew817 0:667132a19341 785 lux = calculate_polynomial(vis_high,
stevew817 0:667132a19341 786 ir,
stevew817 0:667132a19341 787 INPUT_FRACTION_HIGH,
stevew817 0:667132a19341 788 LUX_OUTPUT_FRACTION,
stevew817 0:667132a19341 789 NUMCOEFF_HIGH,
stevew817 0:667132a19341 790 &(lk.coeff_high[0]) );
stevew817 0:667132a19341 791 } else {
stevew817 0:667132a19341 792 lux = calculate_polynomial(vis_low,
stevew817 0:667132a19341 793 ir,
stevew817 0:667132a19341 794 INPUT_FRACTION_LOW,
stevew817 0:667132a19341 795 LUX_OUTPUT_FRACTION,
stevew817 0:667132a19341 796 NUMCOEFF_LOW,
stevew817 0:667132a19341 797 &(lk.coeff_low[0]) );
stevew817 0:667132a19341 798 }
stevew817 0:667132a19341 799
stevew817 0:667132a19341 800 return lux;
stevew817 0:667132a19341 801 }
stevew817 0:667132a19341 802
stevew817 0:667132a19341 803 /***************************************************************************//**
stevew817 0:667132a19341 804 * @brief
stevew817 0:667132a19341 805 * Measure lux and UV index using the Si1133 sensor
stevew817 0:667132a19341 806 *
stevew817 0:667132a19341 807 * @param[out] lux
stevew817 0:667132a19341 808 * The measured ambient light illuminace in lux
stevew817 0:667132a19341 809 *
stevew817 0:667132a19341 810 * @param[out] uvi
stevew817 0:667132a19341 811 * UV index
stevew817 0:667132a19341 812 *
stevew817 0:667132a19341 813 * @return
stevew817 0:667132a19341 814 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 815 ******************************************************************************/
stevew817 0:667132a19341 816 uint32_t Si1133::measureLuxUvi (float *lux, float *uvi)
stevew817 0:667132a19341 817 {
stevew817 0:667132a19341 818 Si1133::Samples_t samples;
stevew817 0:667132a19341 819 uint32_t retval;
stevew817 0:667132a19341 820 uint8_t response;
stevew817 0:667132a19341 821
stevew817 0:667132a19341 822 /* Force measurement */
stevew817 0:667132a19341 823 retval = force_measurement();
stevew817 0:667132a19341 824
stevew817 0:667132a19341 825 /* Go to sleep while the sensor does the conversion */
stevew817 0:667132a19341 826 wait_ms(200);
stevew817 0:667132a19341 827
stevew817 0:667132a19341 828 /* Check if the measurement finished, if not then wait */
stevew817 0:667132a19341 829 retval += read_register(REG_IRQ_STATUS, &response);
stevew817 0:667132a19341 830 while ( response != 0x0F ) {
stevew817 0:667132a19341 831 wait_ms(5);
stevew817 0:667132a19341 832 retval += read_register(REG_IRQ_STATUS, &response);
stevew817 0:667132a19341 833 }
stevew817 0:667132a19341 834
stevew817 0:667132a19341 835 /* Get the results */
stevew817 0:667132a19341 836 measurementGet(&samples);
stevew817 0:667132a19341 837
stevew817 0:667132a19341 838 /* Convert the readings to lux */
stevew817 0:667132a19341 839 *lux = (float) getLux(samples.ch1, samples.ch3, samples.ch2);
stevew817 0:667132a19341 840 *lux = *lux / (1 << LUX_OUTPUT_FRACTION);
stevew817 0:667132a19341 841
stevew817 0:667132a19341 842 /* Convert the readings to UV index */
stevew817 0:667132a19341 843 *uvi = (float) getUv(samples.ch0);
stevew817 0:667132a19341 844 *uvi = *uvi / (1 << UV_OUTPUT_FRACTION);
stevew817 0:667132a19341 845
stevew817 0:667132a19341 846 return retval;
stevew817 0:667132a19341 847 }
stevew817 0:667132a19341 848
stevew817 0:667132a19341 849 /***************************************************************************//**
stevew817 0:667132a19341 850 * @brief
stevew817 0:667132a19341 851 * Reads Hardware ID from the SI1133 sensor
stevew817 0:667132a19341 852 *
stevew817 0:667132a19341 853 * @param[out] hardwareID
stevew817 0:667132a19341 854 * The Hardware ID of the chip (should be 0x33)
stevew817 0:667132a19341 855 *
stevew817 0:667132a19341 856 * @return
stevew817 0:667132a19341 857 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 858 ******************************************************************************/
stevew817 0:667132a19341 859 uint32_t Si1133::getHardwareID (uint8_t *hardwareID)
stevew817 0:667132a19341 860 {
stevew817 0:667132a19341 861 uint32_t retval;
stevew817 0:667132a19341 862
stevew817 0:667132a19341 863 retval = read_register(REG_PART_ID, hardwareID);
stevew817 0:667132a19341 864
stevew817 0:667132a19341 865 return retval;
stevew817 0:667132a19341 866 }
stevew817 0:667132a19341 867
stevew817 0:667132a19341 868 /***************************************************************************//**
stevew817 0:667132a19341 869 * @brief
stevew817 0:667132a19341 870 * Retrieve the sample values from the chip and convert them
stevew817 0:667132a19341 871 * to lux and UV index values
stevew817 0:667132a19341 872 *
stevew817 0:667132a19341 873 * @param[out] lux
stevew817 0:667132a19341 874 * The measured ambient light illuminace in lux
stevew817 0:667132a19341 875 *
stevew817 0:667132a19341 876 * @param[out] uvi
stevew817 0:667132a19341 877 * UV index
stevew817 0:667132a19341 878 *
stevew817 0:667132a19341 879 * @return
stevew817 0:667132a19341 880 * Returns zero on OK, non-zero otherwise
stevew817 0:667132a19341 881 ******************************************************************************/
stevew817 0:667132a19341 882 uint32_t Si1133::getMeasurement (float *lux, float *uvi)
stevew817 0:667132a19341 883 {
stevew817 0:667132a19341 884 Si1133::Samples_t samples;
stevew817 0:667132a19341 885 uint32_t retval;
stevew817 0:667132a19341 886
stevew817 0:667132a19341 887 /* Get the results */
stevew817 0:667132a19341 888 retval = measurementGet(&samples);
stevew817 0:667132a19341 889
stevew817 0:667132a19341 890 /* Convert the readings to lux */
stevew817 0:667132a19341 891 *lux = (float) getLux(samples.ch1, samples.ch3, samples.ch2);
stevew817 0:667132a19341 892 *lux = *lux / (1 << LUX_OUTPUT_FRACTION);
stevew817 0:667132a19341 893
stevew817 0:667132a19341 894 /* Convert the readings to UV index */
stevew817 0:667132a19341 895 *uvi = (float) getUv(samples.ch0);
stevew817 0:667132a19341 896 *uvi = *uvi / (1 << UV_OUTPUT_FRACTION);
stevew817 0:667132a19341 897
stevew817 0:667132a19341 898 return retval;
stevew817 0:667132a19341 899 }