Complete DS1621 library (all functions implemented)

Revision:
0:096dbb58d60e
--- /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