vlx lib
Diff: als_driver.cpp
- Revision:
- 0:bc9f26b5dadf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/als_driver.cpp Sun Feb 08 14:26:51 2015 +0000 @@ -0,0 +1,482 @@ +/******************************************************************************* +################################################################################ +# (C) STMicroelectronics 2014 +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License version 2 and only version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +#------------------------------------------------------------------------------ +# Imaging Division +################################################################################ +********************************************************************************/ + +/* +''' +Application-level methods used by VL6180X for ALS operations. +''' +*/ + +//# ST libraries +#include "als_driver.h" +#include "debug.h" +#include "platform.h" +#include "utilities.h" + +//----------------------------------------------------------------------------- +// global variable declarations +//----------------------------------------------------------------------------- +static uint16_t _integration_period = DEFAULT_INTEGRATION_PERIOD; +static float_t _lux_resolution = DEFAULT_LUX_RESOLUTION; +static uint32_t _als_scaler = DEFAULT_ALS_SCALER; +static uint32_t _als_real_gain_val = DEFAULT_ALS_GAIN; +//----------------------------------------------------------------------------- +// method definitions +//----------------------------------------------------------------------------- + +sensor_error als_set_dynamic_config(uint8_t device_base_address) +{ +/* + ''' + Device setup for ALS parameters. These settings can be applied at any time. The status of operation bit (bit 0) of the SYSALS_START is not important. + + :rtype: none + ''' +*/ + + LOG_FUNCTION_START((void*)&device_base_address); + + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +sensor_error als_set_systemMode(uint8_t device_base_address, uint8_t mode) +{ + uint8_t startRegVal; + sensor_error ret = SENSOR_ERROR_NONE; + + LOG_FUNCTION_START((void*)&device_base_address, (void*)&mode); + switch (mode) + { + case ALS_START_SINGLESHOT: + i2c_write_byte(SYSALS_START, mode, device_base_address); +// i2c_write_byte(SYSALS_START, (uint8_t)ALS_START_SINGLESHOT, I2C_ADDR); + break; + case ALS_START_CONTINUOUS: + // ensure mode bit is set! + startRegVal = i2c_read_byte(SYSALS_START, device_base_address); + startRegVal |= 0x03; + i2c_write_byte(SYSALS_START, startRegVal, device_base_address); + break; + case ALS_STOP: + // ensure mode bit is left unaffected! + startRegVal = i2c_read_byte(SYSALS_START, device_base_address); + startRegVal |= 0x01; + // set the bit, as it is a toggle state, not a 0=Off, 1=ON! + i2c_write_byte(SYSALS_START, startRegVal, device_base_address); + break; + default: + ret = COMMON_INVALID_PARAMS; + } + LOG_FUNCTION_END(ret); + + return ret; +} + +uint8_t als_get_systemMode(uint8_t device_base_address) +{ + uint8_t ret=0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_byte(SYSALS_START, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +uint16_t als_get_result(uint8_t device_base_address) +{ + uint16_t ret=0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_word(RESULT_ALS_VAL, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +uint16_t als_get_lux(uint8_t device_base_address) +{ + //uint16_t ret=0; + float rawValue = 0.0f; + float integrationTimeRatio = DEFAULT_INTEGRATION_PERIOD/_integration_period; + uint32_t luxValue = 0; + + LOG_FUNCTION_START((void*)&device_base_address); + + rawValue = (float_t)als_get_result(device_base_address); + luxValue = roundFloatToInt(rawValue * integrationTimeRatio * _lux_resolution); + luxValue /= float(_als_scaler * _als_real_gain_val); + + LOG_FUNCTION_END((uint16_t)luxValue); + + return luxValue; +} + +sensor_error als_set_thresholds(uint8_t device_base_address, uint16_t low_threshold, uint16_t high_threshold) +{ + LOG_FUNCTION_START((void*)&device_base_address,(void*)&low_threshold, (void*)&high_threshold); + i2c_write_word(SYSALS_THRESH_LOW, low_threshold, device_base_address); + i2c_write_word(SYSALS_THRESH_HIGH, high_threshold, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +sensor_error als_set_high_threshold(uint8_t device_base_address, uint16_t threshold) +{ + LOG_FUNCTION_START((void*)&device_base_address,(void*)&threshold); + i2c_write_word(SYSALS_THRESH_HIGH, threshold, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint16_t als_get_high_threshold(uint8_t device_base_address) +{ + uint16_t ret = 0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_word(SYSALS_THRESH_HIGH, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +sensor_error als_set_low_threshold(uint8_t device_base_address, uint16_t threshold) +{ + LOG_FUNCTION_START((void*)&device_base_address,(void*)&threshold); + i2c_write_word(SYSALS_THRESH_LOW, threshold, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint16_t als_get_low_threshold(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + uint16_t ret = i2c_read_word(SYSALS_THRESH_LOW, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +sensor_error als_set_interMeasurement_period(uint8_t device_base_address, uint16_t intermeasurement_period) +{ + LOG_FUNCTION_START((void*)&device_base_address, (void*)&intermeasurement_period); + //clipping: range is 0-2550ms + if (intermeasurement_period >= 255 *10) + intermeasurement_period = 255 *10; + i2c_write_byte(SYSALS_INTERMEASUREMENT_PERIOD, (uint8_t)(intermeasurement_period/10), device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint16_t als_get_interMeasurement_period(uint8_t device_base_address) +{ + uint16_t ret=0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_byte(SYSALS_INTERMEASUREMENT_PERIOD, device_base_address); + ret *=10; //retun as time in ms + LOG_FUNCTION_END(ret); + + return ret; +} + +sensor_error als_set_analogue_gain(uint8_t device_base_address, uint8_t light_analogue_gain) +{ + const uint8_t GainDark = 0x40; + uint8_t GainTotal; + + LOG_FUNCTION_START((void*)&device_base_address, (void*)&light_analogue_gain); + if (light_analogue_gain > 7) + { + // ALS_SetAnalogueGainLight: Clipping value to 7 + light_analogue_gain = 7; + } + + GainTotal = GainDark | light_analogue_gain; // add both together + i2c_write_byte(SYSALS_ANALOGUE_GAIN, GainTotal, device_base_address); + + if(light_analogue_gain == 0) + { + _als_real_gain_val = 20.0f; + } + else if(light_analogue_gain == 1) + { + _als_real_gain_val = 10.0f; + } + else if(light_analogue_gain == 2) + { + _als_real_gain_val = 5.0f; + } + else if(light_analogue_gain == 3) + { + _als_real_gain_val = 2.5f; + } + else if(light_analogue_gain == 4) + { + _als_real_gain_val = 1.67f; + } + else if(light_analogue_gain == 5) + { + _als_real_gain_val = 1.25; + } + else if(light_analogue_gain == 6) + { + _als_real_gain_val = 1.0; + } + + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint8_t als_get_analogue_gain(uint8_t device_base_address) +{ + int8_t ret=0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_byte(SYSALS_ANALOGUE_GAIN, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +sensor_error als_set_integration_period(uint8_t device_base_address, uint16_t integration_period) +{ + int myTime; + + LOG_FUNCTION_START((void*)&device_base_address, (void*)&integration_period); + + myTime = integration_period - 1; + + if (myTime < 0) + { + myTime = 0; + } + else if (myTime > 464) + { + // ALS_SetIntegrationPeriod: Clipping value to 465ms + myTime = 464; + } + else if (myTime == 255) + { + myTime++; + // can't write 255 since this causes the device to lock out. + } + + i2c_write_word(SYSALS_INTEGRATION_PERIOD, myTime, device_base_address); + + _integration_period = myTime; + + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint16_t als_get_integration_period(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + uint16_t intTime = i2c_read_word(SYSALS_INTEGRATION_PERIOD, device_base_address); + intTime +=1; + + _integration_period = intTime; + + LOG_FUNCTION_END(intTime); + + return intTime; +} + + +uint8_t als_get_result_status(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + uint8_t resultStatus = i2c_read_byte(RESULT_ALS_STATUS, device_base_address); + LOG_FUNCTION_END(resultStatus); + + return resultStatus; +} + +bool_t als_get_device_ready(uint8_t device_base_address) +{ + bool_t deviceReady = FALSE; + + LOG_FUNCTION_START((void*)&device_base_address); + if ((i2c_read_byte(RESULT_ALS_STATUS, device_base_address) & ALS_DEVICE_READY) == ALS_DEVICE_READY) + { + deviceReady = TRUE; + } + LOG_FUNCTION_END(deviceReady); + + return deviceReady; +} + +uint8_t als_get_result_error_codes(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + uint8_t errorCode = (i2c_read_byte(RESULT_ALS_STATUS, device_base_address) & 0xF0) >> 4; + LOG_FUNCTION_END(errorCode); + + return errorCode; +} + + +sensor_error als_set_interleaved_mode(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + i2c_write_byte(INTERLEAVED_MODE_ENABLE, 1, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +sensor_error als_clear_interleaved_mode(uint8_t device_base_address) +{ + LOG_FUNCTION_START((void*)&device_base_address); + i2c_write_byte(INTERLEAVED_MODE_ENABLE, 0, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint8_t als_get_interleaved_mode(uint8_t device_base_address) +{ + uint8_t ret=0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = i2c_read_byte(INTERLEAVED_MODE_ENABLE, device_base_address); + LOG_FUNCTION_END(ret); + + return ret; +} + +/////////////////////// + +sensor_error als_set_system_interrupt_config_gpio(uint8_t device_base_address, uint8_t ALS_GPIO_interrupt_config) +{ + uint8_t cmd, reg; + sensor_error ret = SENSOR_ERROR_NONE; + + LOG_FUNCTION_START((void*)&device_base_address, (void*)&ALS_GPIO_interrupt_config); + switch (ALS_GPIO_interrupt_config) + { + case CONFIG_GPIO_INTERRUPT_DISABLED: + case CONFIG_GPIO_INTERRUPT_LEVEL_LOW: + case CONFIG_GPIO_INTERRUPT_LEVEL_HIGH: + case CONFIG_GPIO_INTERRUPT_OUT_OF_WINDOW: + case CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY: + cmd = ALS_GPIO_interrupt_config << 3; // shift command upto bits [5:3] + reg = i2c_read_byte(SYSTEM_INTERRUPT_CONFIG_GPIO, device_base_address); + reg &= 0x07; // preserve only the range part of the reg + i2c_write_byte(SYSTEM_INTERRUPT_CONFIG_GPIO, (reg | cmd), device_base_address); + _integration_period = als_get_integration_period(device_base_address); + break; + default : + ret = COMMON_INVALID_PARAMS; + break; + } + LOG_FUNCTION_END(ret); + + return ret; +} + +uint8_t als_get_system_interrupt_config_gpio(uint8_t device_base_address) +{ + uint8_t ret = 0; + + LOG_FUNCTION_START((void*)&device_base_address); + //# expose only bits [5:3], then shift down 3 places + ret = ( (i2c_read_byte(SYSTEM_INTERRUPT_CONFIG_GPIO, device_base_address) & 0x38) >> 3 ); + LOG_FUNCTION_END(ret); + + return ret; +} + +uint8_t als_get_result_interrupt_status_gpio(uint8_t device_base_address) +{ + uint8_t ret = 0; + + LOG_FUNCTION_START((void*)&device_base_address); + ret = ( (i2c_read_byte(RESULT_INTERRUPT_STATUS_GPIO, device_base_address) & 0x38) >> 3 ); + LOG_FUNCTION_END(ret); + + return ret; +} + +sensor_error als_set_system_interrupt_clear(uint8_t device_base_address) +{ + + LOG_FUNCTION_START((void*)&device_base_address); + i2c_write_byte(SYSTEM_INTERRUPT_CLEAR, INTERRUPT_CLEAR_ALS, device_base_address); + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +sensor_error als_set_history_buffer_mode_enable(uint8_t device_base_address) +{ + uint8_t mode; + sensor_error ret = SENSOR_ERROR_NONE; + + LOG_FUNCTION_START((void*)&device_base_address); + + mode = i2c_read_byte(SYSTEM_HISTORY_CTRL, device_base_address); + mode = mode | 0x03; // set bits 0 and 1 to set to ALS mode and enable + i2c_write_byte(SYSTEM_HISTORY_CTRL, mode, device_base_address); + + LOG_FUNCTION_END(NULL); + + return ret; +} + +sensor_error als_set_scaler(uint8_t device_base_address, uint8_t scaler) +{ + const uint32_t cMask = 0x0f; + + LOG_FUNCTION_START((void*)&device_base_address); + + _als_scaler = (uint32_t)scaler & cMask; + i2c_write_byte(FW_ALS_RESULT_SCALER, (uint8_t)_als_scaler, device_base_address); + + LOG_FUNCTION_END(NULL); + + return SENSOR_ERROR_NONE; +} + +uint32_t als_get_scaler(uint8_t device_base_address) +{ + const uint32_t cMask = 0x0f; + + LOG_FUNCTION_START((void*)&device_base_address); + + _als_scaler = (uint32_t)i2c_read_byte(FW_ALS_RESULT_SCALER, device_base_address) & cMask; + + LOG_FUNCTION_END(_als_scaler); + + return _als_scaler; +} + +