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
--- a/MaximInterfaceDevices/DS28E15_22_25.hpp	Mon Jul 22 11:44:07 2019 -0500
+++ b/MaximInterfaceDevices/DS28E15_22_25.hpp	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"),
@@ -30,8 +30,8 @@
 * ownership rights.
 *******************************************************************************/
 
-#ifndef MaximInterfaceDevices_DS28E15_22_25
-#define MaximInterfaceDevices_DS28E15_22_25
+#ifndef MaximInterfaceDevices_DS28E15_22_25_hpp
+#define MaximInterfaceDevices_DS28E15_22_25_hpp
 
 #include <stdint.h>
 #include <MaximInterfaceCore/Algorithm.hpp>
@@ -48,6 +48,9 @@
 /// @brief
 /// Interface to the DS28E15/22/25 series of authenticators
 /// including low power variants.
+/// @details
+/// Const member functions should not affect the state of the memory,
+/// block protection, or secret on the device.
 class DS28E15_22_25 {
 public:
   enum ErrorValue { CrcError = 1, OperationFailure };
@@ -91,54 +94,51 @@
     this->selectRom = selectRom;
   }
 
-  // Const member functions should not affect the state of the memory,
-  // block protection, or secret on the device.
-
   /// @brief Read memory segment using the Read Memory command on the device.
   /// @param pageNum Page number for read operation.
   /// @param segmentNum Segment number within page for read operation.
-  /// @param[out] data Buffer to read data from the segment into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readSegment(int pageNum, int segmentNum, Segment::span data) const;
+  /// @returns Buffer to read data from the segment into.
+  MaximInterfaceDevices_EXPORT Core::Result<Segment::array>
+  readSegment(int pageNum, int segmentNum) const;
 
   /// @brief Continue an in-progress readSegment operation.
   /// @note A CRC16 will encountered after reading the last segment of a page.
-  /// @param[out] data Buffer to read data from the segment into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  continueReadSegment(Segment::span data) const;
+  /// @returns Buffer to read data from the segment into.
+  MaximInterfaceDevices_EXPORT Core::Result<Segment::array>
+  continueReadSegment() const;
 
   /// @brief Write memory segment using the Write Memory command.
   /// @note 1-Wire ROM selection should have already occurred.
   /// @param pageNum Page number for write operation.
   /// @param segmentNum Segment number within page for write operation.
   /// @param[in] data Data to write to the memory segment.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeSegment(int pageNum, int segmentNum, Segment::const_span data);
 
   /// @brief Continue an in-progress Write Memory command.
   /// @param[in] data Data to write to the memory segment.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   continueWriteSegment(Segment::const_span data);
 
   /// @brief Read memory page using the Read Memory command on the device.
   /// @param pageNum Page number for write operation.
-  /// @param[out] rdbuf Buffer to read data from the page into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readPage(int pageNum, Page::span rdbuf) const;
+  /// @returns Buffer to read data from the page into.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  readPage(int pageNum) const;
 
   /// @brief Continue an in-progress readPageOperation.
-  /// @param[out] rdbuf Buffer to read data from the page into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  continueReadPage(Page::span rdbuf) const;
+  /// @returns Buffer to read data from the page into.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  continueReadPage() const;
 
   /// @brief
   /// Perform a Compute Page MAC command on the device.
   /// Read back the MAC and verify the CRC16.
   /// @param pageNum Page number to use for the computation.
   /// @param anon True to compute in anonymous mode where ROM ID is not used.
-  /// @param[out] mac The device computed MAC.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  computeReadPageMac(int pageNum, bool anon, Page::span mac) const;
+  /// @returns The device computed MAC.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array>
+  computeReadPageMac(int pageNum, bool anon) const;
 
   /// @brief
   /// Update the status of a memory protection block using the
@@ -146,7 +146,7 @@
   /// @param protection
   /// Desired protection status for the block.
   /// It is not possible to disable existing protections.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeBlockProtection(BlockProtection protection);
 
   /// @brief
@@ -154,26 +154,26 @@
   /// Authenticated Write Page Protection command.
   /// @param newProtection New protection status to write.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeAuthBlockProtection(BlockProtection newProtection, Page::const_span mac);
 
   /// @brief Perform Load and Lock Secret command on the device.
   /// @note The secret should already be stored in the scratchpad on the device.
   /// @param lock
   /// Prevent further changes to the secret on the device after loading.
-  MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
 
   /// @brief Perform a Compute and Lock Secret command on the device.
   /// @param pageNum Page number to use as the binding data.
   /// @param lock
   /// Prevent further changes to the secret on the device after computing.
-  MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
-                                                              bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
+                                                                bool lock);
 
   /// @brief Read the personality bytes using the Read Status command.
-  /// @param[out] personality Receives personality read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readPersonality(Personality & personality) const;
+  /// @returns Receives personality read from device.
+  MaximInterfaceDevices_EXPORT Core::Result<Personality>
+  readPersonality() const;
 
   MaximInterfaceDevices_EXPORT static const Core::error_category &
   errorCategory();
@@ -187,29 +187,28 @@
 
   ~DS28E15_22_25() {}
 
-  Core::error_code doWriteScratchpad(Page::const_span data, Variant variant);
-
-  Core::error_code doReadScratchpad(Page::span data, Variant variant) const;
+  Core::Result<void> doWriteScratchpad(Page::const_span data, Variant variant);
 
-  Core::error_code doReadBlockProtection(int blockNum,
-                                         BlockProtection & protection,
-                                         Variant variant) const;
+  Core::Result<Page::array> doReadScratchpad(Variant variant) const;
+
+  Core::Result<BlockProtection> doReadBlockProtection(int blockNum,
+                                                      Variant variant) const;
 
-  Core::error_code doWriteAuthSegment(int pageNum, int segmentNum,
-                                      Segment::const_span newData,
-                                      Page::const_span mac, Variant variant);
+  Core::Result<void> doWriteAuthSegment(int pageNum, int segmentNum,
+                                        Segment::const_span newData,
+                                        Page::const_span mac, Variant variant);
 
-  Core::error_code doContinueWriteAuthSegment(Segment::const_span newData,
-                                              Page::const_span mac,
-                                              Variant variant);
+  Core::Result<void> doContinueWriteAuthSegment(Segment::const_span newData,
+                                                Page::const_span mac,
+                                                Variant variant);
 
-  Core::error_code
+  Core::Result<void>
   doReadAllBlockProtection(Core::span<BlockProtection> protection,
                            Variant variant) const;
 
-  Core::error_code doLoadSecret(bool lock, bool lowPower);
+  Core::Result<void> doLoadSecret(bool lock, bool lowPower);
 
-  Core::error_code doComputeSecret(int pageNum, bool lock, bool lowPower);
+  Core::Result<void> doComputeSecret(int pageNum, bool lock, bool lowPower);
 
 private:
   enum Command {
@@ -225,11 +224,11 @@
     AuthWriteBlockProtection = 0xCC,
   };
 
-  Core::error_code doWriteAuthSegment(Segment::const_span newData,
-                                      Page::const_span mac, Variant variant,
-                                      bool continuing);
+  Core::Result<void> doWriteAuthSegment(Segment::const_span newData,
+                                        Page::const_span mac, Variant variant,
+                                        bool continuing);
 
-  Core::error_code
+  Core::Result<void>
   writeCommandWithCrc(Command command, uint_least8_t parameter,
                       Core::OneWireMaster::Level level =
                           Core::OneWireMaster::NormalLevel) const;
@@ -239,6 +238,16 @@
   Core::Sleep * sleep;
 };
 
+} // namespace MaximInterfaceDevices
+namespace MaximInterfaceCore {
+
+template <>
+struct is_error_code_enum<MaximInterfaceDevices::DS28E15_22_25::ErrorValue>
+    : true_type {};
+
+} // namespace MaximInterfaceCore
+namespace MaximInterfaceDevices {
+
 inline Core::error_code make_error_code(DS28E15_22_25::ErrorValue e) {
   return Core::error_code(e, DS28E15_22_25::errorCategory());
 }
@@ -256,41 +265,41 @@
 
   /// @brief Perform Write Scratchpad operation on the device.
   /// @param[in] data Data to write to the scratchpad.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeScratchpad(Page::const_span data);
 
   /// @brief Perform a Read Scratchpad operation on the device.
-  /// @param[out] data Buffer to read data from the scratchpad into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readScratchpad(Page::span data) const;
+  /// @returns Buffer to read data from the scratchpad into.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
 
   /// @brief
   /// Read the status of a memory protection block using the Read Status command.
   /// @param blockNum Block number to to read status of.
-  /// @param[out] protection Receives protection status read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readBlockProtection(int blockNum, BlockProtection & protection) const;
+  /// @returns Receives protection status read from device.
+  MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
+  readBlockProtection(int blockNum) const;
 
   /// @brief Write memory segment using the Authenticated Write Memory command.
   /// @param pageNum Page number for write operation.
   /// @param segmentNum Segment number within page for write operation.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
                    Page::const_span mac);
 
   /// @brief Continue an in-progress Authenticated Write Memory command.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
 
   /// @brief
   /// Read the status of all memory protection blocks using the Read Status command.
-  /// @param[out] protection Receives protection statuses read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
-      Core::span<BlockProtection, protectionBlocks> protection) const;
+  /// @returns Receives protection statuses read from device.
+  MaximInterfaceDevices_EXPORT
+      Core::Result<Core::array<BlockProtection, protectionBlocks> >
+      readAllBlockProtection() const;
 };
 
 /// Interface to the DS28E15 authenticator.
@@ -304,14 +313,14 @@
   /// @note The secret should already be stored in the scratchpad on the device.
   /// @param lock
   /// Prevent further changes to the secret on the device after loading.
-  MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
 
   /// @brief Perform a Compute and Lock Secret command on the device.
   /// @param pageNum Page number to use as the binding data.
   /// @param lock
   /// Prevent further changes to the secret on the device after computing.
-  MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
-                                                              bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
+                                                                bool lock);
 };
 
 /// Interface to the DS28EL22 (low power) authenticator.
@@ -327,41 +336,41 @@
 
   /// @brief Perform Write Scratchpad operation on the device.
   /// @param[in] data Data to write to the scratchpad.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeScratchpad(Page::const_span data);
 
   /// @brief Perform a Read Scratchpad operation on the device.
-  /// @param[out] data Buffer to read data from the scratchpad into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readScratchpad(Page::span data) const;
+  /// @returns Buffer to read data from the scratchpad into.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
 
   /// @brief
   /// Read the status of a memory protection block using the Read Status command.
   /// @param blockNum Block number to to read status of.
-  /// @param[out] protection Receives protection status read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readBlockProtection(int blockNum, BlockProtection & protection) const;
+  /// @returns Receives protection status read from device.
+  MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
+  readBlockProtection(int blockNum) const;
 
   /// @brief Write memory segment using the Authenticated Write Memory command.
   /// @param pageNum Page number for write operation.
   /// @param segmentNum Segment number within page for write operation.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
                    Page::const_span mac);
 
   /// @brief Continue an in-progress Authenticated Write Memory command.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
 
   /// @brief
   /// Read the status of all memory protection blocks using the Read Status command.
-  /// @param[out] protection Receives protection statuses read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
-      Core::span<BlockProtection, protectionBlocks> protection) const;
+  /// @returns Receives protection statuses read from device.
+  MaximInterfaceDevices_EXPORT
+      Core::Result<Core::array<BlockProtection, protectionBlocks> >
+      readAllBlockProtection() const;
 };
 
 /// Interface to the DS28E22 authenticator.
@@ -375,14 +384,14 @@
   /// @note The secret should already be stored in the scratchpad on the device.
   /// @param lock
   /// Prevent further changes to the secret on the device after loading.
-  MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
 
   /// @brief Perform a Compute and Lock Secret command on the device.
   /// @param pageNum Page number to use as the binding data.
   /// @param lock
   /// Prevent further changes to the secret on the device after computing.
-  MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
-                                                              bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
+                                                                bool lock);
 };
 
 /// Interface to the DS28EL25 (low power) authenticator.
@@ -398,41 +407,41 @@
 
   /// @brief Perform Write Scratchpad operation on the device.
   /// @param[in] data Data to write to the scratchpad.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeScratchpad(Page::const_span data);
 
   /// @brief Perform a Read Scratchpad operation on the device.
-  /// @param[out] data Buffer to read data from the scratchpad into.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readScratchpad(Page::span data) const;
+  /// @returns Buffer to read data from the scratchpad into.
+  MaximInterfaceDevices_EXPORT Core::Result<Page::array> readScratchpad() const;
 
   /// @brief
   /// Read the status of a memory protection block using the Read Status command.
   /// @param blockNum Block number to to read status of.
-  /// @param[out] protection Receives protection status read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code
-  readBlockProtection(int blockNum, BlockProtection & protection) const;
+  /// @returns Receives protection status read from device.
+  MaximInterfaceDevices_EXPORT Core::Result<BlockProtection>
+  readBlockProtection(int blockNum) const;
 
   /// Write memory segment using the Authenticated Write Memory command.
   /// @param pageNum Page number for write operation.
   /// @param segmentNum Segment number within page for write operation.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
                    Page::const_span mac);
 
   /// @brief Continue an in-progress Authenticated Write Memory command.
   /// @param[in] newData New data to write to the segment.
   /// @param[in] mac Write MAC computed for this operation.
-  MaximInterfaceDevices_EXPORT Core::error_code
+  MaximInterfaceDevices_EXPORT Core::Result<void>
   continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
 
   /// @brief
   /// Read the status of all memory protection blocks using the Read Status command.
-  /// @param[out] protection Receives protection statuses read from device.
-  MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
-      Core::span<BlockProtection, protectionBlocks> protection) const;
+  /// @returns Receives protection statuses read from device.
+  MaximInterfaceDevices_EXPORT
+      Core::Result<Core::array<BlockProtection, protectionBlocks> >
+      readAllBlockProtection() const;
 };
 
 /// Interface to the DS28E25 authenticator.
@@ -445,14 +454,14 @@
   /// @brief Perform Load and Lock Secret command on the device.
   /// @note The secret should already be stored in the scratchpad on the device.
   /// @param lock Prevent further changes to the secret on the device after loading.
-  MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> loadSecret(bool lock);
 
   /// @brief Perform a Compute and Lock Secret command on the device.
   /// @param pageNum Page number to use as the binding data.
   /// @param lock
   /// Prevent further changes to the secret on the device after computing.
-  MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
-                                                              bool lock);
+  MaximInterfaceDevices_EXPORT Core::Result<void> computeSecret(int pageNum,
+                                                                bool lock);
 };
 
 /// Represents the status of a memory protection block.
@@ -523,20 +532,11 @@
   static const unsigned int readProtectionMask = 0x80,
                             writeProtectionMask = 0x40,
                             eepromEmulationMask = 0x20,
-                            authProtectionMask = 0x10, blockNumMask = 0x0F;
+                            authProtectionMask = 0x10,
+                            blockNumMask = 0x0F;
   uint_least8_t status;
 };
 
-inline bool operator==(DS28E15_22_25::BlockProtection lhs,
-                       DS28E15_22_25::BlockProtection rhs) {
-  return lhs.statusByte() == rhs.statusByte();
-}
-
-inline bool operator!=(DS28E15_22_25::BlockProtection lhs,
-                       DS28E15_22_25::BlockProtection rhs) {
-  return !operator==(lhs, rhs);
-}
-
 /// Format data to hash for an Authenticated Write to a memory segment.
 class DS28E15_22_25::SegmentWriteMacData {
 public:
@@ -666,14 +666,12 @@
   /// @}
 
 private:
-  typedef Result::span::index_type index;
-
-  static const index romIdIdx = 0;
-  static const index manIdIdx = romIdIdx + Core::RomId::size;
-  static const index pageNumIdx = manIdIdx + Core::ManId::size;
-  static const index segmentNumIdx = pageNumIdx + 1;
-  static const index oldDataIdx = segmentNumIdx + 1;
-  static const index newDataIdx = oldDataIdx + Segment::size;
+  static const size_t romIdIdx = 0;
+  static const size_t manIdIdx = romIdIdx + Core::RomId::size;
+  static const size_t pageNumIdx = manIdIdx + Core::ManId::size;
+  static const size_t segmentNumIdx = pageNumIdx + 1;
+  static const size_t oldDataIdx = segmentNumIdx + 1;
+  static const size_t newDataIdx = oldDataIdx + Segment::size;
 
   Result::array result_;
 };
@@ -759,13 +757,11 @@
   /// @}
 
 private:
-  typedef Result::span::index_type index;
-
-  static const index romIdIdx = 0;
-  static const index manIdIdx = romIdIdx + Core::RomId::size;
-  static const index blockNumIdx = manIdIdx + Core::ManId::size;
-  static const index oldProtectionIdx = blockNumIdx + 2;
-  static const index newProtectionIdx = oldProtectionIdx + 4;
+  static const size_t romIdIdx = 0;
+  static const size_t manIdIdx = romIdIdx + Core::RomId::size;
+  static const size_t blockNumIdx = manIdIdx + Core::ManId::size;
+  static const size_t oldProtectionIdx = blockNumIdx + 2;
+  static const size_t newProtectionIdx = oldProtectionIdx + 4;
 
   Result::array result_;
   BlockProtection oldProtection_;
@@ -893,13 +889,11 @@
   /// @}
 
 private:
-  typedef Result::span::index_type index;
-
-  static const index pageIdx = 0;
-  static const index scratchpadIdx = pageIdx + Page::size;
-  static const index romIdIdx = scratchpadIdx + Page::size;
-  static const index manIdIdx = romIdIdx + Core::RomId::size;
-  static const index pageNumIdx = manIdIdx + Core::ManId::size;
+  static const size_t pageIdx = 0;
+  static const size_t scratchpadIdx = pageIdx + Page::size;
+  static const size_t romIdIdx = scratchpadIdx + Page::size;
+  static const size_t manIdIdx = romIdIdx + Core::RomId::size;
+  static const size_t pageNumIdx = manIdIdx + Core::ManId::size;
 
   Result::array result_;
 };