vlx lib

als_driver.cpp

Committer:
vijaynvr
Date:
2015-02-08
Revision:
0:bc9f26b5dadf

File content as of revision 0:bc9f26b5dadf:

/*******************************************************************************
################################################################################
#                             (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;
}