Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.

The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface

Revision:
8:5ea891c7d1a1
Parent:
7:9cd16581b578
Child:
11:3f3bf6bf5e6c
--- a/MaximInterfaceDevices/DS2465.cpp	Mon Jul 22 11:44:07 2019 -0500
+++ b/MaximInterfaceDevices/DS2465.cpp	Mon Sep 16 11:13:37 2019 -0500
@@ -1,5 +1,5 @@
 /*******************************************************************************
-* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+* Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
@@ -33,15 +33,20 @@
 #include <MaximInterfaceCore/Error.hpp>
 #include "DS2465.hpp"
 
+#define TRY MaximInterfaceCore_TRY
+#define TRY_VALUE MaximInterfaceCore_TRY_VALUE
+
 namespace MaximInterfaceDevices {
 
 using namespace Core;
 
-/// Delay required after writing an EEPROM segment.
+// Delay required after writing an EEPROM segment.
 static const int eepromSegmentWriteDelayMs = 10;
-/// Delay required after writing an EEPROM page such as the secret memory.
+
+// Delay required after writing an EEPROM page such as the secret memory.
 static const int eepromPageWriteDelayMs = 8 * eepromSegmentWriteDelayMs;
-/// Delay required for a SHA computation to complete.
+
+// Delay required for a SHA computation to complete.
 static const int shaComputationDelayMs = 2;
 
 static const uint_least8_t scratchpad = 0x00;
@@ -49,36 +54,32 @@
 
 static const uint_least8_t owTransmitBlockCmd = 0x69;
 
-/// DS2465 Status bits.
-enum StatusBit {
-  Status_1WB = 0x01,
-  Status_PPD = 0x02,
-  Status_SD = 0x04,
-  Status_LL = 0x08,
-  Status_RST = 0x10,
-  Status_SBR = 0x20,
-  Status_TSB = 0x40,
-  Status_DIR = 0x80
-};
+// DS2465 status bits.
+static const uint_least8_t status_1WB = 0x01;
+static const uint_least8_t status_PPD = 0x02;
+static const uint_least8_t status_SD = 0x04;
+static const uint_least8_t status_SBR = 0x20;
+static const uint_least8_t status_TSB = 0x40;
+static const uint_least8_t status_DIR = 0x80;
 
 static const int maxBlockSize = 63;
 
 const int DS2465::memoryPages;
 const int DS2465::segmentsPerPage;
 
-error_code DS2465::initialize(Config config) {
+Result<void> DS2465::initialize(Config config) {
   // reset DS2465
-  error_code result = resetDevice();
-  if (!result) {
+  Result<void> result = resetDevice();
+  if (result) {
     // write the default configuration setup
     result = writeConfig(config);
   }
   return result;
 }
 
-error_code DS2465::computeNextMasterSecret(bool swap, int pageNum,
-                                           PageRegion region) {
-  error_code result = make_error_code(ArgumentOutOfRangeError);
+Result<void> DS2465::computeNextMasterSecret(bool swap, int pageNum,
+                                             PageRegion region) {
+  Result<void> result = ArgumentOutOfRangeError;
   if (pageNum >= 0) {
     const uint_least8_t command[] = {
         0x1E, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
@@ -88,52 +89,52 @@
   return result;
 }
 
-error_code DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum,
-                                   int segmentNum) const {
-  error_code result = make_error_code(ArgumentOutOfRangeError);
+Result<void> DS2465::computeWriteMac(bool regwrite, bool swap, int pageNum,
+                                     int segmentNum) const {
+  Result<void> result = ArgumentOutOfRangeError;
   if (pageNum >= 0 && segmentNum >= 0) {
     const uint_least8_t command[] = {
         0x2D, static_cast<uint_least8_t>((regwrite << 7) | (swap << 6) |
                                          (pageNum << 4) | segmentNum)};
     result = writeMemory(commandReg, command);
-    if (!result) {
+    if (result) {
       sleep->invoke(shaComputationDelayMs);
     }
   }
   return result;
 }
 
-error_code DS2465::computeAuthMac(bool swap, int pageNum,
-                                  PageRegion region) const {
-  error_code result = make_error_code(ArgumentOutOfRangeError);
+Result<void> DS2465::computeAuthMac(bool swap, int pageNum,
+                                    PageRegion region) const {
+  Result<void> result = ArgumentOutOfRangeError;
   if (pageNum >= 0) {
     const uint_least8_t command[] = {
         0x3C, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
                                               : 0xBF)};
     result = writeMemory(commandReg, command);
-    if (!result) {
+    if (result) {
       sleep->invoke(shaComputationDelayMs * 2);
     }
   }
   return result;
 }
 
-error_code DS2465::computeSlaveSecret(bool swap, int pageNum,
-                                      PageRegion region) {
-  error_code result = make_error_code(ArgumentOutOfRangeError);
+Result<void> DS2465::computeSlaveSecret(bool swap, int pageNum,
+                                        PageRegion region) {
+  Result<void> result = ArgumentOutOfRangeError;
   if (pageNum >= 0) {
     const uint_least8_t command[] = {
         0x4B, static_cast<uint_least8_t>(swap ? (0xC8 | (pageNum << 4) | region)
                                               : 0xBF)};
     result = writeMemory(commandReg, command);
-    if (!result) {
+    if (result) {
       sleep->invoke(shaComputationDelayMs * 2);
     }
   }
   return result;
 }
 
-error_code DS2465::readPage(int pageNum, Page::span data) const {
+Result<DS2465::Page::array> DS2465::readPage(int pageNum) const {
   uint_least8_t addr;
   switch (pageNum) {
   case 0:
@@ -143,48 +144,50 @@
     addr = 0xA0;
     break;
   default:
-    return make_error_code(ArgumentOutOfRangeError);
+    return ArgumentOutOfRangeError;
   }
-  return readMemory(addr, data);
+  Page::array data;
+  TRY(readMemory(addr, data));
+  return data;
 }
 
-error_code DS2465::writePage(int pageNum, Page::const_span data) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void> DS2465::writePage(int pageNum, Page::const_span data) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = copyScratchpad(false, pageNum, false, 0);
   }
-  if (!result) {
+  if (result) {
     sleep->invoke(eepromPageWriteDelayMs);
   }
   return result;
 }
 
-error_code DS2465::writeSegment(int pageNum, int segmentNum,
-                                Segment::const_span data) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void> DS2465::writeSegment(int pageNum, int segmentNum,
+                                  Segment::const_span data) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = copyScratchpad(false, pageNum, true, segmentNum);
   }
-  if (!result) {
+  if (result) {
     sleep->invoke(eepromSegmentWriteDelayMs);
   }
   return result;
 }
 
-error_code DS2465::writeMasterSecret(Page::const_span masterSecret) {
-  error_code result = writeMemory(scratchpad, masterSecret);
-  if (!result) {
+Result<void> DS2465::writeMasterSecret(Page::const_span masterSecret) {
+  Result<void> result = writeMemory(scratchpad, masterSecret);
+  if (result) {
     result = copyScratchpad(true, 0, false, 0);
   }
-  if (!result) {
+  if (result) {
     sleep->invoke(eepromPageWriteDelayMs);
   }
   return result;
 }
 
-error_code DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull,
-                                  int segmentNum) {
-  error_code result = make_error_code(ArgumentOutOfRangeError);
+Result<void> DS2465::copyScratchpad(bool destSecret, int pageNum, bool notFull,
+                                    int segmentNum) {
+  Result<void> result = ArgumentOutOfRangeError;
   if (pageNum >= 0 && segmentNum >= 0) {
     const uint_least8_t command[] = {
         0x5A,
@@ -196,41 +199,41 @@
   return result;
 }
 
-error_code DS2465::configureLevel(Level level) {
+Result<void> DS2465::configureLevel(Level level) {
   // Check if supported level
   if (!((level == NormalLevel) || (level == StrongLevel))) {
-    return make_error_code(InvalidLevelError);
+    return InvalidLevelError;
   }
   // Check if requested level already set
   if (curConfig.getSPU() == (level == StrongLevel)) {
-    return error_code();
+    return none;
   }
   // Set the level
   return writeConfig(Config(curConfig).setSPU(level == StrongLevel));
 }
 
-error_code DS2465::setLevel(Level newLevel) {
+Result<void> DS2465::setLevel(Level newLevel) {
   if (newLevel == StrongLevel) {
-    return make_error_code(InvalidLevelError);
+    return InvalidLevelError;
   }
 
   return configureLevel(newLevel);
 }
 
-error_code DS2465::setSpeed(Speed newSpeed) {
+Result<void> DS2465::setSpeed(Speed newSpeed) {
   // Check if supported speed
   if (!((newSpeed == OverdriveSpeed) || (newSpeed == StandardSpeed))) {
-    return make_error_code(InvalidSpeedError);
+    return InvalidSpeedError;
   }
   // Check if requested speed is already set
   if (curConfig.get1WS() == (newSpeed == OverdriveSpeed)) {
-    return error_code();
+    return none;
   }
   // Set the speed
   return writeConfig(Config(curConfig).set1WS(newSpeed == OverdriveSpeed));
 }
 
-error_code DS2465::triplet(TripletData & data) {
+Result<OneWireMaster::TripletData> DS2465::triplet(bool sendBit) {
   // 1-Wire Triplet (Case B)
   //   S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
   //                                         \--------/
@@ -239,89 +242,74 @@
   //  SS indicates byte containing search direction bit value in msbit
 
   const uint_least8_t command[] = {
-      0x78, static_cast<uint_least8_t>(data.writeBit ? 0x80 : 0x00)};
-  error_code result = writeMemory(commandReg, command);
-  if (!result) {
-    uint_least8_t status;
-    result = pollBusy(&status);
-    if (!result) {
-      // check bit results in status byte
-      data.readBit = ((status & Status_SBR) == Status_SBR);
-      data.readBitComplement = ((status & Status_TSB) == Status_TSB);
-      data.writeBit = ((status & Status_DIR) == Status_DIR);
-    }
-  }
-  return result;
+      0x78, static_cast<uint_least8_t>(sendBit ? 0x80 : 0x00)};
+  TRY(writeMemory(commandReg, command));
+
+  uint_least8_t status;
+  TRY_VALUE(status, pollBusy());
+
+  TripletData data;
+  data.readBit = ((status & status_SBR) == status_SBR);
+  data.readBitComplement = ((status & status_TSB) == status_TSB);
+  data.writeBit = ((status & status_DIR) == status_DIR);
+  return data;
 }
 
-error_code DS2465::readBlock(span<uint_least8_t> recvBuf) {
+Result<void> DS2465::readBlock(span<uint_least8_t> recvBuf) {
   // 1-Wire Receive Block (Case A)
   //   S AD,0 [A] CommandReg [A] 1WRF [A] PR [A] P
   //  [] indicates from slave
   //  PR indicates byte containing parameter
 
-  error_code result;
   span<uint_least8_t>::index_type recvIdx = 0;
-  while (recvIdx < recvBuf.size() && !result) {
+  while (recvIdx < recvBuf.size()) {
     const uint_least8_t command[] = {
         0xE1,
         static_cast<uint_least8_t>(std::min<span<uint_least8_t>::index_type>(
             recvBuf.size() - recvIdx, maxBlockSize))};
-    result = writeMemory(commandReg, command);
-    if (!result) {
-      result = pollBusy();
-    }
-    if (!result) {
-      result = readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1]));
-    }
+    TRY(writeMemory(commandReg, command));
+    TRY(pollBusy());
+    TRY(readMemory(scratchpad, recvBuf.subspan(recvIdx, command[1])));
     recvIdx += command[1];
   }
-  return result;
+  return none;
 }
 
-error_code DS2465::writeBlock(span<const uint_least8_t> sendBuf) {
-  error_code result;
+Result<void> DS2465::writeBlock(span<const uint_least8_t> sendBuf) {
   span<const uint_least8_t>::index_type sendIdx = 0;
-  while (sendIdx < sendBuf.size() && !result) {
+  while (sendIdx < sendBuf.size()) {
     const uint_least8_t command[] = {
         owTransmitBlockCmd, static_cast<uint_least8_t>(
                                 std::min<span<const uint_least8_t>::index_type>(
                                     sendBuf.size() - sendIdx, maxBlockSize))};
 
     // prefill scratchpad with required data
-    result = writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1]));
+    TRY(writeMemory(scratchpad, sendBuf.subspan(sendIdx, command[1])));
 
     // 1-Wire Transmit Block (Case A)
     //   S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
     //  [] indicates from slave
     //  PR indicates byte containing parameter
-    if (!result) {
-      result = writeMemory(commandReg, command);
-    }
-    if (!result) {
-      result = pollBusy();
-    }
+    TRY(writeMemory(commandReg, command));
+    TRY(pollBusy());
     sendIdx += command[1];
   }
-  return result;
+  return none;
 }
 
-error_code DS2465::writeMacBlock() const {
+Result<void> DS2465::writeMacBlock() {
   // 1-Wire Transmit Block (Case A)
   //   S AD,0 [A] CommandReg [A] 1WTB [A] PR [A] P
   //  [] indicates from slave
   //  PR indicates byte containing parameter
 
   const uint_least8_t command[] = {owTransmitBlockCmd, 0xFF};
-  error_code result = writeMemory(commandReg, command);
-  if (!result) {
-    result = pollBusy();
-  }
-  return result;
+  TRY(writeMemory(commandReg, command));
+  TRY(pollBusy());
+  return none;
 }
 
-error_code DS2465::readByteSetLevel(uint_least8_t & recvByte,
-                                    Level afterLevel) {
+Result<uint_least8_t> DS2465::readByteSetLevel(Level afterLevel) {
   // 1-Wire Read Bytes (Case C)
   //   S AD,0 [A] CommandReg [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
   //                                                  \--------/
@@ -331,27 +319,17 @@
   //  [] indicates from slave
   //  DD data read
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
+  TRY(configureLevel(afterLevel));
 
-  const uint_least8_t command = 0x96;
-  result = writeMemory(commandReg, make_span(&command, 1));
-  if (result) {
-    return result;
-  }
-
-  result = pollBusy();
-  if (result) {
-    return result;
-  }
-
-  result = readMemory(0x62, make_span(&recvByte, 1));
-  return result;
+  uint_least8_t buf = 0x96;
+  TRY(writeMemory(commandReg, make_span(&buf, 1)));
+  TRY(pollBusy());
+  TRY(readMemory(0x62, make_span(&buf, 1)));
+  return buf;
 }
 
-error_code DS2465::writeByteSetLevel(uint_least8_t sendByte, Level afterLevel) {
+Result<void> DS2465::writeByteSetLevel(uint_least8_t sendByte,
+                                       Level afterLevel) {
   // 1-Wire Write Byte (Case B)
   //   S AD,0 [A] CommandReg [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status]
   //   A\ P
@@ -360,22 +338,15 @@
   //  [] indicates from slave
   //  DD data to write
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
+  TRY(configureLevel(afterLevel));
 
   const uint_least8_t command[] = {0xA5, sendByte};
-  result = writeMemory(commandReg, command);
-  if (result) {
-    return result;
-  }
-
-  result = pollBusy();
-  return result;
+  TRY(writeMemory(commandReg, command));
+  TRY(pollBusy());
+  return none;
 }
 
-error_code DS2465::touchBitSetLevel(bool & sendRecvBit, Level afterLevel) {
+Result<bool> DS2465::touchBitSetLevel(bool sendBit, Level afterLevel) {
   // 1-Wire bit (Case B)
   //   S AD,0 [A] CommandReg [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status]
   //   A\ P
@@ -384,28 +355,20 @@
   //  [] indicates from slave
   //  BB indicates byte containing bit value in msbit
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
+  TRY(configureLevel(afterLevel));
 
   const uint_least8_t command[] = {
-      0x87, static_cast<uint_least8_t>(sendRecvBit ? 0x80 : 0x00)};
-  result = writeMemory(commandReg, command);
-  if (result) {
-    return result;
-  }
+      0x87, static_cast<uint_least8_t>(sendBit ? 0x80 : 0x00)};
+  TRY(writeMemory(commandReg, command));
 
   uint_least8_t status;
-  result = pollBusy(&status);
-  if (!result) {
-    sendRecvBit = ((status & Status_SBR) == Status_SBR);
-  }
-  return result;
+  TRY_VALUE(status, pollBusy());
+
+  return (status & status_SBR) == status_SBR;
 }
 
-error_code DS2465::writeMemory(uint_least8_t addr,
-                               span<const uint_least8_t> buf) const {
+Result<void> DS2465::writeMemory(uint_least8_t addr,
+                                 span<const uint_least8_t> buf) const {
   // Write SRAM (Case A)
   //   S AD,0 [A] VSA [A] DD [A]  P
   //                      \-----/
@@ -414,18 +377,18 @@
   //  VSA valid SRAM memory address
   //  DD memory data to write
 
-  error_code result = master->start(address_);
-  if (result) {
+  Result<void> result = master->start(address_);
+  if (!result) {
     master->stop();
     return result;
   }
   result = master->writeByte(addr);
-  if (result) {
+  if (!result) {
     master->stop();
     return result;
   }
   result = master->writeBlock(buf);
-  if (result) {
+  if (!result) {
     master->stop();
     return result;
   }
@@ -433,8 +396,8 @@
   return result;
 }
 
-error_code DS2465::readMemory(uint_least8_t addr,
-                              span<uint_least8_t> buf) const {
+Result<void> DS2465::readMemory(uint_least8_t addr,
+                                span<uint_least8_t> buf) const {
   // Read (Case A)
   //   S AD,0 [A] MA [A] Sr AD,1 [A] [DD] A [DD] A\ P
   //                                 \-----/
@@ -443,13 +406,13 @@
   //  MA memory address
   //  DD memory data read
 
-  error_code result = master->start(address_);
-  if (result) {
+  Result<void> result = master->start(address_);
+  if (!result) {
     master->stop();
     return result;
   }
   result = master->writeByte(addr);
-  if (result) {
+  if (!result) {
     master->stop();
     return result;
   }
@@ -457,14 +420,14 @@
   return result;
 }
 
-error_code DS2465::readMemory(span<uint_least8_t> buf) const {
-  error_code result = master->start(address_ | 1);
-  if (result) {
+Result<void> DS2465::readMemory(span<uint_least8_t> buf) const {
+  Result<void> result = master->start(address_ | 1);
+  if (!result) {
     master->stop();
     return result;
   }
-  result = master->readBlock(I2CMaster::Nack, buf);
-  if (result) {
+  result = master->readBlock(buf, I2CMaster::Nack);
+  if (!result) {
     master->stop();
     return result;
   }
@@ -472,27 +435,26 @@
   return result;
 }
 
-error_code DS2465::writeConfig(Config config) {
+Result<void> DS2465::writeConfig(Config config) {
   const uint_least8_t configReg = 0x67;
   uint_least8_t configBuf =
       ((config.readByte() ^ 0xF) << 4) | config.readByte();
-  error_code result = writeMemory(configReg, make_span(&configBuf, 1));
-  if (!result) {
+  Result<void> result = writeMemory(configReg, make_span(&configBuf, 1));
+  if (result) {
     result = readMemory(configReg, make_span(&configBuf, 1));
   }
-  if (!result) {
-    if (configBuf != config.readByte())
-      result = make_error_code(HardwareError);
+  if (result && configBuf != config.readByte()) {
+    result = HardwareError;
   }
-  if (!result) {
+  if (result) {
     curConfig = config;
   }
   return result;
 }
 
-error_code DS2465::writePortParameter(PortParameter param, int val) {
+Result<void> DS2465::writePortParameter(PortParameter param, int val) {
   if (val < 0 || val > 15) {
-    return make_error_code(ArgumentOutOfRangeError);
+    return ArgumentOutOfRangeError;
   }
 
   uint_least8_t addr = 0;
@@ -521,8 +483,8 @@
   }
 
   uint_least8_t data;
-  error_code result = readMemory(addr, make_span(&data, 1));
-  if (result) {
+  Result<void> result = readMemory(addr, make_span(&data, 1));
+  if (!result) {
     return result;
   }
 
@@ -539,28 +501,24 @@
   return result;
 }
 
-error_code DS2465::pollBusy(uint_least8_t * pStatus) const {
+Result<uint_least8_t> DS2465::pollBusy() const {
   const int pollLimit = 200;
 
   int pollCount = 0;
   uint_least8_t status;
   do {
-    error_code result = readMemory(make_span(&status, 1));
-    if (result) {
-      return result;
-    }
-    if (pStatus != NULL) {
-      *pStatus = status;
+    const Result<void> result = readMemory(make_span(&status, 1));
+    if (!result) {
+      return result.error();
     }
     if (pollCount++ >= pollLimit) {
-      return make_error_code(HardwareError);
+      return HardwareError;
     }
-  } while (status & Status_1WB);
-
-  return error_code();
+  } while ((status & status_1WB) == status_1WB);
+  return status;
 }
 
-error_code DS2465::reset() {
+Result<void> DS2465::reset() {
   // 1-Wire reset (Case B)
   //   S AD,0 [A] CommandReg  [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
   //                                                  \--------/
@@ -568,191 +526,210 @@
   //  [] indicates from slave
 
   uint_least8_t buf = 0xB4;
-  error_code result = writeMemory(commandReg, make_span(&buf, 1));
+  TRY(writeMemory(commandReg, make_span(&buf, 1)));
+
+  TRY_VALUE(buf, pollBusy());
 
-  if (!result) {
-    result = pollBusy(&buf);
+  if ((buf & status_SD) == status_SD) {
+    return ShortDetectedError;
+  }
+  if ((buf & status_PPD) != status_PPD) {
+    return NoSlaveError;
   }
 
-  if (!result) {
-    if ((buf & Status_SD) == Status_SD) {
-      result = make_error_code(ShortDetectedError);
-    } else if ((buf & Status_PPD) != Status_PPD) {
-      result = make_error_code(NoSlaveError);
-    }
-  }
-
-  return result;
+  return none;
 }
 
-error_code DS2465::resetDevice() {
+Result<void> DS2465::resetDevice() {
   // Device Reset
   //   S AD,0 [A] CommandReg [A] 1WMR [A] Sr AD,1 [A] [SS] A\ P
   //  [] indicates from slave
   //  SS status byte to read to verify state
 
   uint_least8_t buf = 0xF0;
-  error_code result = writeMemory(commandReg, make_span(&buf, 1));
+  Result<void> result = writeMemory(commandReg, make_span(&buf, 1));
 
-  if (!result) {
+  if (result) {
     result = readMemory(make_span(&buf, 1));
   }
 
-  if (!result) {
+  if (result) {
     if ((buf & 0xF7) != 0x10) {
-      result = make_error_code(HardwareError);
+      result = HardwareError;
     }
   }
 
-  if (!result) {
+  if (result) {
     reset(); // do a command to get 1-Wire master reset out of holding state
   }
 
   return result;
 }
 
-error_code
+Result<void>
 DS2465::computeNextMasterSecret(AuthenticationData::const_span data) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeNextMasterSecret(false, 0, FullPage);
   }
   return result;
 }
 
-error_code
+Result<void>
 DS2465::computeNextMasterSecretWithSwap(AuthenticationData::const_span data,
                                         int pageNum, PageRegion region) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeNextMasterSecret(true, pageNum, region);
   }
   return result;
 }
 
-error_code DS2465::computeWriteMac(WriteMacData::const_span data) const {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void> DS2465::doComputeWriteMac(WriteMacData::const_span data) const {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeWriteMac(false, false, 0, 0);
   }
   return result;
 }
 
-error_code DS2465::computeWriteMac(WriteMacData::const_span data,
-                                   Page::span mac) const {
-  error_code result = computeWriteMac(data);
+Result<DS2465::Page::array>
+DS2465::computeWriteMac(WriteMacData::const_span data) const {
+  Result<void> result = doComputeWriteMac(data);
   if (!result) {
-    result = readMemory(mac);
+    return result.error();
   }
-  return result;
+  Page::array mac;
+  result = readMemory(mac);
+  if (!result) {
+    return result.error();
+  }
+  return mac;
 }
 
-error_code
-DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) const {
-  error_code result = computeWriteMac(data);
-  if (!result) {
+Result<void> DS2465::computeAndTransmitWriteMac(WriteMacData::const_span data) {
+  Result<void> result = doComputeWriteMac(data);
+  if (result) {
     result = writeMacBlock();
   }
   return result;
 }
 
-error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
-                                           int pageNum, int segmentNum) const {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void> DS2465::doComputeWriteMacWithSwap(WriteMacData::const_span data,
+                                               int pageNum,
+                                               int segmentNum) const {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeWriteMac(false, true, pageNum, segmentNum);
   }
   return result;
 }
 
-error_code DS2465::computeWriteMacWithSwap(WriteMacData::const_span data,
-                                           int pageNum, int segmentNum,
-                                           Page::span mac) const {
-  error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
+Result<DS2465::Page::array>
+DS2465::computeWriteMacWithSwap(WriteMacData::const_span data, int pageNum,
+                                int segmentNum) const {
+  Result<void> result = doComputeWriteMacWithSwap(data, pageNum, segmentNum);
   if (!result) {
-    result = readMemory(mac);
+    return result.error();
   }
-  return result;
+  Page::array mac;
+  result = readMemory(mac);
+  if (!result) {
+    return result.error();
+  }
+  return mac;
 }
 
-error_code
+Result<void>
 DS2465::computeAndTransmitWriteMacWithSwap(WriteMacData::const_span data,
-                                           int pageNum, int segmentNum) const {
-  error_code result = computeWriteMacWithSwap(data, pageNum, segmentNum);
-  if (!result) {
+                                           int pageNum, int segmentNum) {
+  Result<void> result = doComputeWriteMacWithSwap(data, pageNum, segmentNum);
+  if (result) {
     result = writeMacBlock();
   }
   return result;
 }
 
-error_code DS2465::computeSlaveSecret(AuthenticationData::const_span data) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void> DS2465::computeSlaveSecret(AuthenticationData::const_span data) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeSlaveSecret(false, 0, FullPage);
   }
   return result;
 }
 
-error_code
+Result<void>
 DS2465::computeSlaveSecretWithSwap(AuthenticationData::const_span data,
                                    int pageNum, PageRegion region) {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeSlaveSecret(true, pageNum, region);
   }
   return result;
 }
 
-error_code DS2465::computeAuthMac(AuthenticationData::const_span data) const {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void>
+DS2465::doComputeAuthMac(AuthenticationData::const_span data) const {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeAuthMac(false, 0, FullPage);
   }
   return result;
 }
 
-error_code DS2465::computeAuthMac(AuthenticationData::const_span data,
-                                  Page::span mac) const {
-  error_code result = computeAuthMac(data);
+Result<DS2465::Page::array>
+DS2465::computeAuthMac(AuthenticationData::const_span data) const {
+  Result<void> result = doComputeAuthMac(data);
   if (!result) {
-    result = readMemory(mac);
+    return result.error();
   }
-  return result;
+  Page::array mac;
+  result = readMemory(mac);
+  if (!result) {
+    return result.error();
+  }
+  return mac;
 }
 
-error_code
-DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) const {
-  error_code result = computeAuthMac(data);
-  if (!result) {
+Result<void>
+DS2465::computeAndTransmitAuthMac(AuthenticationData::const_span data) {
+  Result<void> result = doComputeAuthMac(data);
+  if (result) {
     result = writeMacBlock();
   }
   return result;
 }
 
-error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
-                                          int pageNum,
-                                          PageRegion region) const {
-  error_code result = writeMemory(scratchpad, data);
-  if (!result) {
+Result<void>
+DS2465::doComputeAuthMacWithSwap(AuthenticationData::const_span data,
+                                 int pageNum, PageRegion region) const {
+  Result<void> result = writeMemory(scratchpad, data);
+  if (result) {
     result = computeAuthMac(true, pageNum, region);
   }
   return result;
 }
 
-error_code DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data,
-                                          int pageNum, PageRegion region,
-                                          Page::span mac) const {
-  error_code result = computeAuthMacWithSwap(data, pageNum, region);
+Result<DS2465::Page::array>
+DS2465::computeAuthMacWithSwap(AuthenticationData::const_span data, int pageNum,
+                               PageRegion region) const {
+  Result<void> result = doComputeAuthMacWithSwap(data, pageNum, region);
   if (!result) {
-    result = readMemory(mac);
+    return result.error();
   }
-  return result;
+  Page::array mac;
+  result = readMemory(mac);
+  if (!result) {
+    return result.error();
+  }
+  return mac;
 }
 
-error_code DS2465::computeAndTransmitAuthMacWithSwap(
-    AuthenticationData::const_span data, int pageNum, PageRegion region) const {
-  error_code result = computeAuthMacWithSwap(data, pageNum, region);
-  if (!result) {
+Result<void>
+DS2465::computeAndTransmitAuthMacWithSwap(AuthenticationData::const_span data,
+                                          int pageNum, PageRegion region) {
+  Result<void> result = doComputeAuthMacWithSwap(data, pageNum, region);
+  if (result) {
     result = writeMacBlock();
   }
   return result;
@@ -770,10 +747,8 @@
 
       case ArgumentOutOfRangeError:
         return "Argument Out of Range Error";
-
-      default:
-        return defaultErrorMessage(condition);
       }
+      return defaultErrorMessage(condition);
     }
   } instance;
   return instance;