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/DS2482_DS2484.cpp	Mon Jul 22 11:44:07 2019 -0500
+++ b/MaximInterfaceDevices/DS2482_DS2484.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,60 +33,50 @@
 #include <MaximInterfaceCore/Error.hpp>
 #include "DS2482_DS2484.hpp"
 
+#define TRY MaximInterfaceCore_TRY
+#define TRY_VALUE MaximInterfaceCore_TRY_VALUE
+
 namespace MaximInterfaceDevices {
 
 using namespace Core;
 
-// Device 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
-};
+// Device 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;
 
-error_code DS2482_DS2484::initialize(Config config) {
-  error_code result = resetDevice();
-  if (result) {
-    return result;
-  }
+Result<void> DS2482_DS2484::initialize(Config config) {
+  TRY(resetDevice());
   // Write the default configuration setup.
-  result = writeConfig(config);
-  return result;
+  TRY(writeConfig(config));
+  return none;
 }
 
-error_code DS2482_DS2484::resetDevice() {
+Result<void> DS2482_DS2484::resetDevice() {
   // Device Reset
   //   S AD,0 [A] DRST [A] Sr AD,1 [A] [SS] A\ P
   //  [] indicates from slave
   //  SS status byte to read to verify state
 
-  error_code result = sendCommand(0xF0);
-  if (result) {
-    return result;
-  }
+  TRY(sendCommand(0xF0));
 
   uint_least8_t buf;
-  result = readRegister(buf);
-  if (result) {
-    return result;
-  }
+  TRY_VALUE(buf, readRegister());
 
   if ((buf & 0xF7) != 0x10) {
-    return make_error_code(HardwareError);
+    return HardwareError;
   }
 
   // Do a command to get 1-Wire master reset out of holding state.
   reset();
 
-  return result;
+  return none;
 }
 
-error_code DS2482_DS2484::triplet(TripletData & data) {
+Result<OneWireMaster::TripletData> DS2482_DS2484::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
   //                                         \--------/
@@ -94,48 +84,41 @@
   //  [] indicates from slave
   //  SS indicates byte containing search direction bit value in msbit
 
-  error_code result = sendCommand(0x78, data.writeBit ? 0x80 : 0x00);
-  if (!result) {
-    uint_least8_t status;
-    result = pollBusy(&status);
-    if (!result) {
-      data.readBit = ((status & Status_SBR) == Status_SBR);
-      data.readBitComplement = ((status & Status_TSB) == Status_TSB);
-      data.writeBit = ((status & Status_DIR) == Status_DIR);
-    }
-  }
-  return result;
+  TRY(sendCommand(0x78, sendBit ? 0x80 : 0x00));
+
+  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 DS2482_DS2484::reset() {
+Result<void> DS2482_DS2484::reset() {
   // 1-Wire reset (Case B)
   //   S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
   //                                   \--------/
   //                       Repeat until 1WB bit has changed to 0
   //  [] indicates from slave
 
-  error_code result = sendCommand(0xB4);
-  if (result) {
-    return result;
-  }
+  TRY(sendCommand(0xB4));
+
+  uint_least8_t status;
+  TRY_VALUE(status, pollBusy());
 
-  uint_least8_t buf;
-  result = pollBusy(&buf);
-  if (result) {
-    return result;
+  if ((status & status_SD) == status_SD) {
+    return ShortDetectedError;
+  }
+  if ((status & status_PPD) != status_PPD) {
+    return NoSlaveError;
   }
 
-  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 DS2482_DS2484::touchBitSetLevel(bool & sendRecvBit,
-                                           Level afterLevel) {
+Result<bool> DS2482_DS2484::touchBitSetLevel(bool sendBit, Level afterLevel) {
   // 1-Wire bit (Case B)
   //   S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
   //                                          \--------/
@@ -143,26 +126,15 @@
   //  [] indicates from slave
   //  BB indicates byte containing bit value in msbit
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
-
-  result = sendCommand(0x87, sendRecvBit ? 0x80 : 0x00);
-  if (result) {
-    return result;
-  }
-
+  TRY(configureLevel(afterLevel));
+  TRY(sendCommand(0x87, sendBit ? 0x80 : 0x00));
   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 DS2482_DS2484::writeByteSetLevel(uint_least8_t sendByte,
-                                            Level afterLevel) {
+Result<void> DS2482_DS2484::writeByteSetLevel(uint_least8_t sendByte,
+                                              Level afterLevel) {
   // 1-Wire Write Byte (Case B)
   //   S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
   //                                          \--------/
@@ -170,22 +142,13 @@
   //  [] indicates from slave
   //  DD data to write
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
-
-  result = sendCommand(0xA5, sendByte);
-  if (result) {
-    return result;
-  }
-
-  result = pollBusy();
-  return result;
+  TRY(configureLevel(afterLevel));
+  TRY(sendCommand(0xA5, sendByte));
+  TRY(pollBusy());
+  return none;
 }
 
-error_code DS2482_DS2484::readByteSetLevel(uint_least8_t & recvByte,
-                                           Level afterLevel) {
+Result<uint_least8_t> DS2482_DS2484::readByteSetLevel(Level afterLevel) {
   // 1-Wire Read Bytes (Case C)
   //   S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A
   //                                   \--------/
@@ -195,119 +158,94 @@
   //  [] indicates from slave
   //  DD data read
 
-  error_code result = configureLevel(afterLevel);
-  if (result) {
-    return result;
-  }
-
-  result = sendCommand(0x96);
-  if (result) {
-    return result;
-  }
-
-  result = pollBusy();
-  if (result) {
-    return result;
-  }
-
-  result = readRegister(0xE1, recvByte);
-  return result;
+  TRY(configureLevel(afterLevel));
+  TRY(sendCommand(0x96));
+  TRY(pollBusy());
+  return readRegister(0xE1);
 }
 
-error_code DS2482_DS2484::setSpeed(Speed newSpeed) {
+Result<void> DS2482_DS2484::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 DS2482_DS2484::setLevel(Level newLevel) {
+Result<void> DS2482_DS2484::setLevel(Level newLevel) {
   if (newLevel == StrongLevel) {
-    return make_error_code(InvalidLevelError);
+    return InvalidLevelError;
   }
 
   return configureLevel(newLevel);
 }
 
-error_code DS2482_DS2484::writeConfig(Config config) {
+Result<void> DS2482_DS2484::writeConfig(Config config) {
   uint_least8_t configBuf =
       ((config.readByte() ^ 0xF) << 4) | config.readByte();
-  error_code result = sendCommand(0xD2, configBuf);
-  if (!result) {
-    result = readRegister(0xC3, configBuf);
+  TRY(sendCommand(0xD2, configBuf));
+
+  TRY_VALUE(configBuf, readRegister(0xC3));
+
+  if (configBuf != config.readByte()) {
+    return HardwareError;
   }
-  if (!result) {
-    if (configBuf != config.readByte()) {
-      result = make_error_code(HardwareError);
-    }
-  }
-  if (!result) {
-    curConfig = config;
-  }
-  return result;
+
+  curConfig = config;
+  return none;
 }
 
-error_code DS2482_DS2484::readRegister(uint_least8_t reg,
-                                       uint_least8_t & buf) const {
-  error_code result = sendCommand(0xE1, reg);
-  if (!result) {
-    result = readRegister(buf);
-  }
-  return result;
+Result<uint_least8_t> DS2482_DS2484::readRegister(uint_least8_t reg) const {
+  TRY(sendCommand(0xE1, reg));
+  return readRegister();
 }
 
-error_code DS2482_DS2484::readRegister(uint_least8_t & buf) const {
-  return master->readPacket(address_, make_span(&buf, 1));
+Result<uint_least8_t> DS2482_DS2484::readRegister() const {
+  uint_least8_t buf;
+  TRY(master->readPacket(address_, make_span(&buf, 1), I2CMaster::Stop));
+  return buf;
 }
 
-error_code DS2482_DS2484::pollBusy(uint_least8_t * pStatus) {
+Result<uint_least8_t> DS2482_DS2484::pollBusy() {
   const int pollLimit = 200;
 
   int pollCount = 0;
   uint_least8_t status;
   do {
-    error_code result = readRegister(status);
-    if (result) {
-      return result;
-    }
-    if (pStatus != NULL) {
-      *pStatus = status;
+    TRY_VALUE(status, readRegister());
+    if (pollCount++ >= pollLimit) {
+      return HardwareError;
     }
-    if (pollCount++ >= pollLimit) {
-      return make_error_code(HardwareError);
-    }
-  } while (status & Status_1WB);
-
-  return error_code();
+  } while ((status & status_1WB) == status_1WB);
+  return status;
 }
 
-error_code DS2482_DS2484::configureLevel(Level level) {
+Result<void> DS2482_DS2484::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 DS2482_DS2484::sendCommand(uint_least8_t cmd) const {
-  return master->writePacket(address_, make_span(&cmd, 1));
+Result<void> DS2482_DS2484::sendCommand(uint_least8_t cmd) const {
+  return master->writePacket(address_, make_span(&cmd, 1), I2CMaster::Stop);
 }
 
-error_code DS2482_DS2484::sendCommand(uint_least8_t cmd,
-                                      uint_least8_t param) const {
-  uint_least8_t buf[] = {cmd, param};
-  return master->writePacket(address_, buf);
+Result<void> DS2482_DS2484::sendCommand(uint_least8_t cmd,
+                                        uint_least8_t param) const {
+  const uint_least8_t buf[] = {cmd, param};
+  return master->writePacket(address_, buf, I2CMaster::Stop);
 }
 
 const error_category & DS2482_DS2484::errorCategory() {
@@ -322,16 +260,14 @@
 
       case ArgumentOutOfRangeError:
         return "Argument Out of Range Error";
-
-      default:
-        return defaultErrorMessage(condition);
       }
+      return defaultErrorMessage(condition);
     }
   } instance;
   return instance;
 }
 
-error_code DS2482_800::selectChannel(int channel) {
+Result<void> DS2482_800::selectChannel(int channel) {
   // Channel Select (Case A)
   //   S AD,0 [A] CHSL [A] CC [A] Sr AD,1 [A] [RR] A\ P
   //  [] indicates from slave
@@ -382,45 +318,35 @@
     break;
 
   default:
-    return make_error_code(ArgumentOutOfRangeError);
+    return ArgumentOutOfRangeError;
   };
 
-  error_code result = sendCommand(0xC3, ch);
-  if (!result) {
-    result = readRegister(ch);
-    if (!result) {
-      // check for failure due to incorrect read back of channel
-      if (ch != ch_read) {
-        result = make_error_code(HardwareError);
-      }
-    }
+  TRY(sendCommand(0xC3, ch));
+  TRY_VALUE(ch, readRegister());
+  // check for failure due to incorrect read back of channel
+  if (ch != ch_read) {
+    return HardwareError;
   }
 
-  return result;
+  return none;
 }
 
-error_code DS2484::adjustPort(PortParameter param, int val) {
+Result<void> DS2484::adjustPort(PortParameter param, int val) {
   if (val < 0 || val > 15) {
-    return make_error_code(ArgumentOutOfRangeError);
+    return ArgumentOutOfRangeError;
   }
 
-  error_code result = sendCommand(0xC3, (param << 4) | val);
-  if (result) {
-    return result;
-  }
+  TRY(sendCommand(0xC3, (param << 4) | val));
 
   uint_least8_t portConfig = val + 1;
   for (int reads = -1; reads < param; ++reads) {
-    result = readRegister(portConfig);
-    if (result) {
-      return result;
-    }
+    TRY_VALUE(portConfig, readRegister());
   }
   if (val != portConfig) {
-    result = make_error_code(HardwareError);
+    return HardwareError;
   }
 
-  return result;
+  return none;
 }
 
 } // namespace MaximInterfaceDevices