Industry's Lowest-Power Ambient Light Sensor with ADC

Dependents:   FYPhh FYPhh5 FYPhh5ultrafinal FYPhh5ultrafinal

MAX44009.cpp

Committer:
mcm
Date:
2018-09-17
Revision:
3:13e5af215b11
Parent:
2:08d850dd1cb8

File content as of revision 3:13e5af215b11:

/**
 * @brief       MAX44009.cpp
 * @details     Industry's Lowest-Power Ambient Light Sensor with ADC.
 *              Functions file.
 *
 *
 * @return      N/A
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018    The ORIGIN
 * @pre         N/A
 * @warning     N/A
 * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
 */

#include "MAX44009.h"


MAX44009::MAX44009 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
    : _i2c            ( sda, scl )
    , _MAX44009_Addr  ( addr )
{
    _i2c.frequency( freq );
}


MAX44009::~MAX44009()
{
}



/**
 * @brief       MAX44009_ReadInterruptStatus ( MAX44009_vector_data_t* )
 *
 * @details     It gets the interrupt status value.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myInterruptStatus:     Interrupt status register.
 *
 *
 * @return       Status of MAX44009_ReadInterruptStatus.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_ReadInterruptStatus ( MAX44009_vector_data_t* myInterruptStatus )
{
    char     cmd    =    0U;
    uint32_t aux;


    /* Read INTERRUPT STATUS register    */
    cmd      =   MAX44009_INTERRUPT_STATUS;
    aux      =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux      =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );


    /* Parse data   */
    myInterruptStatus->interruptStatus   =   (MAX44009_interrupt_status_ints_t)( cmd & INTERRUPT_STATUS_INTS_MASK );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_InterrupEnable ( MAX44009_interrupt_enable_ints_t )
 *
 * @details     It enables/disables the interrupt.
 *
 * @param[in]    myInterruptEnable      Enable/Disable the interrupt.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of MAX44009_InterrupEnable.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_InterrupEnable ( MAX44009_interrupt_enable_ints_t myInterruptEnable )
{
    char     cmd[]    =  { 0U, 0U };
    uint32_t aux;


    /* Update the register   */
    cmd[0]   =   MAX44009_INTERRUPT_ENABLE;
    cmd[1]   =   myInterruptEnable;
    aux      =   _i2c.write ( _MAX44009_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_Configuration ( MAX44009_configuration_cont_t , MAX44009_configuration_manual_t , MAX44009_configuration_cdr_t , MAX44009_configuration_tim_t )
 *
 * @details     It configures the device.
 *
 * @param[in]    myContinuousMode:  Default/Continuous mode.
 * @param[in]    myManualMode:      Default/Manual mode.
 * @param[in]    myCurrentRatio:    Current division ratio.
 * @param[in]    myIntegrationTime: Integration time.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of MAX44009_Configuration.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         In automatic mode ( MANUAL = 0 ), reading the contents of TIM<2:0> and CDR bits reflects the automatically generated values from an internal timing register and are read-only.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_Configuration ( MAX44009_configuration_cont_t myContinuousMode, MAX44009_configuration_manual_t myManualMode,
                                                                MAX44009_configuration_cdr_t myCurrentRatio, MAX44009_configuration_tim_t myIntegrationTime )
{
    char     cmd[]    =  { 0U, 0U };
    uint32_t aux;


    /* Update the register   */
    cmd[0]   =   MAX44009_CONFIGURATION;

    /* In automatic mode ( MANUAL = 0 ), reading the contents of TIM<2:0> and CDR bits reflects the automatically generated values from an internal timing register and are read-only  */
    if ( myManualMode == CONFIGURATION_MANUAL_MANUAL_MODE )
    {
        cmd[1]   =   ( myContinuousMode | myManualMode | myCurrentRatio | myIntegrationTime );
    }
    else
    {
        cmd[1]   =   ( myContinuousMode | myManualMode );
    }

    /* Update the register   */
    aux      =   _i2c.write ( _MAX44009_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetCurrentDivisionRatio ( MAX44009_vector_data_t* )
 *
 * @details     It gets the current division ratio.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myCDR:             Current Division Ratio value
 *
 *
 * @return       Status of MAX44009_GetCurrentDivisionRatio.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetCurrentDivisionRatio ( MAX44009_vector_data_t* myCDR )
{
    char     cmd    =   0U;
    uint32_t aux;


    /* Read the CONFIGURATION register   */
    cmd  =   MAX44009_CONFIGURATION;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );

    /* Parse the data    */
    myCDR->cdr   =   (MAX44009_configuration_cdr_t)( cmd & CONFIGURATION_CDR_MASK );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetIntegrationTime ( MAX44009_vector_data_t* )
 *
 * @details     It gets the integration time.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myTIM:             Integration Time value
 *
 *
 * @return       Status of MAX44009_GetIntegrationTime.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetIntegrationTime ( MAX44009_vector_data_t* myTIM )
{
    char     cmd    =   0U;
    uint32_t aux;


    /* Read the CONFIGURATION register   */
    cmd  =   MAX44009_CONFIGURATION;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );

    /* Parse the data    */
    myTIM->tim   =   (MAX44009_configuration_tim_t)( cmd & CONFIGURATION_TIM_MASK );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetLux ( MAX44009_device_resolution_t , MAX44009_vector_data_t* )
 *
 * @details     It gets the Lux value regarding of the resolution.
 *
 * @param[in]    myResolution:      Resolution.
 *
 * @param[out]   myLux:             Lux value
 *
 *
 * @return       Status of MAX44009_GetLux.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetLux ( MAX44009_device_resolution_t myResolution, MAX44009_vector_data_t* myLux )
{
    char     cmd        =   0U;
    uint8_t  exponent   =   0U;
    uint8_t  mantissa   =   0U;
    float    mulFactor  =   0.0f;
    uint32_t aux;


    /* Read the LUX HIGH BYTE register   */
    cmd  =   MAX44009_LUX_HIGH_BYTE;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );


    /* Check the resolution  */
    exponent   =   ( cmd & LUX_HIGH_BYTE_EXPONENT_MASK );
    exponent >>=   4U;
    mantissa   =   ( cmd & LUX_HIGH_BYTE_MANTISSA_MASK );
    if ( myResolution == RESOLUTION_NORMAL_RESOLUTION )
    {
        mulFactor  =   0.72f;
    }
    else
    {
        cmd  =   MAX44009_LUX_LOW_BYTE;
        aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
        aux  =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );

        mantissa    <<=  4U;
        mantissa     |=  ( cmd & LUX_LOW_BYTE_MANTISSA_MASK );

        mulFactor     =   0.045f;
    }


    /* Calculate the Lux value   */
    myLux->lux   =   (float)( pow( 2.0, exponent ) * mantissa * mulFactor );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_SetUpperThreshold ( MAX44009_vector_data_t )
 *
 * @details     It sets the upper threshold high-byte.
 *
 * @param[in]    myUpperThreshold:  Upper threshold Lux value.
 *
 * @param[out]   N/A
 *
 *
 * @return       Status of MAX44009_SetUpperThreshold.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The Upper Threshold High-Byte register exponent with the four most significant bits of the mantissa sets the upper trip
 *              level for interrupt functionality.
 *
 *              Upper lux threshold = 2^( exponent ) x mantissa x 0.045
 *
 *              exponent: BITS<7:4>, mantissa: BITS<3:0>
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_SetUpperThreshold ( MAX44009_vector_data_t myUpperThreshold )
{
    char     cmd[]   =   { 0U, 0U };
    uint32_t aux;


    /* Update the register value   */
    cmd[0]  =   MAX44009_UPPER_THRESHOLD_HIGH_BYTE;
    cmd[1]  =   myUpperThreshold.lux_upper_threshold;
    aux     =   _i2c.write ( _MAX44009_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_SetLowerThreshold ( MAX44009_vector_data_t )
 *
 * @details     It sets the lower threshold high-byte.
 *
 * @param[in]    myLowerThreshold:  Lower threshold Lux value.
 *
 * @param[out]   N/A
 *
 *
 * @return       Status of MAX44009_SetLowerThreshold.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The Lower Threshold High-Byte register exponent with the four most significant bits of the mantissa sets the lower trip
 *              level for interrupt functionality.
 *
 *              Lower lux threshold = 2^( exponent ) x mantissa x 0.045
 *
 *              exponent: BITS<7:4>, mantissa: BITS<3:0>
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_SetLowerThreshold ( MAX44009_vector_data_t myLowerThreshold )
{
    char     cmd[]   =   { 0U, 0U };
    uint32_t aux;


    /* Update the register value   */
    cmd[0]  =   MAX44009_LOWER_THRESHOLD_HIGH_BYTE;
    cmd[1]  =   myLowerThreshold.lux_lower_threshold;
    aux     =   _i2c.write ( _MAX44009_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetUpperThreshold ( MAX44009_vector_data_t* )
 *
 * @details     It gets the upper threshold high-byte.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myUpperThreshold:  Upper threshold raw data
 *
 *
 * @return       Status of MAX44009_GetUpperThreshold.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The Upper Threshold High-Byte register exponent with the four most significant bits of the mantissa sets the upper trip
 *              level for interrupt functionality.
 *
 *              Upper lux threshold = 2^( exponent ) x mantissa x 0.045
 *
 *              exponent: BITS<7:4>, mantissa: BITS<3:0>
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetUpperThreshold ( MAX44009_vector_data_t* myUpperThreshold )
{
    char     cmd   =   0U;
    uint32_t aux;


    /* Get the register value  */
    cmd  =   MAX44009_UPPER_THRESHOLD_HIGH_BYTE;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, (char*)&myUpperThreshold->lux_upper_threshold, 1U );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetLowerThreshold ( MAX44009_vector_data_t* )
 *
 * @details     It gets the lower threshold high-byte.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myLowerThreshold:  Lower threshold raw data
 *
 *
 * @return       Status of MAX44009_GetLowerThreshold.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The Lower Threshold High-Byte register exponent with the four most significant bits of the mantissa sets the lower trip
 *              level for interrupt functionality.
 *
 *              Lower lux threshold = 2^( exponent ) x mantissa x 0.045
 *
 *              exponent: BITS<7:4>, mantissa: BITS<3:0>
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetLowerThreshold ( MAX44009_vector_data_t* myLowerThreshold )
{
    char     cmd   =   0U;
    uint32_t aux;


    /* Get the register value  */
    cmd  =   MAX44009_LOWER_THRESHOLD_HIGH_BYTE;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, (char*)&myLowerThreshold->lux_lower_threshold, 1U );



    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_SetThresholdTimer ( MAX44009_vector_data_t )
 *
 * @details     It sets the threshold timer register.
 *
 * @param[in]    myThresholdTimer_us:   Time delay in us.
 *
 * @param[out]   N/A
 *
 *
 * @return       Status of MAX44009_SetThresholdTimer.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The value in this register sets the time used to control this delay
 *
 *              Time delay = ( 128xT7 + 64xT6 + 32xT5 + 16xT4 + 8xT3 + 4xT2 + 2xT1 + T0 ) x 100ms
 *
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_SetThresholdTimer ( MAX44009_vector_data_t myThresholdTimer_us )
{
    char     cmd[]   =   { 0U, 0U };
    uint32_t aux;


    /* Maximum delay is 25.5ms   */
    if ( myThresholdTimer_us.threshold_timer_us > 25500U )
    {
        return   MAX44009_FAILURE;
    }


    /* Update the register value  */
    cmd[0]  =   MAX44009_THRESHOLD_TIMER;
    cmd[1]  =   ( myThresholdTimer_us.threshold_timer_us / 100U );
    aux     =   _i2c.write ( _MAX44009_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}



/**
 * @brief       MAX44009_GetThresholdTimer ( MAX44009_vector_data_t* )
 *
 * @details     It gets the threshold timer register.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myThresholdTimer_us:   Time delay in us.
 *
 *
 * @return       Status of MAX44009_GetThresholdTimer.
 *
 *
 * @author      Manuel Caballero
 * @date        17/September/2018
 * @version     17/September/2018   The ORIGIN
 * @pre         The value in this register gets the time used to control this delay
 *
 *              Time delay = ( 128xT7 + 64xT6 + 32xT5 + 16xT4 + 8xT3 + 4xT2 + 2xT1 + T0 ) x 100ms
 *
 * @warning     N/A.
 */
MAX44009::MAX44009_status_t  MAX44009::MAX44009_GetThresholdTimer ( MAX44009_vector_data_t* myThresholdTimer_us )
{
    char     cmd   =   0U;
    uint32_t aux;


    /* Get the register value  */
    cmd  =   MAX44009_THRESHOLD_TIMER;
    aux  =   _i2c.write ( _MAX44009_Addr, &cmd, 1U, true );
    aux  =   _i2c.read  ( _MAX44009_Addr, &cmd, 1U );


    /* Parse the data    */
    myThresholdTimer_us->threshold_timer_us  =   ( (uint16_t)cmd * 100U );




    if ( aux == I2C_SUCCESS )
    {
        return   MAX44009_SUCCESS;
    }
    else
    {
        return   MAX44009_FAILURE;
    }
}