Complete DS1621 library (all functions implemented)
Diff: ds1621.cpp
- 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