Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2482_DS2484.cpp Source File

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