Complete DS1621 library (all functions implemented)

Files at this revision

API Documentation at this revision

Comitter:
bborredon
Date:
Sat Jul 14 08:20:05 2012 +0000
Commit message:
[mbed] converted /I2c/DS1621

Changed in this revision

ds1621.cpp Show annotated file Show diff for this revision Revisions of this file
ds1621.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 096dbb58d60e ds1621.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1621.cpp	Sat Jul 14 08:20:05 2012 +0000
@@ -0,0 +1,479 @@
+/***********************************************************
+Author: Bernard Borredon
+Date: 27 december 2011
+Version: 1.0
+************************************************************/
+#include "ds1621.h"
+
+#define BIT_SET(x,n) (x=x | (0x01<<n))
+#define BIT_TEST(x,n) (x & (0x01<<n))
+#define BIT_CLEAR(x,n) (x=x & ~(0x01<<n))
+
+// Constructor
+DS1621::DS1621(PinName sda, PinName scl, uint8_t address) : _i2c(sda, scl) 
+{
+  _errnum = DS1621_NoError;
+  _config = DS1621_PolHigh;
+  
+  // Check address range (0 to 7)
+  _address = address;
+  if(address > 7) {
+    _errnum = DS1621_BadAddress;
+  }
+  _address = _address << 1;
+  
+  // Set I2C frequency
+  _i2c.frequency(100000);
+}
+
+// Get temperature with 0.5 degrees resolution
+float DS1621::getTemp(void) 
+{
+  char cmd;
+  int8_t temp8[2];
+  float temp;
+  int ack;
+  
+  // Check error
+  if(_errnum) 
+    return(0.0);
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // Start convert
+  startConvert(true);
+  if(getError() != 0)
+    return(0.0);
+  
+  cmd = 0xAA; // Read Temperature [AAh]
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+    
+  // Read value
+  ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  // Format temperature
+  temp8[1] = temp8[1] >> 7;
+  if(temp8[0] < 0) { // -
+    temp = -~temp8[0] + 0.5 * temp8[1];
+  }
+  else { // +
+    temp = temp8[0] - 0.5 * temp8[1];
+  }
+
+  return(temp);
+}
+
+// Get temperature with 0.01 degrees resolution
+float DS1621::getHrTemp(void) 
+{
+  char cmd;
+  int8_t temp8[2];
+  int ack;
+  uint8_t count_remain, count_per_c;
+  uint8_t config,config_mem;
+  int16_t ifract;
+  int16_t itemp;
+  float temp;
+    
+  // Check error
+  if(_errnum) 
+    return(0.0);
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // Get config register
+  config = getConfig();
+  if(getError() != 0)
+    return(0.0);
+  
+  // Force 1Shot if needed
+  config_mem = 0;
+  if(!BIT_TEST(config,DS1621_CFG_1SHOT)) {
+    config_mem = config;
+    BIT_SET(config,DS1621_CFG_1SHOT);
+    setConfig(config);
+    if(getError() != 0)
+      return(0.0);
+    startConvert(false);
+    if(getError() != 0)
+      return(0.0);
+  }
+  
+  // Start conversion
+  startConvert(true);
+  if(getError() != 0)
+    return(0.0);
+  
+  // Wait end of conversion
+  waitEndConvert();
+  if(getError() != 0)
+    return(0.0);
+  
+  cmd = 0xAA; // Read Temperature [AAh]
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  // Read value
+  ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  cmd = 0xA8; // Read Counter [A8H]
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  // Read value
+  ack = _i2c.read(DS1621_address | _address,(char *)&count_remain,sizeof(count_remain));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  cmd = 0xA9; // Read Slope [A9H]
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  // Read value
+  ack = _i2c.read(DS1621_address | _address,(char *)&count_per_c,sizeof(count_per_c));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+    
+  // Format temperature
+  ifract = ((int16_t)(count_per_c - count_remain) * 100) / 25;
+  if(temp8[0] < 0) { // -
+    itemp = -~temp8[0] * 100 + ifract;
+  }
+  else { // +
+    itemp = temp8[0] * 100 + ifract;
+  }
+  temp = (float)itemp / 100.0;
+  
+  // Restore config if needed
+  if(config_mem) {
+    setConfig(config_mem);
+    if(getError() != 0)
+      return(0.0);
+    startConvert(true);
+    if(getError() != 0)
+      return(0.0);
+  }
+
+  return(temp);
+}
+
+// Read config register
+uint8_t DS1621::getConfig(void) 
+{
+  char cmd;
+  uint8_t config;
+  int ack;
+  
+  // Check error
+  if(_errnum) 
+    return(0);
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  cmd = 0xAC; // Access Config [ACh]
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0);
+  }
+  
+  // Read value
+  ack = _i2c.read(DS1621_address | _address,(char *)&config,sizeof(config));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0);
+  }
+  
+  return(config);
+}
+
+// Write config register
+void DS1621::setConfig(uint8_t config) 
+{
+  char cmd[2];
+  int ack;
+  
+  // Check error
+  if(_errnum) 
+    return;
+  
+  // No error
+  _errnum = DS1621_NoError; 
+   
+  _config = config;
+    
+  cmd[0] = 0xAC; // Access Config [ACh]
+  cmd[1] = config;
+  ack = _i2c.write(DS1621_address | _address,cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+  }
+}
+
+// Start or stop convert
+void DS1621::startConvert(bool flag) 
+{
+  char cmd;
+  int ack;
+  
+  // Check error
+  if(_errnum) 
+    return;
+    
+  // No error
+  _errnum = DS1621_NoError;
+      
+  if(flag)
+    cmd = 0xEE; // Start Convert [EEh]
+  else
+    cmd = 0x22; // Stop Convert [22h]
+    
+  ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+  }
+}
+
+// Wait end of conversion
+void DS1621::waitEndConvert(void) 
+{
+  uint8_t cfg;
+  
+  // Check error
+  if(_errnum) 
+    return;
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // Wait end of conversion
+  do {
+       // Get Config register and test bit DONE
+       cfg = getConfig();
+       if(getError() != 0)
+         return;
+  }
+  while(cfg < DS1621_DONE);
+}
+
+// Read Temperature High Flag
+bool DS1621::getTHF(void) 
+{
+  uint8_t cfg;
+  bool thf;
+  
+  // Check error
+  if(_errnum) 
+    return(0);
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // get Config register
+  cfg = getConfig();
+  if(getError() != 0)
+    return(0);
+  
+  // Test THF bit
+  if(BIT_TEST(cfg,DS1621_CFG_THF))
+    thf = true;
+  else
+    thf = false;
+    
+  return(thf);
+}
+
+// Read Temperature Low Flag
+bool DS1621::getTLF() 
+{
+  uint8_t cfg;
+  bool tlf;
+  
+  // Check error
+  if(_errnum) 
+    return(0);
+  
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // get Config register
+  cfg = getConfig();
+  if(getError() != 0)
+    return(0);
+    
+  // Test TLF bit
+  if(BIT_TEST(cfg,DS1621_CFG_TLF))
+    tlf = true;
+  else
+    tlf = false;
+    
+  return(tlf);
+}
+
+// Read Temperature Low and High Flag
+void DS1621::getTF(bool& tlf,bool& thf) 
+{
+  uint8_t cfg;
+  
+  // Check error
+  if(_errnum) 
+    return;
+  
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // get Config register
+  cfg = getConfig();
+  if(getError() != 0)
+    return;
+  
+  // Test TLF bit
+  tlf = false;
+  if(BIT_TEST(cfg,DS1621_CFG_TLF))
+    tlf = true;
+    
+  // Test THF bit
+  thf = false;
+  if(BIT_TEST(cfg,DS1621_CFG_THF))
+    thf = true;
+}
+
+// Read 1Shot bit
+bool DS1621::get1Shot(void) 
+{
+  
+  // Test 1Shot bit
+  if(BIT_TEST(_config,DS1621_CFG_1SHOT))
+    return(true);
+  else
+    return(false);
+}
+
+// Write Temperature (High or Low)
+void DS1621::setTemperature(float temp,uint8_t trig) 
+{
+  uint8_t temp8[3];
+  int ack;
+  float r;
+  
+  // Chack param
+  if(trig > 1) {
+    _errnum = DS1621_ParamError;
+    return;
+  }
+    
+  // Check error
+  if(_errnum) 
+    return;
+    
+  // No error
+  _errnum = DS1621_NoError;
+  
+  // Format temperature
+  if(temp >= 0.0) {
+    temp8[1] = (uint8_t)temp;
+    r = temp - (int)temp;
+    if(r >= 0.5)
+      temp8[2] = 0x80;
+    else
+      temp8[2] = 0;
+  }
+  else {
+    temp8[1] = ~(-(int8_t)temp);
+    r = -temp + (int)temp;
+    if(r >= 0.5)
+      temp8[2] = 0x80;
+    else
+      temp8[2] = 0;
+  }
+  
+  wait_ms(100);
+    
+  temp8[0] = 0xA1 + trig; // Access TH or TL [A1h or A2h]
+  ack = _i2c.write(DS1621_address | _address,(char *)temp8,sizeof(temp8));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+  }
+}
+
+// Read Temperature (High or Low)
+float DS1621::getTemperature(uint8_t trig) 
+{
+  char cmd;
+  float temp;
+  int8_t temp8[2];
+  int ack;
+  
+  // Check param
+  if(trig > 1) {
+    _errnum = DS1621_ParamError;
+    return(0.0);
+  }
+    
+  // Check error
+  if(_errnum) 
+    return(0.0);
+    
+  // No error
+  _errnum = DS1621_NoError;
+    
+  wait_ms(100);
+    
+  cmd = 0xA1 + trig; // Access TH or TL [A1h or A2h]
+  ack = _i2c.write(DS1621_address| _address,&cmd,sizeof(cmd));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+    
+  ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8));
+  if(ack != 0) {
+    _errnum = DS1621_I2cError;
+    return(0.0);
+  }
+  
+  // Format temperature
+  temp8[1] = temp8[1] >> 7;
+  if(temp8[0] < 0) { // -
+    temp = -~temp8[0] + 0.5 * temp8[1];
+  }
+  else { // +
+    temp = temp8[0] - 0.5 * temp8[1];
+  }
+  
+  return(temp);
+}
+
+// Get current error number
+uint8_t DS1621::getError(void)
+{ 
+  return(_errnum);
+}
\ No newline at end of file
diff -r 000000000000 -r 096dbb58d60e ds1621.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1621.h	Sat Jul 14 08:20:05 2012 +0000
@@ -0,0 +1,264 @@
+#ifndef DS1621__H_
+#define DS1621__H_
+
+// Includes
+#include <string>
+
+#include "mbed.h"
+
+// Example
+/*
+#include <string>
+
+#include "mbed.h"
+#include "ds1621.h"
+#define DS1621_ADDR 0     // I2c DS1621 address is 0x00
+
+static void myerror(std::string msg)
+{
+  printf("Error %s\n",msg.c_str());
+  exit(1);
+}
+
+int main()
+{
+  DS1621 ds(p9,p10,DS1621_ADDR);  // Declare DS1621 i2c with sda = p9 and scl = p10
+  bool tlf,thf;
+  uint8_t i;
+  uint8_t config;
+  uint16_t count = 0;
+  float temp = 0.0;
+  
+  printf("Test DS1621 I2C\n\n");
+  
+  // Check error
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+
+  // Config with OneShot and Pol high and test error
+  ds.setConfig(DS1621_1Shot | DS1621_PolHigh);
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  
+  // Read Config register
+  config = ds.getConfig();
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  printf("DS1621 Config : %02X\n",config);
+   
+  printf("Test HR Temperature\n"); 
+  
+  // Test HR temperature
+  for(i = 0;i < 24;i++) {
+     temp = ds.getHrTemp();
+     if(ds.getError() != 0)
+       myerror(ds.getErrorMessage());
+     printf("Measurment at start + %d seconds, Temperature HR = %.2f\n",(count*5),temp);
+     wait(5.0);
+     count++;
+  }
+ 
+  printf("Test Temperature\n"); 
+ 
+  // Test temperature
+  count = 0;
+  for(i = 0;i < 12;i++) {
+     temp = ds.getTemp();
+     if(ds.getError() != 0)
+       myerror(ds.getErrorMessage());
+     printf("Measurment at start + %d seconds, Temperature = %.2f\n",(count*5),temp);
+     wait(5.0);
+     count++;
+  }
+  
+  // Config with Continuous and Pol high
+  ds.setConfig(DS1621_PolHigh); 
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  
+  // Read Config register
+  config = ds.getConfig();
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  printf("DS1621 Config : %02X\n",config);
+  
+  // Write trigger temperatures
+  ds.setTemperature(18.0,DS1621_Access_TL);
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  ds.setTemperature(25.5,DS1621_Access_TH);
+  if(ds.getError() != 0)
+    myerror(ds.getErrorMessage());
+  
+  printf("Test temperature and triggers\n");
+  while(1) {
+             temp = ds.getTemp();
+             if(ds.getError() != 0)
+               myerror(ds.getErrorMessage());
+             ds.getTF(tlf,thf);
+             if(ds.getError() != 0)
+               myerror(ds.getErrorMessage());
+             printf("Temperature=%.2f  TLF %d  THF %d\n",temp,tlf,thf);
+             wait(5.0);
+  }
+}
+*/
+
+// Defines
+#define DS1621_address     0x90
+
+#define DS1621_PolHigh     0x02
+#define DS1621_1Shot       0x01
+#define DS1621_DONE        0x80
+
+#define DS1621_CFG_1SHOT      0
+#define DS1621_CFG_POL        1
+#define DS1621_CFG_TLF        5
+#define DS1621_CFG_THF        6
+#define DS1621_CFG_DONE       7
+
+#define DS1621_Access_TH      0
+#define DS1621_Access_TL      1
+
+#define DS1621_NoError     0x00
+#define DS1621_BadAddress  0x01
+#define DS1621_I2cError    0x02
+#define DS1621_ParamError  0x03
+
+#define DS1621_MaxError       4
+
+static std::string _ErrorMessageDS1621[DS1621_MaxError] = {
+                                                            "",
+                                                            "Bad chip address",
+                                                            "I2C error (nack)",
+                                                            "Invalid parameter",
+                                                          };
+
+// Class
+class DS1621 {
+public:
+    /*
+     * Constructor, initialize the ds1621 on i2c interface.
+     * @param sda : sda i2c pin (PinName)
+     * @param scl : scl i2c pin (PinName)
+     * @param address : ds1621 address between 0 and 7 (uint8_t) 
+     * @return none
+    */
+    DS1621(PinName sda, PinName scl, uint8_t address);
+
+    /*
+     * Get temperature from the ds1621 with 0.5 degrees resolution
+     * @param : none
+     * @return current temperature in degrees Celsius between -55 and +125 (float)
+    */
+    float getTemp(void);
+    
+    /*
+     * Get temperature from the ds1621 with 0.01 degrees resolution
+     * @param : none
+     * @return current temperature in degrees Celsius between -55 and +125 (float) 
+    */
+    float getHrTemp(void);
+    
+    /*
+     * Read config register
+     * @param : none
+     * @return  current config register value (uin8_t)
+    */
+    uint8_t getConfig(void);
+    
+    /*
+     * Write config register
+     * @param config : config value (uint8_t) 
+     * @return none
+    */
+    void setConfig(uint8_t config);
+    
+    /*
+     * Start / stop convert
+     * @param flag : start convert if true else stop 
+     * @return none
+    */
+    void startConvert(bool flag);
+    
+    /*
+     * Wait end of conversion (Config register bit 7 at 1)
+     * @param : none
+     * @return none
+    */
+    void waitEndConvert(void);
+    
+    /*
+     * Get Temperature High Flag
+     * @param : none
+     * @return thf flag (bool)
+    */
+    bool getTHF(void);
+    
+    /*
+     * Get Temperature Low Flag
+     * @param : none
+     * @return tlf flag (bool)
+    */
+    bool getTLF(void);
+    
+    /*
+     * Get Temperature Low and High Flags
+     * @param tlf : temperature low flag (uint8_t&)
+     * @param thf : temperature high flag (uint8_t&)
+     * @return none
+    */
+    void getTF(bool& tlf,bool& thf);
+    
+     /*
+    *Get 1Shot bit
+    *@param : none
+    *@return true if 1Shot (bool)
+    */
+    bool get1Shot(void);
+    
+    /*
+    *Set Temperature (High or Low)
+    *@param temp : temperature, the fractionnal part is rounded to 0.5 (float)
+    *@param trig : mode,low or high (uint8_t) [DS1621_Access_TL DS1621_Access_TH]
+    *@return none
+    */
+    void setTemperature(float temp,uint8_t trig);
+    
+     /*
+    *Get Temperature (High or Low)
+    *@param trig : mode,low or high (uint8_t) [DS1621_Access_TL DS1621_Access_TH]
+    *@return  temperature, with 0.5 degrees Celsius resolution (float)
+    */
+    float getTemperature(uint8_t trig);
+    
+    /*
+    *Get current error message
+    *@param  : none
+    *@return current error message(std::string)
+    */
+    std::string getErrorMessage(void)
+    { 
+      if(_errnum < DS1621_MaxError)
+        return(_ErrorMessageDS1621[_errnum]);
+      else
+        return("errnum out of range");
+    }
+    
+    /*
+     * Get the current error number (DS1621_NoError if no error)
+     * @param  : none
+     * @return current error number (uint8_t)
+    */
+    uint8_t getError(void);
+    
+//---------- local variables ----------
+private:
+    I2C _i2c;        // Local i2c communication interface instance
+    int _address;    // Local ds1621 i2c address
+    uint8_t _errnum; // Error number
+    uint8_t _config; // Config register value
+//-------------------------------------
+};
+
+#endif
\ No newline at end of file