Infrared Thermopile Sensor in Chip-Scale Package
AMG8833.cpp
- Committer:
- mcm
- Date:
- 2019-01-22
- Revision:
- 4:d3c9c6df14a8
- Parent:
- 2:4c2811c6faa1
File content as of revision 4:d3c9c6df14a8:
/** * @brief AMG8833.c * @details Infrared Thermopile Sensor in Chip-Scale Package. * Functions file. * * * @return N/A * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ). All rights reserved. */ #include "AMG8833.h" AMG8833::AMG8833 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq ) : _i2c ( sda, scl ) , _AMG8833_Addr ( addr ) { _i2c.frequency( freq ); } AMG8833::~AMG8833() { } /** * @brief AMG8833_GetOperationMode ( AMG8833_data_t* ) * * @details It reads the operation mode ( power control register ). * * @param[in] N/A. * * @param[out] myOperationMode: Current operation mode. * * * @return Status of AMG8833_GetOperationMode. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetOperationMode ( AMG8833_data_t* myOperationMode ) { char cmd = 0U; uint32_t aux; /* Read the register */ cmd = AMG8833_PCTL; aux = _i2c.write ( _AMG8833_Addr, &cmd, 1U, true ); aux = _i2c.read ( _AMG8833_Addr, &cmd, 1U ); /* Parse data */ myOperationMode->operationMode = (AMG8833_pctl_t)cmd; if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetOperationMode ( AMG8833_data_t* ) * * @details It sets the operation mode ( power control register ). * * @param[in] myOperationMode: Operation mode. * * @param[out] N/A. * * * @return Status of AMG8833_SetOperationMode. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetOperationMode ( AMG8833_data_t myOperationMode ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_PCTL; cmd[1] = myOperationMode.operationMode; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SoftwareReset ( AMG8833_rst_t ) * * @details It sets the reset mode. * * @param[in] mySoftwareReset: Reset mode. * * @param[out] N/A. * * * @return Status of AMG8833_SoftwareReset. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SoftwareReset ( AMG8833_rst_t mySoftwareReset ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_RST; cmd[1] = mySoftwareReset; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetFrameMode ( AMG8833_fpsc_t ) * * @details It sets frame mode. * * @param[in] myFrameMode: Frame mode. * * @param[out] N/A. * * * @return Status of AMG8833_SetFrameMode. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetFrameMode ( AMG8833_fpsc_t myFrameMode ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_FPSC; cmd[1] = myFrameMode; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetInterruptFunctionMode ( AMG8833_intmod_t , AMG8833_inten_t ) * * @details It sets interrupt function mode. * * @param[in] myInterruptMode: Interrupt mode. * @param[in] myInterruptOutput: Interrupt output mode. * * @param[out] N/A. * * * @return Status of AMG8833_SetInterruptFunctionMode. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetInterruptFunctionMode ( AMG8833_intmod_t myInterruptMode, AMG8833_inten_t myInterruptOutput ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_INTC; cmd[1] = ( myInterruptMode | myInterruptOutput ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetStatusRegisterValue ( uint8_t* ) * * @details It gets the status register value. * * @param[in] N/A. * * @param[out] myStatusRegisterValue: Current status register value. * * * @return Status of AMG8833_GetStatusRegisterValue. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetStatusRegisterValue ( uint8_t* myStatusRegisterValue ) { char cmd = 0U; uint32_t aux; /* Update the register */ cmd = AMG8833_STAT; aux = _i2c.write ( _AMG8833_Addr, &cmd, 1U, true ); aux = _i2c.read ( _AMG8833_Addr, &cmd, 1U ); /* Parse data */ *myStatusRegisterValue = cmd; if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_ClearFlags ( uint8_t ) * * @details It clears overflow and/or interrupt flags. * * @param[in] myFlagsToBeCleared: OVT_CLR_THERMISTOR_TEMPERATURE_OVERFLOW_CLEAR_FLAG and/or * OVS_CLR_TEMPERATURE_OVERFLOW_CLEAR_FLAG and/or * INTCLR_INTERRUPT_OUTBREAK_CLEAR_FLAG. * * @param[out] N/A. * * * @return Status of AMG8833_ClearFlags. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_ClearFlags ( uint8_t myFlagsToBeCleared ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_SCLR; cmd[1] = myFlagsToBeCleared; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetAverageOutputMode ( AMG8833_mamod_t ) * * @details It sets twice moving average output mode. * * @param[in] myAverageOutputMode: Average output mode. * * @param[out] N/A. * * * @return Status of AMG8833_SetAverageOutputMode. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetAverageOutputMode ( AMG8833_mamod_t myAverageOutputMode ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Update the register */ cmd[0] = AMG8833_AVE; cmd[1] = myAverageOutputMode; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetInterruptLevel ( int16_t , int16_t ) * * @details It sets interrupt level upper/lower limit. * * @param[in] myUpperLimit: Interrupt Level upper limit. * @param[in] myLowerLimit: Interrupt Level loweer limit. * * @param[out] N/A. * * * @return Status of AMG8833_SetInterruptLevel. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetInterruptLevel ( int16_t myUpperLimit, int16_t myLowerLimit ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* 12 bit resolution ( 11 bit + sign ) only */ if ( ( ( myUpperLimit < -4095 ) || ( myUpperLimit > 4095 ) ) || ( ( myLowerLimit < -4095 ) || ( myLowerLimit > 4095 ) ) ) { return AMG8833_FAILURE; } else { /* Update upper limit */ /* Update the register: INTHL */ cmd[0] = AMG8833_INTHL; cmd[1] = (uint8_t)( myUpperLimit & 0x00FF ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); /* Update the register: INTHH */ cmd[0] = AMG8833_INTHH; cmd[1] = (uint8_t)( ( myUpperLimit >> 8U ) & LIMIT_HYSTERESIS_INTHH_MASK ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); /* Update lower limit */ /* Update the register: INTLL */ cmd[0] = AMG8833_INTLL; cmd[1] = (uint8_t)( myLowerLimit & 0x00FF ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); /* Update the register: INTLL */ cmd[0] = AMG8833_INTLH; cmd[1] = (uint8_t)( ( myLowerLimit >> 8U ) & LIMIT_HYSTERESIS_INTLH_MASK ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); } if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_SetHysteresisLevel ( int16_t ) * * @details It sets interrupt hysteresis level when interrupt is generated. * * @param[in] myHysteresisLimit: Interrupt Hysteresis Level when Interrupt is generated. * * @param[out] N/A. * * * @return Status of AMG8833_SetHysteresisLevel. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_SetHysteresisLevel ( int16_t myHysteresisLimit ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* 12 bit resolution ( 11 bit + sign ) only */ if ( ( myHysteresisLimit < -4095 ) || ( myHysteresisLimit > 4095) ) { return AMG8833_FAILURE; } else { /* Hysteresis: Update the register: IHYSL */ cmd[0] = AMG8833_IHYSL; cmd[1] = (uint8_t)( myHysteresisLimit & 0x00FF ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); /* Hysteresis: Update the register: IHYSH */ cmd[0] = AMG8833_IHYSH; cmd[1] = (uint8_t)( ( myHysteresisLimit >> 8U ) & LIMIT_HYSTERESIS_IHYSH_MASK ); aux = _i2c.write ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); } if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetThermistorRawData ( AMG8833_data_t* ) * * @details It gets thermistor raw temperature data. * * @param[in] N/A. * * @param[out] myThermistorRawData: Thermistor raw temperature data. * * * @return Status of AMG8833_GetThermistorRawData. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetThermistorRawData ( AMG8833_data_t* myThermistorRawData ) { char cmd[2] = { 0U }; uint32_t aux; /* Read the register */ cmd[0] = AMG8833_TTHL; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse the data */ myThermistorRawData->termistorOutputRawValue = cmd[1]; myThermistorRawData->termistorOutputRawValue <<= 8U; myThermistorRawData->termistorOutputRawValue |= cmd[0]; if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetThermistorValue ( AMG8833_data_t* ) * * @details It gets thermistor temperature data. * * @param[in] N/A. * * @param[out] myThermistorValue: Thermistor temperature data. * * * @return Status of AMG8833_GetThermistorValue. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetThermistorValue ( AMG8833_data_t* myThermistorValue ) { float mySign = 0.0; AMG8833::AMG8833_status_t aux; /* Get thermistor raw temperature data */ aux = AMG8833::AMG8833_GetThermistorRawData ( myThermistorValue ); /* Check if the temperature is negative */ if ( ( myThermistorValue->termistorOutputRawValue & 0x800 ) == 0x800 ) { myThermistorValue->termistorOutputRawValue &= 0x800; mySign = -1.0; } else { mySign = 1.0; } /* Parse the data */ myThermistorValue->termistorOutputValue = ( mySign ) * ( (float)( myThermistorValue->termistorOutputRawValue * THERMISTOR_RESOLUTION ) ); if ( aux == AMG8833_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetPixelInterruptTable ( AMG8833_data_t* ) * * @details It gets pixel interrupt table. * * @param[in] N/A. * * @param[out] myPixelInterruptTable: Pixel interrupt table. * * * @return Status of AMG8833_GetPixelInterruptTable. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetPixelInterruptTable ( AMG8833_data_t* myPixelInterruptTable ) { char cmd = 0U; uint32_t aux; /* Get pixel interrupt table */ cmd = AMG8833_INT0; aux = _i2c.write ( _AMG8833_Addr, &cmd, 1U, true ); aux = _i2c.read ( _AMG8833_Addr, (char*)&myPixelInterruptTable->pixelInterruptTable[0], 64U ); if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetPixelRawTemperatures ( AMG8833_data_t* ) * * @details It gets pixel raw temperature data. * * @param[in] N/A. * * @param[out] myPixelRawTemperatureData: Pixel raw temperature data. * * * @return Status of AMG8833_GetPixelRawTemperatures. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetPixelRawTemperatures ( AMG8833_data_t* myPixelRawTemperatureData ) { char cmd[128] = { 0U }; uint8_t i = 0U; uint32_t aux; /* Get pixel raw temperature value */ cmd[0] = AMG8833_T01L; aux = _i2c.write ( _AMG8833_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _AMG8833_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); for ( i = 0U; i < ( 64U ); i++ ) { myPixelRawTemperatureData->pixelOutputRawValues[i] = cmd[( i << 1U ) + 1U]; myPixelRawTemperatureData->pixelOutputRawValues[i] <<= 8U; myPixelRawTemperatureData->pixelOutputRawValues[i] |= cmd[( i << 1U )]; } if ( aux == I2C_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } } /** * @brief AMG8833_GetPixelTemperatures ( AMG8833_data_t* ) * * @details It gets pixel temperature value in Celsius degrees. * * @param[in] N/A. * * @param[out] myPixelTemperatureData: Pixel temperature data. * * * @return Status of AMG8833_GetPixelTemperatures. * * * @author Manuel Caballero * @date 11/January/2019 * @version 11/January/2019 The ORIGIN * @pre N/A. * @warning N/A. */ AMG8833::AMG8833_status_t AMG8833::AMG8833_GetPixelTemperatures ( AMG8833_data_t* myPixelTemperatureData ) { uint8_t i = 0U; float mySign = 0.0; AMG8833::AMG8833_status_t aux; /* Get pixel raw temperature data */ aux = AMG8833::AMG8833_GetPixelRawTemperatures ( myPixelTemperatureData ); /* Parse the data */ for ( i = 0U; i < 64U; i++ ) { /* Check if the temperature is negative */ if ( ( myPixelTemperatureData->pixelOutputRawValues[i] & 0x800 ) == 0x800 ) { myPixelTemperatureData->pixelOutputRawValues[i] = ~myPixelTemperatureData->pixelOutputRawValues[i]; myPixelTemperatureData->pixelOutputRawValues[i] += 1U; mySign = -1.0; } else { mySign = 1.0; } /* Parse the data */ myPixelTemperatureData->pixelOutputValues[i] = ( mySign ) * ( (float)( myPixelTemperatureData->pixelOutputRawValues[i] * TEMPERATURE_RESOLUTION ) ); } if ( aux == AMG8833_SUCCESS ) { return AMG8833_SUCCESS; } else { return AMG8833_FAILURE; } }