Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
DS18B20.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 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 <MaximInterfaceCore/Error.hpp> 00034 #include <MaximInterfaceCore/OneWireMaster.hpp> 00035 #include "DS18B20.hpp" 00036 00037 #define TRY MaximInterfaceCore_TRY 00038 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE 00039 00040 namespace MaximInterfaceDevices { 00041 00042 using namespace Core; 00043 00044 const uint_least8_t DS18B20::nineBitResolution; 00045 const uint_least8_t DS18B20::tenBitResolution; 00046 const uint_least8_t DS18B20::elevenBitResolution; 00047 const uint_least8_t DS18B20::twelveBitResolution; 00048 00049 Result<void> DS18B20::initialize() const { 00050 TRY(readScratchpad()); 00051 return none; 00052 } 00053 00054 Result<void> DS18B20::writeScratchpad(uint_least8_t th, uint_least8_t tl, 00055 uint_least8_t res) { 00056 Result<void> result = selectRom(*master); 00057 if (result) { 00058 const uint_least8_t sendBlock[] = {0x4E, th, tl, res}; 00059 result = master->writeBlock(sendBlock); 00060 if (result) { 00061 resolution = res; 00062 } 00063 } 00064 return result; 00065 } 00066 00067 Result<DS18B20::Scratchpad> DS18B20::readScratchpad() const { 00068 Result<void> result = selectRom(*master); 00069 if (!result) { 00070 return result.error(); 00071 } 00072 result = master->writeByte(0xBE); 00073 if (!result) { 00074 return result.error(); 00075 } 00076 Scratchpad scratchpad; 00077 result = master->readBlock(scratchpad); 00078 if (!result) { 00079 return result.error(); 00080 } 00081 uint_least8_t receivedCrc; 00082 TRY_VALUE(receivedCrc, master->readByte()); 00083 if (receivedCrc != calculateCrc8(scratchpad)) { 00084 return CrcError; 00085 } 00086 resolution = scratchpad[4]; 00087 return scratchpad; 00088 } 00089 00090 Result<bool> DS18B20::readPowerSupply() const { 00091 Result<void> result = selectRom(*master); 00092 if (!result) { 00093 return result.error(); 00094 } 00095 result = master->writeByte(0xB4); 00096 if (!result) { 00097 return result.error(); 00098 } 00099 return master->readBit(); 00100 } 00101 00102 Result<void> DS18B20::copyScratchpad() { 00103 const uint_least8_t copyScratchpadCmd = 0x48; 00104 00105 bool hasLocalPower; 00106 TRY_VALUE(hasLocalPower, readPowerSupply()); 00107 Result<void> result = selectRom(*master); 00108 if (!result) { 00109 return result; 00110 } 00111 if (hasLocalPower) { 00112 result = master->writeByte(copyScratchpadCmd); 00113 if (result) { 00114 bool recvBit; 00115 do { 00116 TRY_VALUE(recvBit, master->readBit()); 00117 } while (!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 Result<void> DS18B20::convertTemperature() { 00131 const uint_least8_t convertTemperatureCmd = 0x44; 00132 00133 bool hasLocalPower; 00134 TRY_VALUE(hasLocalPower, readPowerSupply()); 00135 Result<void> result = selectRom(*master); 00136 if (!result) { 00137 return result; 00138 } 00139 if (hasLocalPower) { 00140 result = master->writeByte(convertTemperatureCmd); 00141 if (result) { 00142 bool recvBit; 00143 do { 00144 TRY_VALUE(recvBit, master->readBit()); 00145 } while (!recvBit); 00146 } 00147 } else { 00148 result = master->writeByteSetLevel(convertTemperatureCmd, 00149 OneWireMaster::StrongLevel); 00150 if (result) { 00151 int sleepTime; 00152 switch (resolution) { 00153 case nineBitResolution: 00154 sleepTime = 94; 00155 break; 00156 00157 case tenBitResolution: 00158 sleepTime = 188; 00159 break; 00160 00161 case elevenBitResolution: 00162 sleepTime = 375; 00163 break; 00164 00165 case twelveBitResolution: 00166 default: 00167 sleepTime = 750; 00168 break; 00169 } 00170 sleep->invoke(sleepTime); 00171 result = master->setLevel(OneWireMaster::NormalLevel); 00172 } 00173 } 00174 return result; 00175 } 00176 00177 Result<void> DS18B20::recallEeprom() { 00178 Result<void> result = selectRom(*master); 00179 if (result) { 00180 result = master->writeByte(0xB8); 00181 } 00182 return result; 00183 } 00184 00185 const error_category & DS18B20::errorCategory() { 00186 static class : public error_category { 00187 public: 00188 virtual const char * name() const { 00189 return "MaximInterfaceDevices.DS18B20"; 00190 } 00191 00192 virtual std::string message(int condition) const { 00193 switch (condition) { 00194 case CrcError: 00195 return "CRC Error"; 00196 00197 case DataError: 00198 return "Data Error"; 00199 } 00200 return defaultErrorMessage(condition); 00201 } 00202 } instance; 00203 return instance; 00204 } 00205 00206 Result<int> readTemperature(DS18B20 & ds18b20) { 00207 TRY(ds18b20.convertTemperature()); 00208 DS18B20::Scratchpad scratchpad; 00209 TRY_VALUE(scratchpad, ds18b20.readScratchpad()); 00210 00211 const unsigned int tempData = 00212 (static_cast<unsigned int>(scratchpad[1]) << 8) | scratchpad[0]; 00213 const unsigned int signMask = 0xF800; 00214 int temperature; 00215 if ((tempData & signMask) == signMask) { 00216 temperature = -0x800; 00217 } else if ((tempData & signMask) == 0) { 00218 temperature = 0; 00219 } else { 00220 return DS18B20::DataError; 00221 } 00222 unsigned int precisionMask; 00223 switch (scratchpad[4]) { 00224 case DS18B20::nineBitResolution: 00225 default: 00226 precisionMask = 0x7; 00227 break; 00228 00229 case DS18B20::tenBitResolution: 00230 precisionMask = 0x3; 00231 break; 00232 00233 case DS18B20::elevenBitResolution: 00234 precisionMask = 0x1; 00235 break; 00236 00237 case DS18B20::twelveBitResolution: 00238 precisionMask = 0x0; 00239 break; 00240 } 00241 temperature += static_cast<int>(tempData & ~(signMask | precisionMask)); 00242 return temperature; 00243 } 00244 00245 } // namespace MaximInterfaceDevices
Generated on Tue Jul 12 2022 11:13:04 by 1.7.2