Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
DS2482_DS2484.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 "DS2482_DS2484.hpp" 00035 00036 #define TRY MaximInterfaceCore_TRY 00037 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE 00038 00039 namespace MaximInterfaceDevices { 00040 00041 using namespace Core; 00042 00043 // Device status bits. 00044 static const uint_least8_t status_1WB = 0x01; 00045 static const uint_least8_t status_PPD = 0x02; 00046 static const uint_least8_t status_SD = 0x04; 00047 static const uint_least8_t status_SBR = 0x20; 00048 static const uint_least8_t status_TSB = 0x40; 00049 static const uint_least8_t status_DIR = 0x80; 00050 00051 Result<void> DS2482_DS2484::initialize(Config config) { 00052 TRY(resetDevice()); 00053 // Write the default configuration setup. 00054 TRY(writeConfig(config)); 00055 return none; 00056 } 00057 00058 Result<void> DS2482_DS2484::resetDevice() { 00059 // Device Reset 00060 // S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P 00061 // [] indicates from slave 00062 // SS status byte to read to verify state 00063 00064 TRY(sendCommand(0xF0)); 00065 00066 uint_least8_t buf; 00067 TRY_VALUE(buf, readRegister()); 00068 00069 if ((buf & 0xF7) != 0x10) { 00070 return HardwareError; 00071 } 00072 00073 // Do a command to get 1-Wire master reset out of holding state. 00074 reset(); 00075 00076 return none; 00077 } 00078 00079 Result<OneWireMaster::TripletData> DS2482_DS2484::triplet(bool sendBit) { 00080 // 1-Wire Triplet (Case B) 00081 // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00082 // \--------/ 00083 // Repeat until 1WB bit has changed to 0 00084 // [] indicates from slave 00085 // SS indicates byte containing search direction bit value in msbit 00086 00087 TRY(sendCommand(0x78, sendBit ? 0x80 : 0x00)); 00088 00089 uint_least8_t status; 00090 TRY_VALUE(status, pollBusy()); 00091 00092 TripletData data; 00093 data.readBit = ((status & status_SBR) == status_SBR); 00094 data.readBitComplement = ((status & status_TSB) == status_TSB); 00095 data.writeBit = ((status & status_DIR) == status_DIR); 00096 return data; 00097 } 00098 00099 Result<void> DS2482_DS2484::reset() { 00100 // 1-Wire reset (Case B) 00101 // S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P 00102 // \--------/ 00103 // Repeat until 1WB bit has changed to 0 00104 // [] indicates from slave 00105 00106 TRY(sendCommand(0xB4)); 00107 00108 uint_least8_t status; 00109 TRY_VALUE(status, pollBusy()); 00110 00111 if ((status & status_SD) == status_SD) { 00112 return ShortDetectedError; 00113 } 00114 if ((status & status_PPD) != status_PPD) { 00115 return NoSlaveError; 00116 } 00117 00118 return none; 00119 } 00120 00121 Result<bool> DS2482_DS2484::touchBitSetLevel(bool sendBit, Level afterLevel) { 00122 // 1-Wire bit (Case B) 00123 // S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P 00124 // \--------/ 00125 // Repeat until 1WB bit has changed to 0 00126 // [] indicates from slave 00127 // BB indicates byte containing bit value in msbit 00128 00129 TRY(configureLevel(afterLevel)); 00130 TRY(sendCommand(0x87, sendBit ? 0x80 : 0x00)); 00131 uint_least8_t status; 00132 TRY_VALUE(status, pollBusy()); 00133 return (status & status_SBR) == status_SBR; 00134 } 00135 00136 Result<void> DS2482_DS2484::writeByteSetLevel(uint_least8_t sendByte, 00137 Level afterLevel) { 00138 // 1-Wire Write Byte (Case B) 00139 // S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P 00140 // \--------/ 00141 // Repeat until 1WB bit has changed to 0 00142 // [] indicates from slave 00143 // DD data to write 00144 00145 TRY(configureLevel(afterLevel)); 00146 TRY(sendCommand(0xA5, sendByte)); 00147 TRY(pollBusy()); 00148 return none; 00149 } 00150 00151 Result<uint_least8_t> DS2482_DS2484::readByteSetLevel(Level afterLevel) { 00152 // 1-Wire Read Bytes (Case C) 00153 // S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A 00154 // \--------/ 00155 // Repeat until 1WB bit has changed to 0 00156 // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P 00157 // 00158 // [] indicates from slave 00159 // DD data read 00160 00161 TRY(configureLevel(afterLevel)); 00162 TRY(sendCommand(0x96)); 00163 TRY(pollBusy()); 00164 return readRegister(0xE1); 00165 } 00166 00167 Result<void> DS2482_DS2484::setSpeed(Speed newSpeed) { 00168 // Check if supported speed 00169 if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) { 00170 return InvalidSpeedError; 00171 } 00172 // Check if requested speed is already set 00173 if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) { 00174 return none; 00175 } 00176 // Set the speed 00177 return writeConfig(Config(curConfig).set1WS(newSpeed == OverdriveSpeed)); 00178 } 00179 00180 Result<void> DS2482_DS2484::setLevel(Level newLevel) { 00181 if (newLevel == StrongLevel) { 00182 return InvalidLevelError; 00183 } 00184 00185 return configureLevel(newLevel); 00186 } 00187 00188 Result<void> DS2482_DS2484::writeConfig(Config config) { 00189 uint_least8_t configBuf = 00190 ((config.readByte() ^ 0xF) << 4) | config.readByte(); 00191 TRY(sendCommand(0xD2, configBuf)); 00192 00193 TRY_VALUE(configBuf, readRegister(0xC3)); 00194 00195 if (configBuf != config.readByte()) { 00196 return HardwareError; 00197 } 00198 00199 curConfig = config; 00200 return none; 00201 } 00202 00203 Result<uint_least8_t> DS2482_DS2484::readRegister(uint_least8_t reg) const { 00204 TRY(sendCommand(0xE1, reg)); 00205 return readRegister(); 00206 } 00207 00208 Result<uint_least8_t> DS2482_DS2484::readRegister() const { 00209 uint_least8_t buf; 00210 TRY(master->readPacket(address_, make_span(&buf, 1), I2CMaster::Stop)); 00211 return buf; 00212 } 00213 00214 Result<uint_least8_t> DS2482_DS2484::pollBusy() { 00215 const int pollLimit = 200; 00216 00217 int pollCount = 0; 00218 uint_least8_t status; 00219 do { 00220 TRY_VALUE(status, readRegister()); 00221 if (pollCount++ >= pollLimit) { 00222 return HardwareError; 00223 } 00224 } while ((status & status_1WB) == status_1WB); 00225 return status; 00226 } 00227 00228 Result<void> DS2482_DS2484::configureLevel(Level level) { 00229 // Check if supported level 00230 if (!((level == NormalLevel) || (level == StrongLevel))) { 00231 return InvalidLevelError; 00232 } 00233 // Check if requested level already set 00234 if (curConfig.getSPU() == (level == StrongLevel)) { 00235 return none; 00236 } 00237 // Set the level 00238 return writeConfig(Config(curConfig).setSPU(level == StrongLevel)); 00239 } 00240 00241 Result<void> DS2482_DS2484::sendCommand (uint_least8_t cmd) const { 00242 return master->writePacket(address_, make_span(&cmd, 1), I2CMaster::Stop); 00243 } 00244 00245 Result<void> DS2482_DS2484::sendCommand (uint_least8_t cmd, 00246 uint_least8_t param) const { 00247 const uint_least8_t buf[] = {cmd, param}; 00248 return master->writePacket(address_, buf, I2CMaster::Stop); 00249 } 00250 00251 const error_category & DS2482_DS2484::errorCategory() { 00252 static class : public error_category { 00253 public: 00254 virtual const char * name() const { 00255 return "MaximInterfaceDevices.DS2482_DS2484"; 00256 } 00257 00258 virtual std::string message(int condition) const { 00259 switch (condition) { 00260 case HardwareError: 00261 return "Hardware Error"; 00262 00263 case ArgumentOutOfRangeError: 00264 return "Argument Out of Range Error"; 00265 } 00266 return defaultErrorMessage(condition); 00267 } 00268 } instance; 00269 return instance; 00270 } 00271 00272 Result<void> DS2482_800::selectChannel(int channel) { 00273 // Channel Select (Case A) 00274 // S AD,0 [A] CHSL [A] CC [A] Sr AD,1 [A] [RR] A\ P 00275 // [] indicates from slave 00276 // CC channel value 00277 // RR channel read back 00278 00279 uint_least8_t ch; 00280 uint_least8_t ch_read; 00281 switch (channel) { 00282 case 0: 00283 ch = 0xF0; 00284 ch_read = 0xB8; 00285 break; 00286 00287 case 1: 00288 ch = 0xE1; 00289 ch_read = 0xB1; 00290 break; 00291 00292 case 2: 00293 ch = 0xD2; 00294 ch_read = 0xAA; 00295 break; 00296 00297 case 3: 00298 ch = 0xC3; 00299 ch_read = 0xA3; 00300 break; 00301 00302 case 4: 00303 ch = 0xB4; 00304 ch_read = 0x9C; 00305 break; 00306 00307 case 5: 00308 ch = 0xA5; 00309 ch_read = 0x95; 00310 break; 00311 00312 case 6: 00313 ch = 0x96; 00314 ch_read = 0x8E; 00315 break; 00316 00317 case 7: 00318 ch = 0x87; 00319 ch_read = 0x87; 00320 break; 00321 00322 default: 00323 return ArgumentOutOfRangeError; 00324 }; 00325 00326 TRY(sendCommand(0xC3, ch)); 00327 TRY_VALUE(ch, readRegister()); 00328 // check for failure due to incorrect read back of channel 00329 if (ch != ch_read) { 00330 return HardwareError; 00331 } 00332 00333 return none; 00334 } 00335 00336 Result<void> DS2484::adjustPort(PortParameter param, int val) { 00337 if (val < 0 || val > 15) { 00338 return ArgumentOutOfRangeError; 00339 } 00340 00341 TRY(sendCommand(0xC3, (param << 4) | val)); 00342 00343 uint_least8_t portConfig = val + 1; 00344 for (int reads = -1; reads < param; ++reads) { 00345 TRY_VALUE(portConfig, readRegister()); 00346 } 00347 if (val != portConfig) { 00348 return HardwareError; 00349 } 00350 00351 return none; 00352 } 00353 00354 } // namespace MaximInterfaceDevices
Generated on Tue Jul 12 2022 11:13:06 by 1.7.2