vlx lib

ranging_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
################################################################################
********************************************************************************/

// Ranging_Driver.c

/*
'''
Application-level functions used for configuration and operation during ranging.
'''
*/


// ST libraries
#include "ranging_driver.h"
#include "utilities.h"
#include "platform.h"
#include "debug.h"
//----------------------------ECE_FACTOR-------------------------------------------------
// global variable declarations
//-----------------------------------------------------------------------------
//double_t ece_factor = ECE_FACTOR; // user set ECE margin (< 1.00 for maximum detection, > 1.00 for minimizing red glow)
uint32_t ece_factor_m = ECE_FACTOR_M;
uint32_t ece_factor_d = ECE_FACTOR_D;

//-----------------------------------------------------------------------------
// function definitions
//-----------------------------------------------------------------------------

sensor_error range_set_dynamic_config(uint8_t device_base_address)
{

    LOG_FUNCTION_START((void*)&device_base_address);
    LOG_FUNCTION_END(NULL);

    return SENSOR_ERROR_NONE;
}

sensor_error range_set_systemMode(uint8_t device_base_address, int32_t mode)
{
    uint8_t startRegVal;
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&mode);
    switch (mode)
    {
        case RANGE_START_SINGLESHOT:
            i2c_write_byte(SYSRANGE_START, mode, device_base_address);
            break;
        case RANGE_START_CONTINUOUS:
            // ensure mode bit is set!
            startRegVal = i2c_read_byte(SYSRANGE_START, device_base_address);
            startRegVal |= 0x03;
            i2c_write_byte(SYSRANGE_START, startRegVal, device_base_address);
            break;
        case RANGE_STOP:
            // ensure mode bit is left unaffected!
            startRegVal = i2c_read_byte(SYSRANGE_START, device_base_address);
            startRegVal |= 0x01;
            // set the bit, as it is a toggle state, not a 0=Off, 1=ON!
            i2c_write_byte(SYSRANGE_START, startRegVal, device_base_address);
            break;
        default:
            ret = COMMON_INVALID_PARAMS;
    }
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_systemMode(uint8_t device_base_address)
{
    uint8_t ret = 0;

    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_START, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_result(uint8_t device_base_address)
{
    return i2c_read_byte(RESULT_RANGE_VAL, device_base_address);
}

uint32_t range_get_signal_rate(uint8_t device_base_address)
{
    uint32_t rawVal = (uint32_t)i2c_read_word(RESULT_RANGE_SIGNAL_RATE, device_base_address);

    return rawVal;
}

sensor_error range_get_full_result(uint8_t device_base_address)
{
/*
    return_list = []

# I2C base address is 8-bit indexing
    I2C_base_address = Utilities.device['reg_bank_go2']['I2C_SLAVE_DEVICE_ADDRESS'].read()
    I2C_base_address *= 2 # convert from 7-bit to 8-bit address

# make the indexing easy, read from index 0x60, but we only want data from 0x62!
# reading from indices 0x60-0x84
#    common.Set_System_Group_Parameter_Hold()
    regs = Utilities.device.comms['read'](I2C_base_address, 0x60, 0x25)
    conv_threshold = Utilities.device['reg_bank_go2']['USER_CONV_CTRL_RETURN_THRESHOLD_FINE'].read() * 256
#    common.Clear_System_Group_Parameter_Hold()

    result_range_val = regs[2] # address 0x62
    result_range_stray = regs[3]
    result_range_raw = regs[4]
# no results at 0x65
    result_range_return_rate = (regs[6] << 8) + regs[7]
    result_range_reference_rate = (regs[8] << 8) + regs[9]
# indices 0x6A, 0x6B empty
    result_range_Return_VCSEL_count = (regs[0x0C] << 24) + (regs[0x0D] << 16) + (regs[0x0E] << 8) + regs[0x0F]
    result_range_Reference_VCSEL_count = (regs[0x10] << 24) + (regs[0x11] << 16) + (regs[0x12] << 8) + regs[0x13]
    result_range_Return_AMB_count = (regs[0x14] << 24) + (regs[0x15] << 16) + (regs[0x16] << 8) + regs[0x17]
    result_range_Reference_AMB_count = (regs[0x18] << 24) + (regs[0x19] << 16) + (regs[0x1A] << 8) + regs[0x1B]
    result_range_Return_Conv_time = (regs[0x1C] << 24) + (regs[0x1D] << 16) + (regs[0x1E] << 8) + regs[0x1F]
    result_range_Reference_Conv_time = (regs[0x20] << 24) + (regs[0x21] << 16) + (regs[0x22] << 8) + regs[0x23]

    return_list.append( result_range_val )
    return_list.append( result_range_stray )
    return_list.append( result_range_raw )
    return_list.append( result_range_return_rate )
    return_list.append( result_range_reference_rate )
    return_list.append( result_range_Return_VCSEL_count )
    return_list.append( result_range_Reference_VCSEL_count )
    return_list.append( result_range_Return_AMB_count )
    return_list.append( result_range_Reference_AMB_count )
    return_list.append( result_range_Return_Conv_time )
    return_list.append( result_range_Reference_Conv_time )
    return_list.append( conv_threshold )
    return return_list

*/
    return SENSOR_ERROR_NONE;

}

sensor_error range_set_high_threshold(uint8_t device_base_address, uint8_t threshold)
{
    //threshold type is uint8_t. no need to check parameter since from 0-255
    LOG_FUNCTION_START((void*)&device_base_address,(void*)&threshold);
    i2c_write_byte(SYSRANGE_THRESH_HIGH, threshold, device_base_address);
    LOG_FUNCTION_END(NULL);

    return SENSOR_ERROR_NONE;
}

uint8_t range_get_high_threshold(uint8_t device_base_address)
{
    uint8_t ret = 0;

    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_THRESH_HIGH, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_set_low_threshold(uint8_t device_base_address, uint8_t threshold)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    //threshold type is uint8_t. no need to check parameter since from 0-255
    LOG_FUNCTION_START((void*)&device_base_address,(void*)&threshold);
    i2c_write_byte(SYSRANGE_THRESH_LOW, threshold, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_low_threshold(uint8_t device_base_address)
{
    uint8_t ret=0;

    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_THRESH_LOW, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_set_interMeasurement_period(uint8_t device_base_address, uint16_t intermeasurement_period)
{
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&intermeasurement_period);
    if (intermeasurement_period > 255*10)
    {
        // Clipping value to max of 2.55s
        intermeasurement_period = 255*10;
    }
    i2c_write_byte(SYSRANGE_INTERMEASUREMENT_PERIOD, (uint8_t)(intermeasurement_period/10), device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint16_t range_get_interMeasurement_period(uint8_t device_base_address)
{
    uint8_t ret = 0;

    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_INTERMEASUREMENT_PERIOD, device_base_address);
    ret *=10; //return in ms
    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_set_max_convergence_time(uint8_t device_base_address, int32_t max_convergence_time)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address,(void*)&max_convergence_time);
    i2c_write_byte(SYSRANGE_MAX_CONVERGENCE_TIME, max_convergence_time, device_base_address);
    range_set_early_convergence_estimate_threshold(device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_max_convergence_time(uint8_t device_base_address)
{
    return i2c_read_byte(SYSRANGE_MAX_CONVERGENCE_TIME, device_base_address);
}

sensor_error  range_set_crosstalk_compensation_rate(uint8_t device_base_address, int32_t crosstalk_compensation_rate)
{
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&crosstalk_compensation_rate);
    i2c_write_word(SYSRANGE_CROSSTALK_COMPENSATION_RATE, crosstalk_compensation_rate, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

int32_t range_get_crosstalk_compensation_rate(uint8_t device_base_address)
{
    uint32_t ret=0;
    LOG_FUNCTION_START((void*)&device_base_address);
    ret =  i2c_read_word(SYSRANGE_CROSSTALK_COMPENSATION_RATE, device_base_address);
    LOG_FUNCTION_END(NULL);

    return ret;
}

sensor_error range_set_crosstalk_compensation_range(uint8_t device_base_address, int32_t crosstalk_compensation_range)
{
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&crosstalk_compensation_range);
    i2c_write_byte(SYSRANGE_CROSSTALK_COMPENSATION_RANGE, crosstalk_compensation_range, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_crosstalk_compensation_range(uint8_t device_base_address)
{
    uint8_t ret = 0;

    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_CROSSTALK_COMPENSATION_RANGE, device_base_address);
    LOG_FUNCTION_END(NULL);

    return ret;
}

sensor_error range_set_crosstalk_valid_height(uint8_t device_base_address, int32_t crosstalk_valid_height)
{
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&crosstalk_valid_height);
    i2c_write_byte(SYSRANGE_CROSSTALK_VALID_HEIGHT, crosstalk_valid_height, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_crosstalk_valid_height(uint8_t device_base_address)
{
	uint8_t ret;
    LOG_FUNCTION_START((void*)&device_base_address);
    ret = i2c_read_byte(SYSRANGE_CROSSTALK_VALID_HEIGHT, device_base_address);
    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error  range_set_early_convergence_estimate_threshold(uint8_t device_base_address)
{
    sensor_error ret = SENSOR_ERROR_NONE;
  
    uint32_t cMicroSecPerMilliSec  = 1000;
    uint32_t cEceSampleTime_us     = 500;
    uint32_t maxConv_ms            = (uint32_t)range_get_max_convergence_time(device_base_address);
    uint32_t convergTime_us        = maxConv_ms * cMicroSecPerMilliSec - range_get_vernier_ave_total_time(device_base_address);
    uint32_t fineThresh            = range_get_converg_ctrl_rtn_thresh_fine(device_base_address);
    uint32_t eceThresh             = ece_factor_m * cEceSampleTime_us * fineThresh/(convergTime_us * ece_factor_d);
  	LOG_FUNCTION_START((void*)&device_base_address,);

    i2c_write_word(SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, (uint16_t)eceThresh, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_early_convergence_estimate_threshold(uint8_t device_base_address)
{
    uint8_t ret;

    LOG_FUNCTION_START((void*)&device_base_address);

    ret = i2c_read_word(SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint32_t range_get_vernier_ave_total_time(uint8_t device_base_address)
{
    uint32_t cFwOverhead_us        = 24;
    uint32_t cVernVcpSetupTime_us  = 70;
    uint32_t cPLL2_StartupDelay_us = 200;
    uint8_t cVernMeasMask 		   = 0x07;
    uint32_t vernSamples;
    uint32_t vernSamplePeriod;
    uint32_t singleVernTime_us;
    uint32_t totalVernAveTime_us;

    LOG_FUNCTION_START((void*)&device_base_address);

    // Calculate Vernier average time
    vernSamples         = (uint32_t)(i2c_read_byte(VERNIER_MEASUREMENTS, device_base_address) & cVernMeasMask);
    vernSamplePeriod    = (uint32_t)i2c_read_byte(VERNIER_RIPPLE_AVE_SAMPLE_PERIOD, device_base_address);
    singleVernTime_us   = cFwOverhead_us + cVernVcpSetupTime_us + (vernSamplePeriod * 10);
    totalVernAveTime_us = (vernSamples + 1) * singleVernTime_us + cPLL2_StartupDelay_us;

    LOG_FUNCTION_END(totalVernAveTime_us);

    return totalVernAveTime_us;
}

uint32_t range_get_converg_ctrl_rtn_thresh_fine(uint8_t device_base_address)
{
    //uint32_t cBitMask = 0x00FFFFFFF;
    uint32_t cFineThreshLsb = 256;
    uint32_t rawValue;
    uint32_t realValue;

    LOG_FUNCTION_START((void*)&device_base_address);

    rawValue = i2c_read_uint32(USER_CONV_CTRL_RETURN_THRESHOLD_FINE, device_base_address);
    realValue = rawValue * cFineThreshLsb;

    LOG_FUNCTION_END(realValue);

    return realValue;
}

sensor_error range_set_ignore_valid_height(uint8_t device_base_address, int32_t ignore_valid_height)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&ignore_valid_height);

    i2c_write_byte(SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, ignore_valid_height, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_ignore_valid_height(uint8_t device_base_address)
{
	uint8_t ret; 
    LOG_FUNCTION_START((void*)&device_base_address);

    ret = i2c_read_byte(SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_set_range_ignore_threshold(uint8_t device_base_address, uint32_t range_ignore_threshold)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&range_ignore_threshold);
    i2c_write_word(SYSRANGE_RANGE_IGNORE_THRESHOLD,
                   (uint16_t)range_ignore_threshold,
                   device_base_address);


    LOG_FUNCTION_END(ret);

    return ret;
}

uint32_t range_get_range_ignore_threshold(uint8_t device_base_address)
{
    uint16_t ignoreThreshRegVal = i2c_read_word(SYSRANGE_RANGE_IGNORE_THRESHOLD, device_base_address);
    return ignoreThreshRegVal;
}

sensor_error range_set_emitter_block_threshold(uint8_t device_base_address, int32_t emitter_block_threshold)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&emitter_block_threshold);
    i2c_write_word(SYSRANGE_EMITTER_BLOCK_THRESHOLD, emitter_block_threshold, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_emitter_block_threshold(uint8_t device_base_address)
{
    return i2c_read_word(SYSRANGE_EMITTER_BLOCK_THRESHOLD, device_base_address);
}
#ifndef __KERNEL__
sensor_error range_set_snr_thresh(uint8_t device_base_address, float_t snrThresh)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&snrThresh);

    const float cRegFractionLsb = 0.0625f;
    const float cRegWholeLsb    = 1.0f;
    const float cReciprocalMax  = 16.0f - cRegFractionLsb;
    const float cSnrMin = 1.0f/cReciprocalMax;

    uint8_t snrThresRegVal;

    // Taking the reciprocal into account the allowable SNR range is 0.0625...16.0.
    if(snrThresh < cSnrMin)
    {
        snrThresh = cSnrMin;
    }

    float snrthreshMult = 1.0f/snrThresh;
    snrThresRegVal = (uint8_t)encodeTo4_4_Format(snrthreshMult);
    i2c_write_byte(SYSRANGE_MAX_AMBIENT_LEVEL_MULT, (uint8_t)snrThresRegVal, device_base_address);

    LOG_FUNCTION_END(ret);
		
	  return ret;
}


float range_get_snr_thresh(uint8_t device_base_address)
{
    LOG_FUNCTION_START((void*)&device_base_address);

    uint8_t snrthreshMult = i2c_read_byte(SYSRANGE_MAX_AMBIENT_LEVEL_MULT, device_base_address);
    float snrThresh = 1.0f/decodeFrom4_4_Format((uint32_t)snrthreshMult);

    LOG_FUNCTION_END(snrThresh);

    return snrThresh;
}
#endif
sensor_error range_set_range_check_enables(uint8_t device_base_address, int32_t range_check_enables)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&range_check_enables);

    i2c_write_byte(SYSRANGE_RANGE_CHECK_ENABLES, range_check_enables, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_range_check_enables(uint8_t device_base_address)
{
    return i2c_read_byte(SYSRANGE_RANGE_CHECK_ENABLES, device_base_address);
}

sensor_error range_set_vhv_recalibrate(uint8_t device_base_address, int32_t VHV_Recalibrate)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&VHV_Recalibrate);

    i2c_write_byte(SYSRANGE_VHV_RECALIBRATE, VHV_Recalibrate, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_vhv_recalibrate(uint8_t device_base_address)
{
    return i2c_read_byte(SYSRANGE_VHV_RECALIBRATE, device_base_address);
}

sensor_error range_set_vhv_repeat_rate(uint8_t device_base_address, int32_t VHV_repeat_rate)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address, (void*)&VHV_repeat_rate);

    i2c_write_byte(SYSRANGE_VHV_REPEAT_RATE, VHV_repeat_rate, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_vhv_repeat_rate(uint8_t device_base_address)
{
    return i2c_read_byte(SYSRANGE_VHV_REPEAT_RATE, device_base_address);
}

int32_t range_get_result_status(uint8_t device_base_address)
{
    return i2c_read_byte(RESULT_RANGE_STATUS, device_base_address);
}

bool_t range_get_device_ready(uint8_t device_base_address)
{
    if (i2c_read_byte(RESULT_RANGE_STATUS, device_base_address) & RANGE_DEVICE_READY)
    {
        return TRUE;
    }
    return FALSE;
}

uint8_t range_get_result_error_codes(uint8_t device_base_address)
{
    return (i2c_read_byte(RESULT_RANGE_STATUS, device_base_address) & RANGE_ERROR_CODE) >> 4;
}

sensor_error range_set_ece_factor(uint8_t device_base_address, uint32_t ECE_Factor_M, uint32_t ECE_Factor_D)
{
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&ECE_Factor_M, (void*)&ECE_Factor_D);

    ece_factor_m = ECE_Factor_M;
    ece_factor_d = ECE_Factor_D;
    range_set_early_convergence_estimate_threshold(device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_get_ece_factor(uint32_t *pece_factor_m, uint32_t *pece_factor_d)
{
	*pece_factor_m = ece_factor_m;
	*pece_factor_d = ece_factor_d;

    return SENSOR_ERROR_NONE;
}

sensor_error range_set_system_interrupt_config_gpio(uint8_t device_base_address, uint8_t Ranging_GPIO_interrupt_config)
{
    uint8_t reg;
    sensor_error ret = SENSOR_ERROR_NONE;

    LOG_FUNCTION_START((void*)&device_base_address,(void*)&Ranging_GPIO_interrupt_config);
    switch (Ranging_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:
            reg = i2c_read_byte(SYSTEM_INTERRUPT_CONFIG_GPIO, device_base_address);
            reg &= 0x38; // preserve only the ALS part of reg
            i2c_write_byte(SYSTEM_INTERRUPT_CONFIG_GPIO,
                                   (reg | Ranging_GPIO_interrupt_config),
                                   device_base_address);
            break;
        default :
            ret = COMMON_INVALID_PARAMS;
            break;
    }
    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_get_system_interrupt_config_gpio(uint8_t device_base_address)
{
    uint8_t ret=0;

    LOG_FUNCTION_START((void*)&device_base_address);
    // expose only bits [2:0]

    ret = (i2c_read_byte(SYSTEM_INTERRUPT_CONFIG_GPIO, device_base_address) & 0x07);

    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error range_set_system_interrupt_clear(uint8_t device_base_address)
{
    sensor_error ret = SENSOR_ERROR_NONE;
    LOG_FUNCTION_START((void*)&device_base_address);

    i2c_write_byte(SYSTEM_INTERRUPT_CLEAR, INTERRUPT_CLEAR_RANGING, device_base_address);

    LOG_FUNCTION_END(ret);

    return ret;
}

uint8_t range_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) & 0x07);

    LOG_FUNCTION_END(ret);

    return ret;
}

sensor_error common_set_history_buffer_range_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 & 0xFD; // clear bit 1 to set to range mode
    mode = mode | 0x01; // set bit 0 to enable history buffer
    i2c_write_byte(SYSTEM_HISTORY_CTRL, mode, device_base_address);
    
    LOG_FUNCTION_END(NULL);

    return ret;
}


uint32_t range_get_upper_limit(uint8_t device_base_address)
{
    const uint32_t cScalerMax1X = 255;
    uint32_t upperLim = cScalerMax1X;

    LOG_FUNCTION_START((void*)&device_base_address);

    LOG_FUNCTION_END(upperLim);

    return upperLim;
}


uint32_t range_get_lower_limit(uint8_t device_base_address)
{
    uint32_t lowerLimit = 0;
    LOG_FUNCTION_START((void*)&device_base_address);

    LOG_FUNCTION_END(lowerLimit);

    return lowerLimit;
}