Extended MaximInterface

Dependents:   mbed_DS28EC20_GPIO

Revision:
0:f77ad7f72d04
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Platforms/dotnet/DS9481P_300.cpp	Mon Nov 06 14:39:18 2017 -0600
@@ -0,0 +1,283 @@
+/*******************************************************************************
+* Copyright (C) 2017 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"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************/
+
+#include <utility>
+#include <msclr/marshal_cppstd.h>
+#include <MaximInterface/Utilities/Error.hpp>
+#include "DS9481P_300.hpp"
+
+using System::IO::Ports::SerialPort;
+using msclr::interop::marshal_as;
+using std::string;
+
+namespace MaximInterface {
+
+DS9481P_300::DS9481P_300()
+    : currentBus(Bus::None), linkLayerMaster("{DS9097U_DS9480}"),
+      oneWireMaster_(*this), serial(), ds9400(serial), i2cMaster_(*this) {}
+
+DS9481P_300::~DS9481P_300() { disconnect(); }
+
+error_code DS9481P_300::connect(const string & portName) {
+  return connected() ? make_error_code(ConnectionStateError)
+                     : selectBus(Bus::OneWire, portName);
+}
+
+void DS9481P_300::disconnect() { selectBus(Bus::None); }
+
+string DS9481P_300::portName() const {
+  switch (currentBus) {
+  case Bus::I2C:
+    return serial.portName();
+
+  case Bus::OneWire:
+    return linkLayerMaster.portName();
+  }
+  return "";
+}
+
+error_code DS9481P_300::selectBus(Bus newBus) {
+  return connected() ? selectBus(newBus, portName())
+                     : make_error_code(ConnectionStateError);
+}
+
+error_code DS9481P_300::selectBus(Bus newBus, const string & portName) {
+  error_code result;
+  if (currentBus != newBus) {
+    const auto selectI2C = [this](const string & portName) {
+      auto result = serial.connect(portName);
+      if (!result) {
+        // Escape DS2480 Mode.
+        result = serial.writeByte(0xE5);
+      }
+	  if (!result) {
+	    // Wait for awake notification.
+		uint_least8_t data;
+		result = serial.readByte(data);
+	  }
+      return result;
+    };
+
+    const auto selectOneWire = [this](const string & portName) {
+      return linkLayerMaster.connect(portName);
+    };
+
+    switch (currentBus) {
+    case Bus::None:
+      switch (newBus) {
+      case Bus::OneWire:
+        result = selectOneWire(portName);
+        break;
+
+      case Bus::I2C:
+        result = selectI2C(portName);
+        break;
+      }
+      break;
+
+    case Bus::OneWire:
+      linkLayerMaster.disconnect();
+      switch (newBus) {
+      case Bus::I2C:
+        result = selectI2C(portName);
+        break;
+      }
+      break;
+
+    case Bus::I2C: {
+      constexpr uint_least8_t buffer[] = {'C', 'O'};
+      result = serial.writeBlock(buffer, sizeof(buffer) / sizeof(buffer[0]));
+      if (!result) {
+        serial.disconnect();
+        switch (newBus) {
+        case Bus::OneWire:
+          result = selectOneWire(portName);
+          break;
+        }
+      }
+    } break;
+    }
+    if (!result) {
+      currentBus = newBus;
+    }
+  }
+  return result;
+}
+
+error_code DS9481P_300::OneWireMasterImpl::reset() {
+  return selectAndExecute([this] { return OneWireMasterDecorator::reset(); });
+}
+
+error_code DS9481P_300::OneWireMasterImpl::touchBitSetLevel(bool & sendRecvBit,
+                                                            Level afterLevel) {
+  return selectAndExecute([this, &sendRecvBit, afterLevel] {
+    return OneWireMasterDecorator::touchBitSetLevel(sendRecvBit, afterLevel);
+  });
+}
+
+error_code
+DS9481P_300::OneWireMasterImpl::writeByteSetLevel(uint_least8_t sendByte,
+                                                  Level afterLevel) {
+  return selectAndExecute([this, sendByte, afterLevel] {
+    return OneWireMasterDecorator::writeByteSetLevel(sendByte, afterLevel);
+  });
+}
+
+error_code
+DS9481P_300::OneWireMasterImpl::readByteSetLevel(uint_least8_t & recvByte,
+                                                 Level afterLevel) {
+  return selectAndExecute([this, &recvByte, afterLevel] {
+    return OneWireMasterDecorator::readByteSetLevel(recvByte, afterLevel);
+  });
+}
+
+error_code
+DS9481P_300::OneWireMasterImpl::writeBlock(const uint_least8_t * sendBuf,
+                                           size_t sendLen) {
+  return selectAndExecute([this, sendBuf, sendLen] {
+    return OneWireMasterDecorator::writeBlock(sendBuf, sendLen);
+  });
+}
+
+error_code DS9481P_300::OneWireMasterImpl::readBlock(uint_least8_t * recvBuf,
+                                                     size_t recvLen) {
+  return selectAndExecute([this, recvBuf, recvLen] {
+    return OneWireMasterDecorator::readBlock(recvBuf, recvLen);
+  });
+}
+
+error_code DS9481P_300::OneWireMasterImpl::setSpeed(Speed newSpeed) {
+  return selectAndExecute(
+      [this, newSpeed] { return OneWireMasterDecorator::setSpeed(newSpeed); });
+}
+
+error_code DS9481P_300::OneWireMasterImpl::setLevel(Level newLevel) {
+  return selectAndExecute(
+      [this, newLevel] { return OneWireMasterDecorator::setLevel(newLevel); });
+}
+
+error_code DS9481P_300::OneWireMasterImpl::triplet(TripletData & data) {
+  return selectAndExecute(
+      [this, &data] { return OneWireMasterDecorator::triplet(data); });
+}
+
+template <typename Func>
+error_code DS9481P_300::OneWireMasterImpl::selectAndExecute(Func operation) {
+  auto result = parent->selectBus(Bus::OneWire);
+  if (!result) {
+    result = operation();
+  }
+  return result;
+}
+
+error_code DS9481P_300::I2CMasterImpl::start(uint_least8_t address) {
+  return selectAndExecute(
+      [this, address] { return I2CMasterDecorator::start(address); });
+}
+
+error_code DS9481P_300::I2CMasterImpl::stop() {
+  return selectAndExecute([this] { return I2CMasterDecorator::stop(); });
+}
+
+error_code DS9481P_300::I2CMasterImpl::writeByte(uint_least8_t data) {
+  return selectAndExecute(
+      [this, data] { return I2CMasterDecorator::writeByte(data); });
+}
+
+error_code DS9481P_300::I2CMasterImpl::writeBlock(const uint_least8_t * data,
+                                                  size_t dataLen) {
+  return selectAndExecute([this, data, dataLen] {
+    return I2CMasterDecorator::writeBlock(data, dataLen);
+  });
+}
+
+error_code DS9481P_300::I2CMasterImpl::writePacket(uint_least8_t address,
+                                                   const uint_least8_t * data,
+                                                   size_t dataLen,
+                                                   bool sendStop) {
+  return selectAndExecute([this, address, data, dataLen, sendStop] {
+    return I2CMasterDecorator::writePacket(address, data, dataLen, sendStop);
+  });
+}
+
+error_code DS9481P_300::I2CMasterImpl::readByte(AckStatus status,
+                                                uint_least8_t & data) {
+  return selectAndExecute([this, status, &data] {
+    return I2CMasterDecorator::readByte(status, data);
+  });
+}
+
+error_code DS9481P_300::I2CMasterImpl::readBlock(AckStatus status,
+                                                 uint_least8_t * data,
+                                                 size_t dataLen) {
+  return selectAndExecute([this, status, data, dataLen] {
+    return I2CMasterDecorator::readBlock(status, data, dataLen);
+  });
+}
+
+error_code DS9481P_300::I2CMasterImpl::readPacket(uint_least8_t address,
+                                                  uint_least8_t * data,
+                                                  size_t dataLen,
+                                                  bool sendStop) {
+  return selectAndExecute([this, address, data, dataLen, sendStop] {
+    return I2CMasterDecorator::readPacket(address, data, dataLen, sendStop);
+  });
+}
+
+template <typename Func>
+error_code DS9481P_300::I2CMasterImpl::selectAndExecute(Func operation) {
+  auto result = parent->selectBus(Bus::I2C);
+  if (!result) {
+    result = operation();
+  }
+  return result;
+}
+
+const error_category & DS9481P_300::errorCategory() {
+  static class : public error_category {
+  public:
+    virtual const char * name() const { return "DS9481P_300"; }
+
+    virtual std::string message(int condition) const {
+      switch (condition) {
+      case ConnectionStateError:
+        return "Connection State Error";
+
+      default:
+        return defaultErrorMessage(condition);
+      }
+    }
+  } instance;
+  return instance;
+}
+
+} // namespace MaximInterface
\ No newline at end of file