Gabriel Silva / Mbed OS LOG
Revision:
3:23ecb85b6e8b
Child:
4:0e3e93c26d83
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TMP117.cpp	Wed Sep 30 09:59:57 2020 -0400
@@ -0,0 +1,418 @@
+/*!
+ * @file    TMP117.cpp
+ * @author  Nils Minor
+ * 
+ * @license  GNU GENERAL PUBLIC LICENSE (see license.txt)
+ * 
+ * v1.0.0   - Initial library version
+ * 
+ * 
+ */
+#include "TMP117.h"
+
+/*!
+    @brief   Constructor 
+    @param   addr device I2C address [0x48 - 0x4B]
+*/
+TMP117::TMP117 (uint8_t addr) {  
+  
+  address = addr;
+  alert_pin = -1;
+  alert_type = NOALERT;
+  newDataCallback = NULL;
+}
+
+/*!
+    @brief   Initialize in default mode 
+    @param   _newDataCallback   callback function will be called when new data is available
+*/
+void TMP117::init ( void (*_newDataCallback) (void) ) {
+  setConvMode (CONTINUOUS);
+  setConvTime (C125mS);
+  setAveraging (AVE8);
+  setAlertMode (DATA);
+  setOffsetTemperature(0);    
+  
+  newDataCallback = _newDataCallback;
+}
+
+/*!
+    @brief    Read configuration register and handle events.
+              Should be called in loop in order to call callback functions 
+*/
+void TMP117::update (void) {
+  readConfig ();
+}
+
+/*!
+    @brief   Performs a soft reset. All default values will be loaded to the configuration register
+*/
+void TMP117::softReset ( void ) {
+  uint16_t reg_value = 0;
+  reg_value |= 1UL << 1;
+  writeConfig ( reg_value );
+}
+
+/*!
+    @brief   Set alert pin mode 
+    
+    @param   mode TMP117_PMODE [Thermal-Alert-Data]
+*/
+void      TMP117::setAlertMode ( TMP117_PMODE mode) {
+  uint16_t reg_value = readConfig ();
+  if (mode == THERMAL) {
+    reg_value |= 1UL << 4;    // change to thermal mode
+    reg_value &= ~(1UL << 2); // set pin as alert flag
+    reg_value &= ~(1UL << 3); // alert pin low active
+  }
+  else if (mode == ALERT) {
+    reg_value &= ~(1UL << 4); // change to alert mode
+    reg_value &= ~(1UL << 2); // set pin as alert flag
+    reg_value &= ~(1UL << 3); // alert pin low active
+  } 
+  else if (mode == DATA) {
+    reg_value |= 1UL << 2;    // set pin as data ready flag
+  } 
+  writeConfig ( reg_value );
+}
+
+///*!
+//    @brief   Set alert callback function and ISR pin
+//    @param   *allert_callback  callback function
+//    @param   pin callback pin (INT?)
+//*/
+//void      TMP117::setAllertCallback (void (*allert_callback)(void), uint8_t pin) {
+//  alert_pin = pin;
+//  pinMode(pin, INPUT_PULLUP);
+//   
+//  attachInterrupt(digitalPinToInterrupt(pin), allert_callback, FALLING ); // Sets up pin 2 to trigger "alert" ISR when pin changes H->L and L->H
+//}
+
+/*!
+    @brief    Set alert temperature
+    
+    @param    lowtemp   low boundary alert temperature
+    @param    hightemp  high boundary alert temperature  
+*/
+void      TMP117::setAllertTemperature (double lowtemp, double hightemp) {
+  
+ uint16_t high_temp_value = hightemp / TMP117_RESOLUTION;
+ uint16_t low_temp_value = lowtemp / TMP117_RESOLUTION;
+
+ i2cWrite2B (TMP117_REG_TEMP_HIGH_LIMIT , high_temp_value);
+ i2cWrite2B (TMP117_REG_TEMP_LOW_LIMIT , low_temp_value);  
+}
+
+/*!
+    @brief    Set conversion mode
+    
+    @param    cmode   ::TMP117_CMODE [CONTINUOUS-SHUTDOWN-ONESHOT]
+*/
+void      TMP117::setConvMode ( TMP117_CMODE cmode) {
+   uint16_t reg_value = readConfig ();
+   reg_value &= ~((1UL << 11) | (1UL << 10));       // clear bits
+   reg_value = reg_value | ( cmode  & 0x03 ) << 10; // set bits   
+   writeConfig ( reg_value );
+}
+
+/*!
+    @brief    Set conversion time
+    
+    @param    convtime  ::TMP117_CONVT [C15mS5-C125mS-C250mS-C500mS-C1S-C4S-C8S-C16S]
+*/
+void      TMP117::setConvTime ( TMP117_CONVT convtime ) {
+  uint16_t reg_value = readConfig ();
+  reg_value &= ~((1UL << 9) | (1UL << 8) | (1UL << 7));       // clear bits
+  reg_value = reg_value | ( convtime  & 0x07 ) << 7;          // set bits
+  writeConfig ( reg_value );
+}
+/*!
+    @brief    Set averaging mode
+    
+    @param    ave  ::TMP117_AVE [NOAVE-AVE8-AVE32-AVE64]
+*/
+void      TMP117::setAveraging ( TMP117_AVE ave ) {
+  uint16_t reg_value = readConfig ();
+  reg_value &= ~((1UL << 6) | (1UL << 5) );       // clear bits
+  reg_value = reg_value | ( ave & 0x03 ) << 5;          // set bits
+  writeConfig ( reg_value );
+}
+
+/*!
+    @brief    Set offset temperature
+    
+    @param    double  target offset temperature  in the range of ±256°C  
+*/
+void      TMP117::setOffsetTemperature ( double offset ) {
+  int16_t offset_temp_value = offset / TMP117_RESOLUTION;
+  i2cWrite2B (TMP117_REG_TEMPERATURE_OFFSET , offset_temp_value);
+}
+
+/*!
+    @brief    Set target temperature for calibration purpose
+    
+    @param    double  target temperature to calibrate to in the range of ±256°C  
+*/
+void      TMP117::setTargetTemperature ( double target ) {
+  double actual_temp = getTemperature ( );
+  double delta_temp =  target - actual_temp;
+  setOffsetTemperature ( delta_temp );
+}
+
+/*!
+    @brief    Read configuration register and handle events.
+
+    @return   uint16_t  read value of the configuration regsiter          
+*/
+uint16_t  TMP117::readConfig (void) {
+  uint16_t reg_value = i2cRead2B ( TMP117_REG_CONFIGURATION );
+  bool high_alert = reg_value >> 15 & 1UL;
+  bool low_alert = reg_value >> 14 & 1UL;   
+  bool data_ready = reg_value >> 13 & 1UL;   
+  bool eeprom_busy = reg_value >> 12 & 1UL;   
+
+  if (data_ready && newDataCallback != NULL)
+    newDataCallback ();
+
+  if (reg_value >> 15 & 1UL) {
+    alert_type = HIGHALERT;
+  }
+  else if (reg_value >> 14 & 1UL) {
+    alert_type = LOWALERT;
+  }
+  else {
+    alert_type = NOALERT;
+  }
+  
+  //printConfig ( reg_value );
+    
+  return reg_value;  
+}
+
+/*!
+    @brief    Returns the recalculated temperature
+    
+    @return   double  temperature in °C
+*/
+double    TMP117::getTemperature (void) {
+  int16_t temp = i2cRead2B( TMP117_REG_TEMPERATURE );
+  return  (temp * TMP117_RESOLUTION);
+}
+/*!
+    @brief    Get Device Revision 
+    
+    @return   uint16_t device revision
+*/
+uint16_t  TMP117::getDeviceRev (void) {
+  // read bits [15:12]
+  uint16_t raw = i2cRead2B( TMP117_REG_DEVICE_ID );
+  
+  return ( (raw >> 12) & 0x3);
+}
+
+/*!
+    @brief    Get Device ID (always 0x117)
+    
+    @return   uint16_t  device ID
+*/
+uint16_t  TMP117::getDeviceID (void) {
+  // read bits [11:0]
+  uint16_t raw = i2cRead2B( TMP117_REG_DEVICE_ID );
+  return (raw & 0x0fff);
+}
+
+/*!
+    @brief    Returns the information which alert type happend
+    
+    @return   TMP117_ALERT [NoAlert-HighTempAlert-LowTempAlert]
+*/
+TMP117_ALERT TMP117::getAlertType ( void ) {
+  return alert_type;
+}
+
+/*!
+    @brief    Returns the content of the offset register in °C
+    
+    @return   double  offset temperature in °C
+*/
+double    TMP117::getOffsetTemperature (void) {
+  int16_t temp = i2cRead2B( TMP117_REG_TEMPERATURE_OFFSET );
+  return  (temp * TMP117_RESOLUTION);
+}
+
+/*!
+    @brief    Write data to EEPROM register
+    
+    @param    data        data to write to the EEPROM
+    
+    @param    eeprom_nr   represents the EEPROM number [1 - 3] 
+*/
+void      TMP117::writeEEPROM (uint16_t data, uint8_t eeprom_nr) {
+  if (!EEPROMisBusy()) {
+    unlockEEPROM();
+      switch (eeprom_nr) {
+        case 1 : i2cWrite2B ( TMP117_REG_EEPROM1, data); break;
+        case 2 : i2cWrite2B ( TMP117_REG_EEPROM2, data); break;
+        case 3 : i2cWrite2B ( TMP117_REG_EEPROM3, data); break;
+        default: printf("EEPROM value must be between 1 and 3");
+      }
+    lockEEPROM();
+  }
+  else {
+    printf("EEPROM is busy");
+  }
+}
+
+/*!
+    @brief    Read data from EEPROM register
+    
+    @param    eeprom_nr  represents the EEPROM number [1 - 3] 
+    
+    @return   uint16_t   read EEPROM data
+*/
+uint16_t  TMP117::readEEPROM (uint8_t eeprom_nr) {
+  // read the 48 bit number from the EEPROM
+  if (!EEPROMisBusy()) {
+    uint16_t eeprom_data = 0;
+    switch (eeprom_nr) {
+        case 1 : eeprom_data = i2cRead2B( TMP117_REG_EEPROM1 ); break;
+        case 2 : eeprom_data = i2cRead2B( TMP117_REG_EEPROM2 ); break;
+        case 3 : eeprom_data = i2cRead2B( TMP117_REG_EEPROM3 ); break;
+        default: printf("EEPROM value must be between 1 and 3");
+      }
+    return eeprom_data;
+  }
+  else {
+    printf("EEPROM is busy");
+    return NULL;
+  }
+}
+
+
+/**************************************************************************/
+/* ********************* Library internal functions  ******************** */
+/**************************************************************************/
+
+/*!
+    @brief    Write two bytes (16 bits) to TMP117 I2C sensor
+    
+    @param    reg  target register
+    @param    data data to write
+*/
+void      TMP117::i2cWrite2B (uint8_t reg, uint16_t data){
+  TMP117::i2c.start(); 
+  TMP117::i2c.write(reg);
+  char* w;
+  w[0] = (char)data>>8;
+  w[1] = (char)data & 0xff;
+  TMP117::i2c.write(address, w, 2);
+  TMP117::i2c.stop();
+  wait_us(10*1000);
+}
+
+/*!
+    @brief    Read two bytes (16 bits) from TMP117 I2C sensor
+    
+    @param    reg  target register to read from
+    
+    @return   uint16_t  read data
+*/
+uint16_t  TMP117::i2cRead2B (uint8_t reg) {
+  int ACK = 0;
+  uint8_t read[2] = {0}; 
+  int16_t temp = 0;   
+
+  TMP117::i2c.start(); 
+  ACK = TMP117::i2c.write(TMP117::address<<1);
+  if(!ACK) return -1;
+  ACK = TMP117::i2c.write((0x0f)&reg);
+  if(!ACK) return -1;
+  TMP117::i2c.start();
+  TMP117::i2c.write((TMP117::address<<1)|0x01);
+  if(!ACK) return -1;
+  read[0] = TMP117::i2c.read(ACK);
+  if(!ACK) return -1;
+  read[1] = TMP117::i2c.read(ACK);
+  TMP117::i2c.read(ACK);
+  temp = (read[0] << 8) | read[1];
+  msb = read[0];
+  lsb = read[1];
+  return temp;
+}
+
+/*!
+    @brief    Write configuration to config register
+    
+    @param    config_data  configuration
+*/
+void      TMP117::writeConfig (uint16_t config_data) {
+  i2cWrite2B (TMP117_REG_CONFIGURATION, config_data);
+}
+
+/*!
+    @brief    Prints configuration in user readable format
+    
+    @param    reg_value  configuration value
+*/
+//void      TMP117::printConfig (uint16_t reg_value) {
+//
+////  printf(reg_value, BIN);
+//
+//  printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+//  printf ("HIGH alert:  ");
+//  printf( ( reg_value >> 15) & 0b1 , BIN);
+//  printf ("LOW alert:   ");
+//  printf( ( reg_value >> 14) & 0b1 , BIN);
+//  printf ("Data ready:  ");
+//  printf( ( reg_value >> 13) & 0b1 , BIN);
+//  printf ("EEPROM busy: ");
+//  printf( ( reg_value >> 12) & 0b1 , BIN);
+//  printf ("MOD[1:0]:    ");
+//  printf( ( reg_value >> 10) & 0b11 , BIN);
+//  printf ("CONV[2:0]:   ");
+//  printf( ( reg_value >> 7)  & 0b111 , BIN);
+//  printf ("AVG[1:0]:    ");
+//  printf( ( reg_value >> 5)  & 0b11 , BIN);
+//  printf ("T/nA:        ");
+//  printf( ( reg_value >> 4) & 0b1 , BIN);
+//  printf ("POL:         ");
+//  printf( ( reg_value >> 3) & 0b1 , BIN);
+//  printf ("DR/Alert:    ");
+//  printf( ( reg_value >> 2) & 0b1 , BIN);
+//  printf ("Soft_Reset:  ");
+//  printf( ( reg_value >> 1) & 0b1 , BIN);
+//}
+/*!
+    @brief    Lock EEPROM, write protection
+*/
+void      TMP117::lockEEPROM (void) {
+  // clear bit 15
+  uint16_t code = 0;
+  code &= ~(1UL << 15);
+  i2cWrite2B ( TMP117_REG_EEPROM_UNLOCK, code );
+  wait_us(100*1000);
+}
+
+/*!
+    @brief    Unlock EEPROM, remove write protection
+*/
+void      TMP117::unlockEEPROM (void) {
+  // set bit 15
+  uint16_t code = 0;
+  code |= 1UL << 15;
+  i2cWrite2B ( TMP117_REG_EEPROM_UNLOCK, code );
+  wait_us(100*1000);
+}
+
+/*!
+    @brief    States if the EEPROM is busy
+    
+    @return   Ture if the EEPROM is busy, fals else
+*/
+bool      TMP117::EEPROMisBusy (void) {
+  // Bit 14 indicates the busy state of the eeprom
+  uint16_t code = i2cRead2B ( TMP117_REG_EEPROM_UNLOCK );
+  return (bool) ((code >> 14) & 0x01);
+}
+
+