Maxim Integrated / OneWire

Dependents:   MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2465.cpp Source File

DS2465.cpp

00001 /******************************************************************//**
00002 * Copyright (C) 2016 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 "Masters/DS2465/DS2465.h"
00034 #include "I2C.h"
00035 #include "wait_api.h"
00036 
00037 using namespace OneWire;
00038 
00039 #define I2C_WRITE 0
00040 #define I2C_READ 1
00041 
00042 /// DS2465 Commands
00043 enum Command
00044 {
00045     DeviceResetCmd = 0xF0,
00046     WriteDeviceConfigCmd = 0xD2,
00047     OwResetCmd = 0xB4,
00048     OwWriteByteCmd = 0xA5,
00049     OwReadByteCmd = 0x96,
00050     OwSingleBitCmd = 0x87,
00051     OwTripletCmd = 0x78,
00052     OwTransmitBlockCmd = 0x69,
00053     OwReceiveBlockCmd = 0xE1,
00054     CopyScratchpadCmd = 0x5A,
00055     ComputeSlaveSecretCmd = 0x4B,
00056     ComputeSlaveAuthMacCmd = 0x3C,
00057     ComputeSlaveWriteMacCmd = 0x2D,
00058     ComputeNextMasterSecretCmd = 0x1E,
00059     SetProtectionCmd = 0x0F
00060 };
00061 
00062 /// DS2465 Status Bits
00063 enum StatusBit
00064 {
00065     Status_1WB = 0x01,
00066     Status_PPD = 0x02,
00067     Status_SD = 0x04,
00068     Status_LL = 0x08,
00069     Status_RST = 0x10,
00070     Status_SBR = 0x20,
00071     Status_TSB = 0x40,
00072     Status_DIR = 0x80
00073 };
00074 
00075 static const int I2C_WRITE_OK = 1;
00076 static const uint8_t maxBlockSize = 63;
00077 
00078 uint8_t DS2465::Config::readByte() const
00079 {
00080     uint8_t config = 0;
00081     if (get1WS ())
00082     {
00083         config |= 0x08;
00084     }
00085     if (getSPU ())
00086     {
00087         config |= 0x04;
00088     }
00089     if (getPDN ())
00090     {
00091         config |= 0x02;
00092     }
00093     if (getAPU ())
00094     {
00095         config |= 0x01;
00096     }
00097     return config;
00098 }
00099 
00100 uint8_t DS2465::Config::writeByte() const
00101 {
00102     uint8_t config = readByte();
00103     return ((~config << 4) | config);
00104 }
00105 
00106 void DS2465::Config::reset()
00107 {
00108     set1WS(false);
00109     setSPU(false);
00110     setPDN(false);
00111     setAPU(true);
00112 }
00113 
00114 DS2465::DS2465 (mbed::I2C & I2C_interface, uint8_t I2C_address)
00115     : m_I2C_interface(I2C_interface), m_I2C_address(I2C_address)
00116 {
00117 
00118 }
00119 
00120 OneWireMaster::CmdResult DS2465::OWInitMaster()
00121 {
00122     OneWireMaster::CmdResult result;
00123 
00124     // reset DS2465 
00125     result = reset();
00126     if (result != OneWireMaster::Success)
00127     {
00128         return result;
00129     }
00130 
00131     // write the default configuration setup
00132     Config defaultConfig;
00133     result = writeConfig(defaultConfig, true);
00134     return result;
00135 }
00136 
00137 OneWireMaster::CmdResult DS2465::computeNextMasterSecret(bool swap, unsigned int pageNum, PageRegion region)
00138 {
00139     uint8_t command[2] = { ComputeNextMasterSecretCmd, (uint8_t)(swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
00140     return writeMemory(CommandReg, command, 2);
00141 }
00142 
00143 OneWireMaster::CmdResult DS2465::computeWriteMac(bool regwrite, bool swap, unsigned int pageNum, unsigned int segmentNum) const
00144 {
00145     uint8_t command[2] = { ComputeSlaveWriteMacCmd, (uint8_t)((regwrite << 7) | (swap << 6) | (pageNum << 4) | segmentNum) };
00146     return cWriteMemory(CommandReg, command, 2);
00147 }
00148 
00149 OneWireMaster::CmdResult DS2465::computeAuthMac(bool swap, unsigned int pageNum, PageRegion region) const
00150 {
00151     uint8_t command[2] = { ComputeSlaveAuthMacCmd, (uint8_t)(swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
00152     return cWriteMemory(CommandReg, command, 2);
00153 }
00154 
00155 OneWireMaster::CmdResult DS2465::computeSlaveSecret(bool swap, unsigned int pageNum, PageRegion region)
00156 {
00157     uint8_t command[2] = { ComputeSlaveSecretCmd, (uint8_t)(swap ? (0xC8 | (pageNum << 4) | region) : 0xBF) };
00158     return writeMemory(CommandReg, command, 2);
00159 }
00160 
00161 ISha256MacCoproc::CmdResult DS2465::setMasterSecret(const Secret & masterSecret)
00162 {
00163     OneWireMaster::CmdResult result;
00164     result = writeMemory(Scratchpad, masterSecret.data(), masterSecret.size());
00165     if (result == OneWireMaster::Success)
00166     {
00167         result = copyScratchpadToSecret();
00168     }
00169     if (result == OneWireMaster::Success)
00170     {
00171         wait_ms(eepromPageWriteDelayMs);
00172     }
00173     return (result == OneWireMaster::Success ? ISha256MacCoproc::Success : ISha256MacCoproc::OperationFailure);
00174 }
00175 
00176 ISha256MacCoproc::CmdResult DS2465::computeWriteMac(const WriteMacData & writeMacData, Mac & mac) const
00177 {
00178     OneWireMaster::CmdResult result;
00179     // Write input data to scratchpad
00180     result = writeScratchpad(writeMacData.data(), writeMacData.size());
00181     // Compute MAC
00182     if (result == OneWireMaster::Success)
00183     {
00184         result = computeWriteMac(false);
00185     }
00186     if (result == OneWireMaster::Success)
00187     {
00188         wait_ms(shaComputationDelayMs);
00189         // Read MAC from register
00190         result = readMemory(MacReadoutReg, mac.data(), mac.size(), true);
00191     }
00192     return (result == OneWireMaster::Success ? ISha256MacCoproc::Success : ISha256MacCoproc::OperationFailure);
00193 }
00194 
00195 ISha256MacCoproc::CmdResult DS2465::computeAuthMac(const DevicePage & devicePage, const DeviceScratchpad & challenge, const AuthMacData & authMacData, Mac & mac) const
00196 {
00197     OneWireMaster::CmdResult result;
00198     int addr = Scratchpad;
00199     // Write input data to scratchpad
00200     result = cWriteMemory(addr, devicePage.data(), devicePage.size());
00201     if (result == OneWireMaster::Success)
00202     {
00203         addr += devicePage.size();
00204         result = cWriteMemory(addr, challenge.data(), challenge.size());
00205     }
00206     if (result == OneWireMaster::Success)
00207     {
00208         addr += challenge.size();
00209         result = cWriteMemory(addr, authMacData.data(), authMacData.size());
00210     }
00211     // Compute MAC
00212     if (result == OneWireMaster::Success)
00213     {
00214         result = computeAuthMac();
00215     }
00216     if (result == OneWireMaster::Success)
00217     {
00218         wait_ms(shaComputationDelayMs * 2);
00219         // Read MAC from register
00220         result = readMemory(MacReadoutReg, mac.data(), mac.size(), true);
00221     }
00222     return (result == OneWireMaster::Success ? ISha256MacCoproc::Success : ISha256MacCoproc::OperationFailure);
00223 }
00224 
00225 ISha256MacCoproc::CmdResult DS2465::computeSlaveSecret(const DevicePage & devicePage, const DeviceScratchpad & deviceScratchpad, const SlaveSecretData & slaveSecretData)
00226 {
00227     OneWireMaster::CmdResult result;
00228     int addr = Scratchpad;
00229     // Write input data to scratchpad
00230     result = writeMemory(addr, devicePage.data(), devicePage.size());
00231     if (result == OneWireMaster::Success)
00232     {
00233         addr += devicePage.size();
00234         result = writeMemory(addr, deviceScratchpad.data(), deviceScratchpad.size());
00235     }
00236     if (result == OneWireMaster::Success)
00237     {
00238         addr += deviceScratchpad.size();
00239         result = writeMemory(addr, slaveSecretData.data(), slaveSecretData.size());
00240     }
00241     // Compute secret
00242     if (result == OneWireMaster::Success)
00243     {
00244         result = computeSlaveSecret();
00245     }
00246     if (result == OneWireMaster::Success)
00247     {
00248         wait_ms(shaComputationDelayMs * 2);
00249     }
00250     return (result == OneWireMaster::Success ? ISha256MacCoproc::Success : ISha256MacCoproc::OperationFailure);
00251 }
00252 
00253 OneWireMaster::CmdResult DS2465::copyScratchpad(bool destSecret, unsigned int pageNum, bool notFull, unsigned int segmentNum)
00254 {
00255     uint8_t command[2] = { CopyScratchpadCmd, (uint8_t)(destSecret ? 0 : (0x80 | (pageNum << 4) | (notFull << 3) | segmentNum)) };
00256     return writeMemory(CommandReg, command, 2);
00257 }
00258 
00259 OneWireMaster::CmdResult DS2465::configureLevel(OWLevel level)
00260 {
00261     OneWireMaster::CmdResult result;
00262     if (m_curConfig.getSPU () != (level == StrongLevel))
00263     {
00264         Config newConfig = m_curConfig;
00265         newConfig.setSPU(level == StrongLevel);
00266         result = writeConfig(newConfig, true);
00267     }
00268     else
00269     {
00270         result = OneWireMaster::Success;
00271     }
00272     return result;
00273 }
00274 
00275 OneWireMaster::CmdResult DS2465::OWSetLevel (OWLevel newLevel)
00276 {
00277     if (newLevel == StrongLevel)
00278     {
00279         return OneWireMaster::OperationFailure;
00280     }
00281 
00282     return configureLevel(newLevel);
00283 }
00284 
00285 OneWireMaster::CmdResult DS2465::OWSetSpeed(OWSpeed newSpeed)
00286 {
00287     // Requested speed is already set
00288     if (m_curConfig.get1WS () == (newSpeed == OverdriveSpeed))
00289     {
00290         return OneWireMaster::Success;
00291     }
00292 
00293     // set the speed
00294     Config newConfig = m_curConfig;
00295     newConfig.set1WS(newSpeed == OverdriveSpeed);
00296 
00297     // write the new config
00298     return writeConfig(newConfig, true);
00299 }
00300 
00301 OneWireMaster::CmdResult DS2465::OWTriplet(SearchDirection & searchDirection, uint8_t & sbr, uint8_t & tsb)
00302 {
00303     // 1-Wire Triplet (Case B)
00304     //   S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
00305     //                                         \--------/        
00306     //                           Repeat until 1WB bit has changed to 0
00307     //  [] indicates from slave
00308     //  SS indicates byte containing search direction bit value in msbit
00309 
00310     OneWireMaster::CmdResult result;
00311     uint8_t command[2] = { OwTripletCmd, (uint8_t)((searchDirection == WriteOne) ? 0x80 : 0x00) };
00312     result = writeMemory(CommandReg, command, 2);
00313     if (result == OneWireMaster::Success)
00314     {
00315         uint8_t status;
00316         result = pollBusy(&status);
00317         if (result == OneWireMaster::Success)
00318         {
00319             // check bit results in status byte
00320             sbr = ((status & Status_SBR) == Status_SBR);
00321             tsb = ((status & Status_TSB) == Status_TSB);
00322             searchDirection = ((status & Status_DIR) == Status_DIR) ? WriteOne : WriteZero;
00323         }
00324     }
00325     return result;
00326 }
00327 
00328 OneWireMaster::CmdResult DS2465::OWReadBlock(uint8_t *recvBuf, size_t recvLen)
00329 {
00330     // 1-Wire Receive Block (Case A)
00331     //   S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P
00332     //  [] indicates from slave
00333     //  PR indicates byte containing parameter
00334 
00335     OneWireMaster::CmdResult result = OneWireMaster::Success;
00336     for (size_t i = 0; (i < recvLen) && (result == OneWireMaster::Success); i += maxBlockSize)
00337     {
00338         uint8_t command[2] = { OwReceiveBlockCmd, std::min(static_cast<uint8_t>(recvLen - i), maxBlockSize) };
00339         result = writeMemory(CommandReg, command, 2);
00340         if (result == OneWireMaster::Success)
00341         {
00342             result = pollBusy();
00343         }
00344         if (result == OneWireMaster::Success)
00345         {
00346             result = readMemory(Scratchpad, recvBuf + i, command[1], false);
00347         }
00348     }
00349     return result;
00350 }
00351 
00352 OneWireMaster::CmdResult DS2465::OWWriteBlock(const uint8_t *sendBuf, size_t sendLen)
00353 {
00354     OneWireMaster::CmdResult result = OneWireMaster::Success;
00355     for (size_t i = 0; (i < sendLen) && (result == OneWireMaster::Success); i += maxBlockSize)
00356     {
00357         uint8_t command[2] = { OwTransmitBlockCmd, std::min(static_cast<uint8_t>(sendLen - i), maxBlockSize) };
00358 
00359         // prefill scratchpad with required data
00360         result = writeMemory(Scratchpad, sendBuf + i, command[1]);
00361 
00362         // 1-Wire Transmit Block (Case A)
00363         //   S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
00364         //  [] indicates from slave
00365         //  PR indicates byte containing parameter
00366         if (result == OneWireMaster::Success)
00367         {
00368             result = writeMemory(CommandReg, command, 2);
00369         }
00370         if (result == OneWireMaster::Success)
00371         {
00372             result = pollBusy();
00373         }
00374     }
00375     return result;
00376 }
00377 
00378 OneWireMaster::CmdResult DS2465::OWWriteBlockMac()
00379 {
00380     // 1-Wire Transmit Block (Case A)
00381     //   S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
00382     //  [] indicates from slave
00383     //  PR indicates byte containing parameter
00384 
00385     uint8_t command[2] = { OwTransmitBlockCmd, 0xFF };
00386     OneWireMaster::CmdResult result = writeMemory(CommandReg, command, 2);
00387     if (result == OneWireMaster::Success)
00388     {
00389         result = pollBusy();
00390     }
00391     return result;
00392 }
00393 
00394 OneWireMaster::CmdResult DS2465::OWReadByteSetLevel(uint8_t & recvByte, OWLevel afterLevel)
00395 {
00396     // 1-Wire Read Bytes (Case C)
00397     //   S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A 
00398     //                                                  \--------/        
00399     //                     Repeat until 1WB bit has changed to 0
00400     //   Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
00401     //                                  
00402     //  [] indicates from slave
00403     //  DD data read
00404 
00405     OneWireMaster::CmdResult result;
00406     uint8_t buf;
00407 
00408     result = configureLevel(afterLevel);
00409     if (result != OneWireMaster::Success)
00410     {
00411         return result;
00412     }
00413 
00414     buf = OwReadByteCmd;
00415     result = writeMemory(CommandReg, &buf, 1);
00416 
00417     if (result == OneWireMaster::Success)
00418     {
00419         result = pollBusy();
00420     }
00421 
00422     if (result == OneWireMaster::Success)
00423     {
00424         result = readMemory(ReadDataReg, &buf, 1);
00425     }
00426 
00427     if (result == OneWireMaster::Success)
00428     {
00429         recvByte = buf;
00430     }
00431 
00432     return result;
00433 }
00434 
00435 OneWireMaster::CmdResult DS2465::OWWriteByteSetLevel(uint8_t sendByte, OWLevel afterLevel)
00436 {
00437     // 1-Wire Write Byte (Case B)
00438     //   S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
00439     //                                                           \--------/        
00440     //                             Repeat until 1WB bit has changed to 0
00441     //  [] indicates from slave
00442     //  DD data to write
00443 
00444     OneWireMaster::CmdResult result;
00445 
00446     result = configureLevel(afterLevel);
00447     if (result != OneWireMaster::Success)
00448     {
00449         return result;
00450     }
00451 
00452     uint8_t command[2] = { OwWriteByteCmd, sendByte };
00453 
00454     result = writeMemory(CommandReg, command, 2);
00455     if (result == OneWireMaster::Success)
00456     {
00457         result = pollBusy();
00458     }
00459 
00460     return result;
00461 }
00462 
00463 OneWireMaster::CmdResult DS2465::OWTouchBitSetLevel(uint8_t & sendRecvBit, OWLevel afterLevel)
00464 {
00465     // 1-Wire bit (Case B)
00466     //   S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
00467     //                                                          \--------/        
00468     //                           Repeat until 1WB bit has changed to 0
00469     //  [] indicates from slave
00470     //  BB indicates byte containing bit value in msbit
00471 
00472     OneWireMaster::CmdResult result;
00473 
00474     result = configureLevel(afterLevel);
00475     if (result != OneWireMaster::Success)
00476     {
00477         return result;
00478     }
00479 
00480     uint8_t command[2] = { OwSingleBitCmd, (uint8_t)(sendRecvBit ? 0x80 : 0x00) };
00481     uint8_t status;
00482 
00483     result = writeMemory(CommandReg, command, 2);
00484 
00485     if (result == OneWireMaster::Success)
00486     {
00487         result = pollBusy(&status);
00488     }
00489 
00490     if (result == OneWireMaster::Success)
00491     {
00492         sendRecvBit = (status & Status_SBR);
00493     }
00494 
00495     return result;
00496 }
00497 
00498 OneWireMaster::CmdResult DS2465::cWriteMemory(uint8_t addr, const uint8_t * buf, size_t bufLen) const
00499 {
00500     // Write SRAM (Case A)
00501     //   S AD,0 [A] VSA [A] DD [A]  P
00502     //                      \-----/
00503     //                        Repeat for each data byte
00504     //  [] indicates from slave
00505     //  VSA valid SRAM memory address
00506     //  DD memory data to write
00507 
00508     m_I2C_interface.start();
00509     if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
00510     {
00511         m_I2C_interface.stop();
00512         return OneWireMaster::CommunicationWriteError;
00513     }
00514     if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
00515     {
00516         m_I2C_interface.stop();
00517         return OneWireMaster::CommunicationWriteError;
00518     }
00519     // loop to write each byte
00520     for (size_t i = 0; i < bufLen; i++)
00521     {
00522         if (m_I2C_interface.write(buf[i]) != I2C_WRITE_OK)
00523         {
00524             m_I2C_interface.stop();
00525             return OneWireMaster::CommunicationWriteError;
00526         }
00527     }
00528     m_I2C_interface.stop();
00529 
00530     return OneWireMaster::Success;
00531 }
00532 
00533 OneWireMaster::CmdResult DS2465::readMemory(uint8_t addr, uint8_t * buf, size_t bufLen, bool skipSetPointer) const
00534 {
00535     // Read (Case A)
00536     //   S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
00537     //                                 \-----/
00538     //                                   Repeat for each data byte, NAK last byte
00539     //  [] indicates from slave
00540     //  MA memory address
00541     //  DD memory data read
00542 
00543     m_I2C_interface.start();
00544     if (!skipSetPointer)
00545     {
00546         if (m_I2C_interface.write((m_I2C_address | I2C_WRITE)) != I2C_WRITE_OK)
00547         {
00548             m_I2C_interface.stop();
00549             return OneWireMaster::CommunicationWriteError;
00550         }
00551         if (m_I2C_interface.write(addr) != I2C_WRITE_OK)
00552         {
00553             m_I2C_interface.stop();
00554             return OneWireMaster::CommunicationWriteError;
00555         }
00556         m_I2C_interface.start();
00557     }
00558 
00559     if (m_I2C_interface.write((m_I2C_address | I2C_READ)) != I2C_WRITE_OK)
00560     {
00561         m_I2C_interface.stop();
00562         return OneWireMaster::CommunicationWriteError;
00563     }
00564     // loop to read each byte, NAK last byte
00565     for (size_t i = 0; i < bufLen; i++)
00566     {
00567         buf[i] = m_I2C_interface.read((i == (bufLen - 1)) ? mbed::I2C::NoACK : mbed::I2C::ACK);
00568     }
00569     m_I2C_interface.stop();
00570 
00571     return OneWireMaster::Success;
00572 }
00573 
00574 OneWireMaster::CmdResult DS2465::writeConfig(const Config & config, bool verify)
00575 {
00576     uint8_t configBuf;
00577     OneWireMaster::CmdResult result;
00578 
00579     configBuf = config.writeByte();
00580     result = writeMemory(ConfigReg, &configBuf, 1);
00581     if (verify)
00582     {
00583         if (result == OneWireMaster::Success)
00584         {
00585             result = readMemory(ConfigReg, &configBuf, 1);
00586         }
00587         if (result == OneWireMaster::Success)
00588         {
00589             if (configBuf != config.readByte())
00590                 result = OneWireMaster::OperationFailure;
00591         }
00592     }
00593 
00594     if (result == OneWireMaster::Success)
00595     {
00596         m_curConfig = config;
00597     }
00598 
00599     return result;
00600 }
00601 
00602 OneWireMaster::CmdResult DS2465::pollBusy(uint8_t * pStatus)
00603 {
00604     const unsigned int pollLimit = 200;
00605 
00606     OneWireMaster::CmdResult result;
00607     uint8_t status;
00608     unsigned int pollCount = 0;
00609 
00610     do
00611     {
00612         result = readMemory(StatusReg, &status, 1, true);
00613         if (result != OneWireMaster::Success)
00614         {
00615             return result;
00616         }
00617         if (pStatus != NULL)
00618         {
00619             *pStatus = status;
00620         }
00621         if (pollCount++ >= pollLimit)
00622         {
00623             return OneWireMaster::TimeoutError;
00624         }
00625     } while (status & Status_1WB);
00626 
00627     return OneWireMaster::Success;
00628 }
00629 
00630 OneWireMaster::CmdResult DS2465::OWReset()
00631 {
00632     // 1-Wire reset (Case B)
00633     //   S AD,0 [A] CommandReg  [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
00634     //                                                  \--------/        
00635     //                       Repeat until 1WB bit has changed to 0
00636     //  [] indicates from slave
00637 
00638     OneWireMaster::CmdResult result;
00639     uint8_t buf;
00640 
00641     buf = OwResetCmd;
00642     result = writeMemory(CommandReg, &buf, 1);
00643 
00644     if (result == OneWireMaster::Success)
00645     {
00646         result = pollBusy(&buf);
00647     }
00648 
00649     if (result == OneWireMaster::Success)
00650     {
00651         // check for presence detect
00652         if ((buf & Status_PPD) != Status_PPD)
00653         {
00654             result = OneWireMaster::OperationFailure;
00655         }
00656     }
00657 
00658     return result;
00659 }
00660 
00661 OneWireMaster::CmdResult DS2465::reset()
00662 {
00663     // Device Reset
00664     //   S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
00665     //  [] indicates from slave
00666     //  SS status byte to read to verify state
00667 
00668     OneWireMaster::CmdResult result;
00669     uint8_t buf;
00670 
00671     buf = DeviceResetCmd;
00672     result = writeMemory(CommandReg, &buf, 1);
00673 
00674     if (result == OneWireMaster::Success)
00675     {
00676         result = readMemory(StatusReg, &buf, 1, true);
00677     }
00678 
00679     if (result == OneWireMaster::Success)
00680     {
00681         if ((buf & 0xF7) != 0x10)
00682         {
00683             result = OneWireMaster::OperationFailure;
00684         }
00685     }
00686 
00687     if (result == OneWireMaster::Success)
00688     {
00689         OWReset(); // do a command to get 1-Wire master reset out of holding state
00690     }
00691 
00692     return result;
00693 }