Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS18B20.cpp Source File

DS18B20.cpp

00001 /*******************************************************************************
00002 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 *******************************************************************************/
00032 
00033 #include <MaximInterface/Links/OneWireMaster.hpp>
00034 #include <MaximInterface/Utilities/Error.hpp>
00035 #include "DS18B20.hpp"
00036 
00037 namespace MaximInterface {
00038 
00039 const uint_least8_t DS18B20::nineBitResolution;
00040 const uint_least8_t DS18B20::tenBitResolution;
00041 const uint_least8_t DS18B20::elevenBitResolution;
00042 const uint_least8_t DS18B20::twelveBitResolution;
00043 
00044 error_code DS18B20::initialize() {
00045   Scratchpad::array scratchpad;
00046   return readScratchpad(scratchpad);
00047 }
00048 
00049 error_code DS18B20::writeScratchpad(uint_least8_t th, uint_least8_t tl,
00050                                     uint_least8_t res) {  
00051   error_code result = selectRom(*master);
00052   if (!result) {
00053     const uint_least8_t sendBlock[] = {0x4E, th, tl, res};
00054     result = master->writeBlock(sendBlock);
00055     if (!result) {
00056       resolution = res;
00057     }
00058   }
00059   return result;
00060 }
00061 
00062 error_code DS18B20::readScratchpad(Scratchpad::span scratchpad) {  
00063   error_code result = selectRom(*master);
00064   if (result) {
00065     return result;
00066   }
00067   result = master->writeByte(0xBE);
00068   if (result) {
00069     return result;
00070   }
00071   result = master->readBlock(scratchpad);
00072   if (result) {
00073     return result;
00074   }
00075   uint_least8_t receivedCrc;
00076   result = master->readByte(receivedCrc);
00077   if (result) {
00078     return result;
00079   }
00080   if (receivedCrc == calculateCrc8(scratchpad)) {
00081     resolution = scratchpad[4];
00082   } else {
00083     result = make_error_code(CrcError);
00084   }
00085   return result;
00086 }
00087 
00088 error_code DS18B20::readPowerSupply(bool & localPower) {  
00089   error_code result = selectRom(*master);
00090   if (result) {
00091     return result;
00092   }
00093   result = master->writeByte(0xB4);
00094   if (result) {
00095     return result;
00096   }
00097   result = master->touchBit(localPower);
00098   return result;
00099 }
00100 
00101 error_code DS18B20::copyScratchpad() {
00102   const uint_least8_t copyScratchpadCmd = 0x48;
00103   
00104   bool hasLocalPower;
00105   error_code result = readPowerSupply(hasLocalPower);
00106   if (result) {
00107     return result;
00108   }
00109   result = selectRom(*master);
00110   if (result) {
00111     return result;
00112   }
00113   if (hasLocalPower) {
00114     result = master->writeByte(copyScratchpadCmd);
00115     bool recvbit = 0;
00116     while (!recvbit && !result) {
00117       result = master->touchBit(recvbit);
00118     }
00119   } else {
00120     result = master->writeByteSetLevel(copyScratchpadCmd,
00121                                        OneWireMaster::StrongLevel);
00122     if (!result) {
00123       sleep->invoke(10);
00124       result = master->setLevel(OneWireMaster::NormalLevel);
00125     }
00126   }
00127   return result;
00128 }
00129 
00130 error_code DS18B20::convertTemperature() {
00131   const uint_least8_t convertTemperatureCmd = 0x44;
00132   
00133   bool hasLocalPower;
00134   error_code result = readPowerSupply(hasLocalPower);
00135   if (result) {
00136     return result;
00137   }
00138   result = selectRom(*master);
00139   if (result) {
00140     return result;
00141   }
00142   if (hasLocalPower) {
00143     result = master->writeByte(convertTemperatureCmd);
00144     bool recvbit = 0;
00145     while (!result && !recvbit) {
00146       result = master->touchBit(recvbit);
00147     }
00148   } else {
00149     result = master->writeByteSetLevel(convertTemperatureCmd,
00150                                        OneWireMaster::StrongLevel);
00151     if (!result) {
00152       int sleepTime;
00153       switch (resolution) {
00154       case nineBitResolution:
00155         sleepTime = 94;
00156         break;
00157 
00158       case tenBitResolution:
00159         sleepTime = 188;
00160         break;
00161 
00162       case elevenBitResolution:
00163         sleepTime = 375;
00164         break;
00165 
00166       case twelveBitResolution:
00167       default:
00168         sleepTime = 750;
00169         break;
00170       }
00171       sleep->invoke(sleepTime);
00172       result = master->setLevel(OneWireMaster::NormalLevel);
00173     }
00174   }
00175   return result;
00176 }
00177 
00178 error_code DS18B20::recallEeprom() {  
00179   error_code result = selectRom(*master);
00180   if (!result) {
00181     result = master->writeByte(0xB8);
00182   }
00183   return result;
00184 }
00185 
00186 const error_category & DS18B20::errorCategory() {
00187   static class : public error_category {
00188   public:
00189     virtual const char * name() const { return "DS18B20"; }
00190 
00191     virtual std::string message(int condition) const {
00192       switch (condition) {
00193       case CrcError:
00194         return "CRC Error";
00195 
00196       case DataError:
00197         return "Data Error";
00198 
00199       default:
00200         return defaultErrorMessage(condition);
00201       }
00202     }
00203   } instance;
00204   return instance;
00205 }
00206 
00207 error_code readTemperature(DS18B20 & ds18b20, int & temperature) {
00208   error_code result = ds18b20.convertTemperature();
00209   if (result) {
00210     return result;
00211   }
00212   DS18B20::Scratchpad::array scratchpad;
00213   result = ds18b20.readScratchpad(scratchpad);
00214   if (result) {
00215     return result;
00216   }
00217 
00218   const unsigned int tempData =
00219       (static_cast<unsigned int>(scratchpad[1]) << 8) | scratchpad[0];
00220   const unsigned int signMask = 0xF800;
00221   if ((tempData & signMask) == signMask) {
00222     temperature = -0x800;
00223   } else if ((tempData & signMask) == 0) {
00224     temperature = 0;
00225   } else {
00226     return make_error_code(DS18B20::DataError);
00227   }
00228   unsigned int precisionMask;
00229   switch (scratchpad[4]) {
00230   case DS18B20::nineBitResolution:
00231   default:
00232     precisionMask = 0x7;
00233     break;
00234 
00235   case DS18B20::tenBitResolution:
00236     precisionMask = 0x3;
00237     break;
00238 
00239   case DS18B20::elevenBitResolution:
00240     precisionMask = 0x1;
00241     break;
00242 
00243   case DS18B20::twelveBitResolution:
00244     precisionMask = 0x0;
00245     break;
00246   }
00247   temperature += static_cast<int>(tempData & ~(signMask | precisionMask));
00248   return error_code();
00249 }
00250 
00251 } // namespace MaximInterface