LM77 Temperature sensor with I2C interface. Provides temperature in celsius and fahrenheit. The device also supports temperature alerts.

Dependents:   mbed_HP03SA_LM77

LM77.h

Committer:
wim
Date:
2015-01-10
Revision:
0:8e812deb9f66

File content as of revision 0:8e812deb9f66:

/* mbed LM77 Library, for an I2C Temperature sensor
 * Copyright (c) 2015, v01: WH, Initial version
 * 
 * The LM77 is a digital temperature sensor and thermal window comparator with an I2C Serial Bus interface. 
 * The open-drain Interrupt (INT) output becomes active whenever temperature goes outside a programmable window,
 * while a separate Critical Temperature Alarm (T_CRIT_A) output becomes active when the temperature exceeds a 
 * programmable critical limit. The INT output can operate in either a comparator or event mode, while the T_CRIT_A 
 * output operates in comparator mode only. The host can program both the upper and lower limits of the window as 
 * well as the critical temperature limit. Programmable hysterisis as well as a fault queue are available to minimize 
 * false tripping. Two pins (A0, A1) are available for address selection. The sensor powers up with default thresholds 
 * of 2°C THYST, 10°C TLOW, 64°C THIGH, and 80°C T_CRIT.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef MBED_LM77_H
#define MBED_LM77_H

#include "mbed.h"

/** An interface for the LM77 I2C temperature sensor
 *
 * @code
 * #include "mbed.h"
 * #include "LM77.h"
 * 
 * // I2C Communication
 * I2C i2c(p28,p27); // SDA, SCL
 *
 * // Serial Communication*
 * Serial pc(USBTX,USBRX);
 *
 * //Create an LM77 object at the default address (LM77_SA0)
 * LM77 sensor(&i2c);
 *
 * int main() {
 *   pc.printf("Hello World!\n");
 *   if (lm77.getStatus()) {
 *     pc.printf("LM77 status = Ok\n\r");   
 *
 *     pc.printf("Critical Alert temperature from LM77 is %.1f [C]\r\n", lm77.getCritAlertTemp());     
 *     pc.printf("Low Alert temperature from LM77 is %.1f [C]\r\n", lm77.getLowAlertTemp());     
 *     pc.printf("High Alert temperature from LM77 is %.1f [C]\r\n", lm77.getHighAlertTemp());             
 *     pc.printf("Alert Hysteresis from LM77 is %.1f [C]\r\n", lm77.getAlertHyst());  
 *     wait(1.0);
 *
 *#define CA          95.0f     
 *#define LA           8.0f     
 *#define HA          15.0f     
 *#define HY           3.0f     
 *     lm77.setCritAlertTemp(CA);     
 *     lm77.setLowAlertTemp(LA);         
 *     lm77.setHighAlertTemp(HA);
 *     lm77.setAlertHyst(HY);             
 * 
 *     while(1) {
 *
 *       // Show Temperature LM77
 *       //pc.printf("Ambient temperature from LM77 is %.1f [C]\r\n", (float) lm77.getTemperatureInt() / 10.0f);       
 *       pc.printf("Ambient temperature from LM77 is %.1f [C]\r\n", lm77.getTemperature());     
 *       wait(1.0);
 *     } // while
 *   }
 *   else {
 *       pc.printf("LM77 status = not Ok\n\r");            
 *   } //if
 * }
 * @endcode
 */

// Device I2C Slave addresses
#define LM77_SA0    0x90
#define LM77_SA1    0x92
#define LM77_SA2    0x94
#define LM77_SA3    0x96

//I2C register addresses
#define LM77_REG_TEMP    0x00
#define LM77_REG_CONF    0x01
#define LM77_REG_THYST   0x02
#define LM77_REG_TCRIT   0x03
#define LM77_REG_TLOW    0x04
#define LM77_REG_THIGH   0x05

//Temp Register
#define LM77_FLAG_LOW    0x01
#define LM77_FLAG_HIGH   0x02
#define LM77_FLAG_CRIT   0x04

#define LM77_FLAG_MSK    0x07

//Config Register
#define LM77_PWR_ON      0x00
#define LM77_PWR_DWN     0x01
#define LM77_INT_CMP     0x00
#define LM77_INT_EVENT   0x02
#define LM77_POL_TCRIT_L 0x00
#define LM77_POL_TCRIT_H 0x04
#define LM77_POL_INT_L   0x00
#define LM77_POL_INT_H   0x08
#define LM77_FQU_1       0x00
#define LM77_FQU_4       0x10

#define LM77_PWR_MSK       0x01
#define LM77_INT_MSK       0x02
#define LM77_POL_TCRIT_MSK 0x04
#define LM77_POL_INT_MSK   0x08
#define LM77_FQU_MSK       0x10

/** Create an LM77 Class instance
 *
 */ 
class LM77 {

public:
   
    /** Represents the power mode of the LM77
     */
    enum PowerMode {
        POWER_NORMAL,   /**< Chip is enabled and samples every 100ms */
        POWER_SHUTDOWN  /**< Chip is in low-power shutdown mode */
    };

    /** Represents INT pin mode of the LM77
     */
    enum IntMode {
        INT_COMPARATOR,  /**< INT pin asserted when temp exceeds an alert threshold, and de-asserted when temp crosses alert hysteresis threshold or when LM77 is read. It will be re-asserted when condition is still true after reading. */
        INT_EVENT        /**< INT pin asserted when temp reaches an alert threshold or threshold +/- hysteris and only de-asserted when a register has been read. It will be re-asserted when next event occurs. */
    };

    /** Represents Pin polarity of the LM77
     */
    enum PinPolarity {
        ACTIVE_LOW,     /**< Pin is a logic low when asserted, and a logic high when de-asserted */
        ACTIVE_HIGH     /**< Pin is a logic high when asserted, and a logic low when de-asserted */
    };

    /** Represents OS pin fault queue length of the LM77
     */
    enum FaultQueue {
        FAULT_QUEUE_1,   /**< Pins and flags are asserted after 1 fault */
        FAULT_QUEUE_4,   /**< Pins and flags are asserted after 4 consecutive faults */
    };


   /** Create an LM77 device instance
     *
     * @param i2c    I2C Bus 
     * @param char deviceAddress I2C slaveaddress (defaults to LM77_SA0).
     */ 
    LM77(I2C *i2c, char deviceAddress = LM77_SA0);


   /** Get the current power mode of the LM77
     *
     * @returns The current power mode as a PowerMode enum.
     */
    LM77::PowerMode getPowerMode();

   /** Set the power mode of the LM77
     *
     * @param mode The new power mode as a PowerMode enum.
     */
    void setPowerMode(PowerMode mode);

   /** Get the current INT pin mode of the LM77
     * Reset value is INT_COMPARATOR            
     *
     * @returns The current INT pin mode as an IntMode enum.
     */
    LM77::IntMode getIntMode();

   /** Set the INT pin mode of the LM77
     *
     * @param mode The new INT pin mode as an IntMode enum.
     */
    void setIntMode(IntMode mode);

   /** Get the current INT pin polarity of the LM77
     * Reset value is ACTIVE_LOW            
     *
     * @returns The current INT pin polarity as an PinPolarity enum.
     */
    LM77::PinPolarity getIntPolarity();

   /** Set the INT pin polarity of the LM77
     *
     * @param polarity The new INT pin polarity as an PinPolarity enum.
     */
    void setIntPolarity(PinPolarity polarity);

   /** Get the current T_CRIT_A pin polarity of the LM77
     * Reset value is ACTIVE_LOW            
     *
     * @returns The current T_CRIT_A pin polarity as an PinPolarity enum.
     */
    LM77::PinPolarity getTCritPolarity();

   /** Set the T_CRIT_A pin polarity of the LM77
     *
     * @param polarity The new T_CRIT_A pin polarity as an PinPolarity enum.
     */
    void setTCritPolarity(PinPolarity polarity);


   /** Get the current pin and flag fault queue length of the LM77
     * Reset value is FAULT_QUEUE_1, Pins and flags are asserted after 1 fault
     *
     * @returns The current pin and flag fault queue length as an FaultQueue enum.
     */
    LM77::FaultQueue getFaultQueue();

   /** Set the pin and flag fault queue length of the LM77
     *
     * @param queue The new pin and flag fault queue length as an FaultQueue enum.
     */
    void setFaultQueue(FaultQueue queue);

   /** Get the current critical alert temperature threshold of the LM77
     * Reset value is 80.0 °C.      
     *
     * @returns The current crtitcal alert temperature threshold in °C.
     */
    float getCritAlertTemp();

   /** Set the Critical alert temperature threshold of the LM77
     * Reset value is 80.0 °C.   
     *
     * @param temp The new Critical alert temperature threshold in °C.
     */
    void setCritAlertTemp(float temp);


   /** Get the current Low temperature alert threshold of the LM77
     * Reset value is 10.0 °C.      
     *
     * @returns The current Low temperature alert threshold in °C.
     */
    float getLowAlertTemp();

   /** Set the current Low temperature alert threshold of the LM77
     * Reset value is 10.0 °C.      
     *
     * @param temp The new Low alert temperature threshold in °C.
     */
    void setLowAlertTemp(float temp);

    
   /** Get the current High temperature alert threshold of the LM77
     * Reset value is 64.0 °C.      
     *
     * @returns The current High temperature alert threshold in °C.
     */
    float getHighAlertTemp();
    
   /** Set the High temperature alert threshold of the LM77
     * Reset value is 64.0 °C.   
     *
     * @param temp The new High temperature alert threshold in °C.
     */
    void setHighAlertTemp(float temp);


   /** Get the current alert temperature hysteresis of the LM77
     * Reset value is 2.0 °C.   
     *
     * @returns The current alert temperature hysteresis in °C.
     */
    float getAlertHyst();

   /** Set the alert temperature hysteresis of the LM77
     * Reset value is 2.0 °C.
     *
     * @param temp The new alert temperature hysteris in °C.
     */
    void setAlertHyst(float temp);

   /** Get Temperature as Int in °Celsius x 10
     *
     * @return int Temperature in °Celsius x 10
     */ 
    int getTemperatureInt(void);
    
   /** Get Temperature as float in °Celsius
     *
     * @return float Temperature in °Celsius
     */ 
    float getTemperature(void);

   /** Get the Alert flags of the LM77
     *
     * @returns The current Alert flags as int.
     */
    int getAlertFlags(void);


#ifdef MBED_OPERATORS
    /** A shorthand for Temperature()
     *
     * @returns The current temperature measurement in °C.
     */
    operator float();
#endif

   /** Convert Temperature from °Celsius into °Fahrenheit
     *
     * @param  float celsius in °Celsius  
     * @return float temperature in °Fahrenheit
     */ 
    float celsiusToFahrenheit(float celsius);


   /** Get Status
     *
     * @return bool Sensor ready 
    */ 
    bool getStatus(void);
    
private:
    //Member variables
    I2C* _i2c;
    char _slaveAddress;    

    //Member methods
   /** Read 8 bit value from register
     *
     * @param reg Index of register
     * @return data value from register
     */       
    char _readReg8(char reg);

   /** Write 8 bit value to register
     *
     * @param reg Index of register
     * @param data value to write
     */     
    void _writeReg8(char reg, char data);

   /** Read 16 bit value from register
     * Used for Critical temp threshold, Low and High temp threshold window and Hysteresis
     *
     * @param reg Index of register
     * @return data value from register  
     */     
    int16_t _readReg16(char reg);
    
   /** Write 16 bit value to register
     * Used for Critical temp threshold, Low and High temp threshold window and Hysteresis
     *
     * @param reg Index of register
     * @param data value to write
     */         
    void _writeReg16(char, int16_t data);

   /** Get Temperature as float in °Celsius
     * Used for Critical temp threshold, Low and High temp threshold window and Hysteresis 
     *
     * @param reg Index of register to read temp value
     * @return float Temperature in °Celsius
    */     
    float _readTempHelper(char reg);

   /** Set Temperature as float in °Celsius
     * Used for Critical temp threshold, Low and High temp threshold window and Hysteresis
     *
     * @param reg Index of register to write temp value
     * @param temp float Temperature value in °Celsius
     */        
    void _writeTempHelper(char reg, float temp);
};

#endif