Digital Thermometer and Memory

DS1624.cpp

Committer:
mcm
Date:
2018-02-06
Revision:
4:61eb7429c086
Parent:
3:3a26cd3cd594

File content as of revision 4:61eb7429c086:

/**
 * @brief       DS1624.h
 * @details     Digital Thermometer and Memory.
 *              Function file.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018    The ORIGIN
 * @pre         NaN.
 * @warning     NaN
 * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
 */

#include "DS1624.h"


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


DS1624::~DS1624()
{
}



/**
 * @brief       DS1624_StartConvertTemperature ( void )
 *
 * @details     It triggers a new temperature conversion.
 *
 * @param[in]    N/A.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of DS1624_StartConvertTemperature.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         Temperature Conversion Time ( t_TC ) 200ms maximum.
 * @warning     N/A.
 */
DS1624::DS1624_status_t  DS1624::DS1624_StartConvertTemperature ( void )
{
    char     cmd       =   DS1624_START_CONVERT_T;
    uint32_t aux       =   0;


    // It triggers a new temperature conversion
    aux = _i2c.write ( _DS1624_Addr, &cmd, 1, false );




    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}


/**
 * @brief       DS1624_StopConvertTemperature ( void )
 *
 * @details     It halts the temperature conversion.
 *
 * @param[in]    N/A.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of DS1624_StopConvertTemperature.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         In continuous conversion mode, a StopConvertT command halt
 *              a continuous conversion. To restart, the StartConvertT
 *              command must be issued. In one-shot mode, a StartConvertT command
 *              must be issued for every temperature reading desired.
 * @warning     N/A.
 */
DS1624::DS1624_status_t  DS1624::DS1624_StopConvertTemperature ( void )
{
    char     cmd       =   DS1624_STOP_CONVERT_T;
    uint32_t aux       =   0;


    // It sends the command
    aux = _i2c.write ( _DS1624_Addr, &cmd, 1, false );




    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_ReadRawTemperature ( DS1624_vector_data_t* )
 *
 * @details     It reads the last raw temperature conversion result.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myRawTemperature:  Raw temperature ( two bytes ).
 *
 *
 * @return       Status of DS1624_ReadRawTemperature.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         DONE bit needs to be checked before calling this function.
 * @warning     N/A.
 */
DS1624::DS1624_status_t  DS1624::DS1624_ReadRawTemperature  ( DS1624_vector_data_t* myRawTemperature )
{
    char      cmd[]     =   { DS1624_READ_TEMPERATURE, 0 };
    uint32_t  aux       =   0;



    // It sends the command and gets the result otherwise
    aux      =   _i2c.write ( _DS1624_Addr, &cmd[0], 1, true );
    aux      =   _i2c.read  ( _DS1624_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );


    // Parse the data
    myRawTemperature->MSBTemperature     =   cmd[0];
    myRawTemperature->LSBTemperature     =   cmd[1];




    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_ReadTemperature ( DS1624_vector_data_t* )
 *
 * @details     It reads the last current temperature conversion result.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myTemperature:     Current temperature.
 *
 *
 * @return       Status of DS1624_ReadTemperature.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         This function updates the raw temperature variables.
 * @pre         DONE bit needs to be checked before calling this function.
 * @warning     N/A.
 */
DS1624::DS1624_status_t  DS1624::DS1624_ReadTemperature  ( DS1624_vector_data_t* myTemperature )
{
    char         cmd[]     =   { DS1624_READ_TEMPERATURE, 0 };
    uint32_t     aux       =   0;
    uint32_t     i         =   0;



    // It sends the command and gets the result otherwise
    aux      =   _i2c.write ( _DS1624_Addr, &cmd[0], 1, true );
    aux      =   _i2c.read  ( _DS1624_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );


    // Update the raw temperature value
    myTemperature->MSBTemperature     =   cmd[0];
    myTemperature->LSBTemperature     =   cmd[1];


    // Calculate the current temperature
    // Check if the temperature is positive or negative
    if ( ( myTemperature->MSBTemperature & MSB_TEMPERATURE_SIGN_BIT_MASK ) == MSB_TEMPERATURE_SIGN_BIT_NEGATIVE )
    {
    // The temperature is NEGATIVE
        myTemperature->MSBTemperature   -=   1;
        myTemperature->MSBTemperature    =  ~myTemperature->MSBTemperature;

        myTemperature->LSBTemperature   -=   1;
        myTemperature->LSBTemperature    =   ( ~myTemperature->LSBTemperature & 0xF0 );

        myTemperature->Temperature       =   ( -1.0 * myTemperature->MSBTemperature );
    }
    else
    {
    // The temperature is POSITIVE
        myTemperature->Temperature       =   myTemperature->MSBTemperature;
    }


    // Update the decimal value
    for ( i = 0; i < ( myTemperature->LSBTemperature >> 4 ); i++ )
            myTemperature->Temperature  +=   DS1624_TEMPERATURE_RESOLUTION;






    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_GetStatusRegister ( DS1624_vector_data_t* )
 *
 * @details     It reads the CONFIGURATION/STATUS register.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myStatusRegister:  Current Status register value.
 *
 *
 * @return       Status of DS1624_GetStatusRegister.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
DS1624::DS1624_status_t  DS1624::DS1624_GetStatusRegister   ( DS1624_vector_data_t* myStatusRegister )
{
    char         cmd     =   DS1624_ACCESS_CONFIG;
    uint32_t     aux     =   0;


    // It sends the command and gets the result
    aux = _i2c.write ( _DS1624_Addr, &cmd, 1, true );
    aux = _i2c.read  ( _DS1624_Addr, &myStatusRegister->Control_Status_Register, 1 );





    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_SetConversionMode ( DS1624_access_config_1shot_t )
 *
 * @details     It sets 1SHOT/Continuous temperature conversion mode.
 *
 * @param[in]    myConversionMode:  ACCESS_CONFIG_1SHOT_ONE_TEMPERATURE_CONVERSION:             1SHOT temperature conversion mode
 *                                  ACCESS_CONFIG_1SHOT_CONTINUOUSLY_TEMPERATURE_CONVERSION:    Continuous temperature conversion mode.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of DS1624_SetConversionMode.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         N/A
 * @warning     Since the configuration register is implemented in
 *              EEPROM, writes to the register require 10ms to complete.
 *              After issuing a command to write to the configuration register,
 *              no further accesses to the DS1624 should be made for at least 10ms.
 */
DS1624::DS1624_status_t  DS1624::DS1624_SetConversionMode   ( DS1624_access_config_1shot_t myConversionMode )
{
    char     cmd[]   =   { DS1624_ACCESS_CONFIG, 0 };
    uint32_t aux     =   0;


    // It sends the command and gets the result
    aux = _i2c.write ( _DS1624_Addr, &cmd[0], 1, true );
    aux = _i2c.read  ( _DS1624_Addr, &cmd[1], 1 );


    // Mask the bit and check which mode to use
    cmd[1] &= ~ACCESS_CONFIG_1SHOT_MASK;

    if ( myConversionMode == ACCESS_CONFIG_1SHOT_ONE_TEMPERATURE_CONVERSION )
    {
    // 1SHOT Mode
        cmd[1] |=   ACCESS_CONFIG_1SHOT_ONE_TEMPERATURE_CONVERSION;
    }
    else
    {
    // Continuously Mode
        cmd[1] &=  ~ACCESS_CONFIG_1SHOT_ONE_TEMPERATURE_CONVERSION;
    }


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




    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_IsTemperatureConversionDone ( DS1624_vector_data_t* )
 *
 * @details     It checks if a temperature conversion is done.
 *
 * @param[in]    N/A.
 *
 * @param[out]   myTemperatureConversionStatus:  Temperature conversion bit:
 *                                                  ACCESS_CONFIG_DONE_CONVERSION_COMPLETE
 *                                                  ACCESS_CONFIG_DONE_CONVERSION_IN_PROGRESS.
 *
 *
 * @return       Status of DS1624_IsTemperatureConversionDone.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         N/A.
 * @warning     N/A.
 */
DS1624::DS1624_status_t DS1624::DS1624_IsTemperatureConversionDone ( DS1624_access_config_done_t* myTemperatureConversionStatus )
{
    char     cmd[]     =   { DS1624_ACCESS_CONFIG, 0 };
    uint32_t aux       =   0;


    // It sends the command and gets the result
    aux = _i2c.write ( _DS1624_Addr, &cmd[0], 1, true );
    aux = _i2c.read  ( _DS1624_Addr, &cmd[1], 1 );


    // Update the value
    *myTemperatureConversionStatus   =   ( DS1624_access_config_done_t )( cmd[1] & ACCESS_CONFIG_DONE_MASK );



    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_ReadBytesEEPROM ( char , char* , uint8_t )
 *
 * @details     It reads a certain number of bytes from EEPROM memory.
 *
 * @param[in]    myStartingAddress:     Starting address to read the EEPROM memory.
 * @param[in]    myLength:              Amount of bytes to read.
 *
 * @param[out]   myReadBytesEEPROM:     Read values from EEPROM memory.
 *
 *
 * @return       Status of DS1624_ReadBytesEEPROM.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         N/A.
 * @warning     When the address pointer reaches the end of the 256-byte memory space ( address FFh )
 *              it increments from the end of the memory back to the first location of the memory
 *              ( address 00h ).
 */
DS1624::DS1624_status_t DS1624::DS1624_ReadBytesEEPROM ( char myStartingAddress, char* myReadBytesEEPROM, uint8_t myLength )
{
    char     cmd[]     =   { DS1624_ACCESS_MEMORY, 0 };
    uint32_t aux       =   0;



    // It sends the command, the address location and gets the result
    cmd[1]   =   myStartingAddress;
    aux = _i2c.write ( _DS1624_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), true );
    aux = _i2c.read  ( _DS1624_Addr, myReadBytesEEPROM, myLength );





    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}



/**
 * @brief       DS1624_WriteBytesEEPROM ( char , char , uint8_t )
 *
 * @details     It writes a certain number of bytes to EEPROM memory.
 *
 * @param[in]    myStartingAddress:     Starting address to write the EEPROM memory.
 * @param[in]    myWriteBytesEEPROM:    Bytes to write to the EEPROM memory.
 * @param[in]    myLength:              Amount of bytes to write.
 *
 * @param[out]   N/A.
 *
 *
 * @return       Status of DS1624_WriteBytesEEPROM.
 *
 *
 * @author      Manuel Caballero
 * @date        31/January/2018
 * @version     31/January/2018     The ORIGIN
 * @pre         N/A.
 * @warning     The STOP condition causes the DS1624 to initiate the write to EEPROM sequence.
 * @warning     If the starting address is 00 and the incoming data is 00 11 22 33 44 55 66 77 88 99,
 *              the result is mem00=88 mem01=99 mem02=22 mem03=33 mem04=44 mem05=55 mem06=66 mem07=77.
 *              The data wraps around and overwrites itself.
 * @warning     EEPROM Write Cycle Time: 50ms ( maximum ). The user must take care of this time!.
 */
DS1624::DS1624_status_t DS1624::DS1624_WriteBytesEEPROM ( char myStartingAddress, char myWriteBytesEEPROM[], uint8_t myLength )
{
    char     cmd[ myLength + 2 ];
    uint32_t i         =   0;
    uint32_t aux       =   0;


    // Prepare COMMANDS
    cmd[0]   =   DS1624_ACCESS_MEMORY;
    cmd[1]   =   myStartingAddress;

    // Prepare the payload to be stored into the EEPROM memory
    for ( i = 2 ; i < ( myLength + 2 ); i++ )
        cmd[ i ]       =   myWriteBytesEEPROM[ i - 2 ];
        
    // It sends the command, the address location as well as the payload
    aux = _i2c.write ( _DS1624_Addr, &cmd[0], myLength + 2, false );




    if ( aux == I2C_SUCCESS )
        return   DS1624_SUCCESS;
    else
        return   DS1624_FAILURE;
}