JDI_MIP on ThunderBoardSense2(Silicon-Labs)

JDI_MIP (LPM013M126A) Sample on ThunderBoard2(Silicon-Labs)

/media/uploads/STakayama/mip8_tb2_sample0_.jpg LPM013M126A /media/uploads/STakayama/mip8_tb2_sample1.jpg

Links

https://os.mbed.com/teams/JapanDisplayInc/

https://os.mbed.com/teams/JapanDisplayInc/wiki/MIP-reflective-color-display

Committer:
STakayama
Date:
Tue Jan 22 10:23:39 2019 +0000
Revision:
13:9fb661dd4b2a
Parent:
10:525bcf8907fc
BackColor = Cyan

Who changed what in which revision?

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