Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2482_DS2484.cpp Source File

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