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 DS28E15_22_25.cpp Source File

DS28E15_22_25.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 <algorithm>
00034 #include <MaximInterfaceCore/Crc.hpp>
00035 #include <MaximInterfaceCore/Error.hpp>
00036 #include "DS28E15_22_25.hpp"
00037 
00038 #define TRY MaximInterfaceCore_TRY
00039 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE
00040 
00041 namespace MaximInterfaceDevices {
00042 
00043 using namespace Core;
00044 using std::copy;
00045 
00046 static const int shaComputationDelayMs = 3;
00047 static const int eepromWriteDelayMs = 10;
00048 static inline int secretEepromWriteDelayMs(bool lowPower) {
00049   return lowPower ? 200 : 100;
00050 }
00051 
00052 static const int ds28e22_25_pagesPerBlock = 2;
00053 
00054 static Result<void>
00055 writeDataWithCrc(OneWireMaster & master, span<const uint_least8_t> data,
00056                  OneWireMaster::Level level = OneWireMaster::NormalLevel,
00057                  uint_fast16_t crcStart = 0) {
00058   TRY(master.writeBlock(data));
00059   uint_least8_t response[2];
00060   TRY_VALUE(response[0], master.readByte());
00061   TRY_VALUE(response[1], master.readByteSetLevel(level));
00062   if (calculateCrc16(calculateCrc16(crcStart, data), response) != 0xB001) {
00063     return DS28E15_22_25::CrcError;
00064   }
00065   return none;
00066 }
00067 
00068 const int DS28E15_22_25::segmentsPerPage;
00069 
00070 DS28E15_22_25::AuthenticationData &
00071 DS28E15_22_25::AuthenticationData::setAnonymousRomId() {
00072   std::fill(romId().begin(), romId().end(), 0xFF);
00073   return *this;
00074 }
00075 
00076 Result<void>
00077 DS28E15_22_25::writeCommandWithCrc(Command command, uint_least8_t parameter,
00078                                    OneWireMaster::Level level) const {
00079   Result<void> result = selectRom(*master);
00080   if (result) {
00081     const uint_least8_t data[] = {static_cast<uint_least8_t>(command),
00082                                   parameter};
00083     result = writeDataWithCrc(*master, data, level);
00084   }
00085   return result;
00086 }
00087 
00088 static Result<void> readDataWithCrc(OneWireMaster & master,
00089                                     span<uint_least8_t> data) {
00090   Result<void> result = master.readBlock(data);
00091   if (!result) {
00092     return result;
00093   }
00094   uint_least8_t response[2];
00095   result = master.readBlock(response);
00096   if (!result) {
00097     return result;
00098   }
00099   if (calculateCrc16(calculateCrc16(data), response) != 0xB001) {
00100     result = DS28E15_22_25::CrcError;
00101   }
00102   return result;
00103 }
00104 
00105 static Result<void> readCsByte(OneWireMaster & master) {
00106   const Result<uint_least8_t> response = master.readByte();
00107   if (!response) {
00108     return response.error();
00109   }
00110   return (response.value() == 0xAA) ? makeResult(none)
00111                                     : DS28E15_22_25::OperationFailure;
00112 }
00113 
00114 static Result<void> releaseSequence(OneWireMaster & master, Sleep & sleep,
00115                                     int delayTimeMs) {
00116   Result<void> result = master.writeBytePower(0xAA);
00117   if (!result) {
00118     return result;
00119   }
00120   sleep(delayTimeMs);
00121   result = master.setLevel(OneWireMaster::NormalLevel);
00122   if (!result) {
00123     return result;
00124   }
00125   return readCsByte(master);
00126 }
00127 
00128 DS28E15_22_25::BlockProtection &
00129 DS28E15_22_25::BlockProtection::setBlockNum(int blockNum) {
00130   status &= ~blockNumMask;
00131   status |= (blockNum & blockNumMask);
00132   return *this;
00133 }
00134 
00135 bool DS28E15_22_25::BlockProtection::noProtection() const {
00136   return !readProtection() && !writeProtection() && !eepromEmulation() &&
00137          !authProtection();
00138 }
00139 
00140 DS28E15_22_25::BlockProtection &
00141 DS28E15_22_25::BlockProtection::setReadProtection(bool readProtection) {
00142   if (readProtection) {
00143     status |= readProtectionMask;
00144   } else {
00145     status &= ~readProtectionMask;
00146   }
00147   return *this;
00148 }
00149 
00150 DS28E15_22_25::BlockProtection &
00151 DS28E15_22_25::BlockProtection::setWriteProtection(bool writeProtection) {
00152   if (writeProtection) {
00153     status |= writeProtectionMask;
00154   } else {
00155     status &= ~writeProtectionMask;
00156   }
00157   return *this;
00158 }
00159 
00160 DS28E15_22_25::BlockProtection &
00161 DS28E15_22_25::BlockProtection::setEepromEmulation(bool eepromEmulation) {
00162   if (eepromEmulation) {
00163     status |= eepromEmulationMask;
00164   } else {
00165     status &= ~eepromEmulationMask;
00166   }
00167   return *this;
00168 }
00169 
00170 DS28E15_22_25::BlockProtection &
00171 DS28E15_22_25::BlockProtection::setAuthProtection(bool authProtection) {
00172   if (authProtection) {
00173     status |= authProtectionMask;
00174   } else {
00175     status &= ~authProtectionMask;
00176   }
00177   return *this;
00178 }
00179 
00180 DS28E15_22_25::ProtectionWriteMacData::ProtectionWriteMacData()
00181     : result_(), oldProtection_(), newProtection_() {
00182   setOldProtection(oldProtection_);
00183   setNewProtection(newProtection_);
00184 }
00185 
00186 DS28E15_22_25::ProtectionWriteMacData &
00187 DS28E15_22_25::ProtectionWriteMacData::setOldProtection(
00188     BlockProtection oldProtection) {
00189   result_[oldProtectionIdx] = oldProtection.authProtection() ? 1 : 0;
00190   result_[oldProtectionIdx + 1] = oldProtection.eepromEmulation() ? 1 : 0;
00191   result_[oldProtectionIdx + 2] = oldProtection.writeProtection() ? 1 : 0;
00192   result_[oldProtectionIdx + 3] = oldProtection.readProtection() ? 1 : 0;
00193   oldProtection_ = oldProtection;
00194   return *this;
00195 }
00196 
00197 DS28E15_22_25::ProtectionWriteMacData &
00198 DS28E15_22_25::ProtectionWriteMacData::setNewProtection(
00199     BlockProtection newProtection) {
00200   result_[blockNumIdx] = newProtection.blockNum();
00201   result_[newProtectionIdx] = newProtection.authProtection() ? 1 : 0;
00202   result_[newProtectionIdx + 1] = newProtection.eepromEmulation() ? 1 : 0;
00203   result_[newProtectionIdx + 2] = newProtection.writeProtection() ? 1 : 0;
00204   result_[newProtectionIdx + 3] = newProtection.readProtection() ? 1 : 0;
00205   newProtection_ = newProtection;
00206   return *this;
00207 }
00208 
00209 Result<void>
00210 DS28E15_22_25::writeAuthBlockProtection(BlockProtection newProtection,
00211                                         Page::const_span mac) {
00212   Result<void> result =
00213       writeCommandWithCrc(AuthWriteBlockProtection, newProtection.statusByte(),
00214                           OneWireMaster::StrongLevel);
00215   if (!result) {
00216     return result;
00217   }
00218 
00219   sleep->invoke(shaComputationDelayMs);
00220   result = master->setLevel(OneWireMaster::NormalLevel);
00221   if (!result) {
00222     return result;
00223   }
00224 
00225   result = writeDataWithCrc(*master, mac);
00226   if (!result) {
00227     return result;
00228   }
00229 
00230   result = readCsByte(*master);
00231   if (!result) {
00232     return result;
00233   }
00234 
00235   result = releaseSequence(*master, *sleep, eepromWriteDelayMs);
00236   return result;
00237 }
00238 
00239 Result<void> DS28E15_22_25::writeBlockProtection(BlockProtection protection) {
00240   Result<void> result =
00241       writeCommandWithCrc(WriteBlockProtection, protection.statusByte());
00242   if (!result) {
00243     return result;
00244   }
00245 
00246   result = releaseSequence(*master, *sleep, eepromWriteDelayMs);
00247   return result;
00248 }
00249 
00250 Result<DS28E15_22_25::BlockProtection>
00251 DS28E15_22_25::doReadBlockProtection(int blockNum, Variant variant) const {
00252   uint_least8_t buffer = blockNum;
00253   if (variant == DS28E22 || variant == DS28E25) {
00254     buffer *= ds28e22_25_pagesPerBlock;
00255   }
00256   TRY(writeCommandWithCrc(ReadStatus, buffer));
00257   TRY_VALUE(buffer, master->readByte());
00258   return BlockProtection(buffer);
00259 }
00260 
00261 Result<DS28E15_22_25::Page::array>
00262 DS28E15_22_25::computeReadPageMac(int page_num, bool anon) const {
00263   Result<void> result =
00264       writeCommandWithCrc(ComputePageMac, (anon ? 0xE0 : 0x00) | page_num,
00265                           OneWireMaster::StrongLevel);
00266   if (!result) {
00267     return result.error();
00268   }
00269 
00270   sleep->invoke(shaComputationDelayMs * 2);
00271   result = master->setLevel(OneWireMaster::NormalLevel);
00272   if (!result) {
00273     return result.error();
00274   }
00275 
00276   result = readCsByte(*master);
00277   if (!result) {
00278     return result.error();
00279   }
00280 
00281   Page::array mac;
00282   result = readDataWithCrc(*master, mac);
00283   if (!result) {
00284     return result.error();
00285   }
00286 
00287   return mac;
00288 }
00289 
00290 Result<void> DS28E15_22_25::doComputeSecret(int page_num, bool lock,
00291                                             bool lowPower) {
00292   Result<void> result = writeCommandWithCrc(
00293       ComputeAndLockSecret, lock ? (0xE0 | page_num) : page_num);
00294   if (!result) {
00295     return result;
00296   }
00297 
00298   result = releaseSequence(*master, *sleep,
00299                            shaComputationDelayMs * 2 +
00300                                secretEepromWriteDelayMs(lowPower));
00301   return result;
00302 }
00303 
00304 Result<void> DS28E15_22_25::doWriteScratchpad(Page::const_span data,
00305                                               Variant variant) {
00306   const uint_least8_t parameter =
00307       (variant == DS28E22 || variant == DS28E25) ? 0x20 : 0x00;
00308   Result<void> result = writeCommandWithCrc(ReadWriteScratchpad, parameter);
00309   if (!result) {
00310     return result;
00311   }
00312 
00313   result = writeDataWithCrc(*master, data);
00314   return result;
00315 }
00316 
00317 Result<DS28E15_22_25::Page::array>
00318 DS28E15_22_25::doReadScratchpad(Variant variant) const {
00319   const uint_least8_t parameter =
00320       (variant == DS28E22 || variant == DS28E25) ? 0x2F : 0x0F;
00321   Result<void> result = writeCommandWithCrc(ReadWriteScratchpad, parameter);
00322   if (!result) {
00323     return result.error();
00324   }
00325 
00326   Page::array data;
00327   result = readDataWithCrc(*master, data);
00328   if (!result) {
00329     return result.error();
00330   }
00331 
00332   return data;
00333 }
00334 
00335 Result<void> DS28E15_22_25::doLoadSecret(bool lock, bool lowPower) {
00336   Result<void> result =
00337       writeCommandWithCrc(LoadAndLockSecret, lock ? 0xE0 : 0x00);
00338   if (!result) {
00339     return result;
00340   }
00341 
00342   result = releaseSequence(*master, *sleep, secretEepromWriteDelayMs(lowPower));
00343   return result;
00344 }
00345 
00346 Result<DS28E15_22_25::Page::array> DS28E15_22_25::readPage(int page) const {
00347   const Result<void> result = writeCommandWithCrc(ReadMemory, page);
00348   if (!result) {
00349     return result.error();
00350   }
00351 
00352   return continueReadPage();
00353 }
00354 
00355 Result<DS28E15_22_25::Page::array> DS28E15_22_25::continueReadPage() const {
00356   Page::array rdbuf;
00357   TRY(readDataWithCrc(*master, rdbuf));
00358   return rdbuf;
00359 }
00360 
00361 Result<void> DS28E15_22_25::doWriteAuthSegment(Segment::const_span newData,
00362                                                Page::const_span mac,
00363                                                Variant variant,
00364                                                bool continuing) {
00365   // CRC gets calculated with CS byte when continuing on DS28E22 and DS28E25.
00366   const uint_fast16_t crcStart =
00367       ((variant == DS28E22 || variant == DS28E25) && continuing)
00368           ? calculateCrc16(0xAA)
00369           : 0;
00370   Result<void> result =
00371       writeDataWithCrc(*master, newData, OneWireMaster::StrongLevel, crcStart);
00372   if (!result) {
00373     return result;
00374   }
00375 
00376   sleep->invoke(shaComputationDelayMs);
00377   result = master->setLevel(OneWireMaster::NormalLevel);
00378   if (!result) {
00379     return result;
00380   }
00381 
00382   result = writeDataWithCrc(*master, mac);
00383   if (!result) {
00384     return result;
00385   }
00386 
00387   result = readCsByte(*master);
00388   if (!result) {
00389     return result;
00390   }
00391 
00392   result = releaseSequence(*master, *sleep, eepromWriteDelayMs);
00393   return result;
00394 }
00395 
00396 Result<void> DS28E15_22_25::doWriteAuthSegment(int pageNum, int segmentNum,
00397                                                Segment::const_span newData,
00398                                                Page::const_span mac,
00399                                                Variant variant) {
00400   Result<void> result =
00401       writeCommandWithCrc(AuthWriteMemory, (segmentNum << 5) | pageNum);
00402   if (!result) {
00403     return result;
00404   }
00405 
00406   result = doWriteAuthSegment(newData, mac, variant, false);
00407   return result;
00408 }
00409 
00410 Result<void> DS28E15_22_25::doContinueWriteAuthSegment(
00411     Segment::const_span newData, Page::const_span mac, Variant variant) {
00412   return doWriteAuthSegment(newData, mac, variant, true);
00413 }
00414 
00415 Result<DS28E15_22_25::Segment::array>
00416 DS28E15_22_25::readSegment(int page, int segment) const {
00417   Result<void> result = writeCommandWithCrc(ReadMemory, (segment << 5) | page);
00418   if (!result) {
00419     return result.error();
00420   }
00421 
00422   return continueReadSegment();
00423 }
00424 
00425 Result<DS28E15_22_25::Segment::array>
00426 DS28E15_22_25::continueReadSegment() const {
00427   Segment::array data;
00428   TRY(master->readBlock(data));
00429   return data;
00430 }
00431 
00432 Result<void> DS28E15_22_25::writeSegment(int page, int block,
00433                                          Segment::const_span data) {
00434   Result<void> result = writeCommandWithCrc(WriteMemory, (block << 5) | page);
00435   if (!result) {
00436     return result;
00437   }
00438 
00439   result = continueWriteSegment(data);
00440   return result;
00441 }
00442 
00443 Result<void> DS28E15_22_25::continueWriteSegment(Segment::const_span data) {
00444   Result<void> result = writeDataWithCrc(*master, data);
00445   if (!result) {
00446     return result;
00447   }
00448 
00449   result = releaseSequence(*master, *sleep, eepromWriteDelayMs);
00450   return result;
00451 }
00452 
00453 Result<void>
00454 DS28E15_22_25::doReadAllBlockProtection(span<BlockProtection> protection,
00455                                         Variant variant) const {
00456   Result<void> result = writeCommandWithCrc(ReadStatus, 0);
00457   if (!result) {
00458     if (variant == DS28E22 || variant == DS28E25) {
00459       // Need to read extra data on DS28E22 to get CRC16.
00460       uint_least8_t buf[DS28E25::memoryPages];
00461       result = readDataWithCrc(*master, buf);
00462       if (!result) {
00463         const int blocks = ((variant == DS28E22) ? DS28E22::memoryPages
00464                                                  : DS28E25::memoryPages) /
00465                            ds28e22_25_pagesPerBlock;
00466         for (span<BlockProtection>::index_type i = 0;
00467              i < std::min<span<BlockProtection>::index_type>(protection.size(),
00468                                                              blocks);
00469              ++i) {
00470           protection[i].setStatusByte(
00471               (buf[i * ds28e22_25_pagesPerBlock] & 0xF0) | // Upper nibble
00472               ((buf[i * ds28e22_25_pagesPerBlock] & 0x0F) /
00473                ds28e22_25_pagesPerBlock)); // Lower nibble
00474         }
00475       }
00476     } else { // DS28E15
00477       uint_least8_t buf[DS28E15::protectionBlocks];
00478       result = readDataWithCrc(*master, buf);
00479       if (!result) {
00480         for (span<BlockProtection>::index_type i = 0;
00481              i < std::min<span<BlockProtection>::index_type>(
00482                      protection.size(), DS28E15::protectionBlocks);
00483              ++i) {
00484           protection[i].setStatusByte(buf[i]);
00485         }
00486       }
00487     }
00488   }
00489   return result;
00490 }
00491 
00492 const error_category & DS28E15_22_25::errorCategory() {
00493   static class : public error_category {
00494   public:
00495     virtual const char * name() const {
00496       return "MaximInterfaceDevices.DS28E15_22_25";
00497     }
00498 
00499     virtual std::string message(int condition) const {
00500       switch (condition) {
00501       case CrcError:
00502         return "CRC Error";
00503 
00504       case OperationFailure:
00505         return "Operation Failure";
00506       }
00507       return defaultErrorMessage(condition);
00508     }
00509   } instance;
00510   return instance;
00511 }
00512 
00513 Result<void> DS28E15_22_25::loadSecret(bool lock) {
00514   // Use worst-case low power timing if the device type is not known.
00515   return doLoadSecret(lock, true);
00516 }
00517 
00518 Result<void> DS28E15_22_25::computeSecret(int pageNum, bool lock) {
00519   // Use worst-case low power timing if the device type is not known.
00520   return doComputeSecret(pageNum, lock, true);
00521 }
00522 
00523 Result<DS28E15_22_25::Personality> DS28E15_22_25::readPersonality() const {
00524   Result<void> result = writeCommandWithCrc(ReadStatus, 0xE0);
00525   if (!result) {
00526     return result.error();
00527   }
00528 
00529   uint_least8_t data[4];
00530   result = readDataWithCrc(*master, data);
00531   if (!result) {
00532     return result.error();
00533   }
00534 
00535   Personality personality;
00536   personality.PB1 = data[0];
00537   personality.PB2 = data[1];
00538   personality.manId[0] = data[2];
00539   personality.manId[1] = data[3];
00540   return personality;
00541 }
00542 
00543 const int DS28EL15::memoryPages;
00544 const int DS28EL15::protectionBlocks;
00545 
00546 Result<void> DS28EL15::writeScratchpad(Page::const_span data) {
00547   return doWriteScratchpad(data, DS28E15);
00548 }
00549 
00550 Result<DS28E15_22_25::Page::array> DS28EL15::readScratchpad() const {
00551   return doReadScratchpad(DS28E15);
00552 }
00553 
00554 Result<DS28E15_22_25::BlockProtection>
00555 DS28EL15::readBlockProtection(int blockNum) const {
00556   return doReadBlockProtection(blockNum, DS28E15);
00557 }
00558 
00559 Result<void> DS28EL15::writeAuthSegment(int pageNum, int segmentNum,
00560                                         Segment::const_span newData,
00561                                         Page::const_span mac) {
00562   return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E15);
00563 }
00564 
00565 Result<void> DS28EL15::continueWriteAuthSegment(Segment::const_span newData,
00566                                                 Page::const_span mac) {
00567   return doContinueWriteAuthSegment(newData, mac, DS28E15);
00568 }
00569 
00570 Result<array<DS28E15_22_25::BlockProtection, DS28E15::protectionBlocks> >
00571 DS28EL15::readAllBlockProtection() const {
00572   array<BlockProtection, protectionBlocks> protection;
00573   TRY(doReadAllBlockProtection(protection, DS28E15));
00574   return protection;
00575 }
00576 
00577 Result<void> DS28E15::loadSecret(bool lock) {
00578   return doLoadSecret(lock, false);
00579 }
00580 
00581 Result<void> DS28E15::computeSecret(int pageNum, bool lock) {
00582   return doComputeSecret(pageNum, lock, false);
00583 }
00584 
00585 const int DS28EL22::memoryPages;
00586 const int DS28EL22::protectionBlocks;
00587 
00588 Result<void> DS28EL22::writeScratchpad(Page::const_span data) {
00589   return doWriteScratchpad(data, DS28E22);
00590 }
00591 
00592 Result<DS28E15_22_25::Page::array> DS28EL22::readScratchpad() const {
00593   return doReadScratchpad(DS28E22);
00594 }
00595 
00596 Result<DS28E15_22_25::BlockProtection>
00597 DS28EL22::readBlockProtection(int blockNum) const {
00598   return doReadBlockProtection(blockNum, DS28E22);
00599 }
00600 
00601 Result<void> DS28EL22::writeAuthSegment(int pageNum, int segmentNum,
00602                                         Segment::const_span newData,
00603                                         Page::const_span mac) {
00604   return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E22);
00605 }
00606 
00607 Result<void> DS28EL22::continueWriteAuthSegment(Segment::const_span newData,
00608                                                 Page::const_span mac) {
00609   return doContinueWriteAuthSegment(newData, mac, DS28E22);
00610 }
00611 
00612 Result<array<DS28E15_22_25::BlockProtection, DS28E22::protectionBlocks> >
00613 DS28EL22::readAllBlockProtection() const {
00614   array<BlockProtection, protectionBlocks> protection;
00615   TRY(doReadAllBlockProtection(protection, DS28E22));
00616   return protection;
00617 }
00618 
00619 Result<void> DS28E22::loadSecret(bool lock) {
00620   return doLoadSecret(lock, false);
00621 }
00622 
00623 Result<void> DS28E22::computeSecret(int pageNum, bool lock) {
00624   return doComputeSecret(pageNum, lock, false);
00625 }
00626 
00627 const int DS28EL25::memoryPages;
00628 const int DS28EL25::protectionBlocks;
00629 
00630 Result<void> DS28EL25::writeScratchpad(Page::const_span data) {
00631   return doWriteScratchpad(data, DS28E25);
00632 }
00633 
00634 Result<DS28E15_22_25::Page::array> DS28EL25::readScratchpad() const {
00635   return doReadScratchpad(DS28E25);
00636 }
00637 
00638 Result<DS28E15_22_25::BlockProtection>
00639 DS28EL25::readBlockProtection(int blockNum) const {
00640   return doReadBlockProtection(blockNum, DS28E25);
00641 }
00642 
00643 Result<void> DS28EL25::writeAuthSegment(int pageNum, int segmentNum,
00644                                         Segment::const_span newData,
00645                                         Page::const_span mac) {
00646   return doWriteAuthSegment(pageNum, segmentNum, newData, mac, DS28E25);
00647 }
00648 
00649 Result<void> DS28EL25::continueWriteAuthSegment(Segment::const_span newData,
00650                                                 Page::const_span mac) {
00651   return doContinueWriteAuthSegment(newData, mac, DS28E25);
00652 }
00653 
00654 Result<array<DS28E15_22_25::BlockProtection, DS28E25::protectionBlocks> >
00655 DS28EL25::readAllBlockProtection() const {
00656   array<BlockProtection, protectionBlocks> protection;
00657   TRY(doReadAllBlockProtection(protection, DS28E25));
00658   return protection;
00659 }
00660 
00661 Result<void> DS28E25::loadSecret(bool lock) {
00662   return doLoadSecret(lock, false);
00663 }
00664 
00665 Result<void> DS28E25::computeSecret(int pageNum, bool lock) {
00666   return doComputeSecret(pageNum, lock, false);
00667 }
00668 
00669 } // namespace MaximInterfaceDevices