SI1133 light sensor

Committer:
brunnobbco
Date:
Wed Nov 06 20:10:47 2019 +0000
Revision:
0:fe6c4edd0ecc
Light sensor to NRF52840

Who changed what in which revision?

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