From 11f3badf4609e082e09a374f634717d65855bce3 Mon Sep 17 00:00:00 2001
From: Karol Krizka <karol.krizka@cern.ch>
Date: Wed, 25 Dec 2019 10:07:21 +0000
Subject: [PATCH] libDevCom: Add AD56X9 as a new DAC.

---
 src/libDevCom/AD56X9.cpp     | 62 ++++++++++++++++++++++++++++++++++++
 src/libDevCom/AD56X9.h       | 43 +++++++++++++++++++++++++
 src/libDevCom/CMakeLists.txt |  2 +-
 src/libDevCom/DACDevice.h    |  4 +--
 4 files changed, 108 insertions(+), 3 deletions(-)
 create mode 100644 src/libDevCom/AD56X9.cpp
 create mode 100644 src/libDevCom/AD56X9.h

diff --git a/src/libDevCom/AD56X9.cpp b/src/libDevCom/AD56X9.cpp
new file mode 100644
index 00000000..c2162720
--- /dev/null
+++ b/src/libDevCom/AD56X9.cpp
@@ -0,0 +1,62 @@
+#include "AD56X9.h"
+
+#include "LinearCalibration.h"
+
+#include "NotSupportedException.h"
+#include "OutOfRangeException.h"
+
+const std::map<AD56X9::Model, AD56X9ModelInfo> AD56X9::ModelInfo =
+  {
+   {AD56X9::Model::AD5629, AD56X9ModelInfo({.MaxValue=0xFFF }) },
+   {AD56X9::Model::AD5669, AD56X9ModelInfo({.MaxValue=0xFFFF}) }
+  };
+
+AD56X9::AD56X9(double reference, Model model, std::shared_ptr<I2CCom> com)
+  : DACDevice(std::make_shared<LinearCalibration>(reference, ModelInfo.at(model).MaxValue)),
+    m_model(model), m_com(com)
+{ }
+
+AD56X9::~AD56X9()
+{ }
+
+void AD56X9::setCount(int32_t counts)
+{
+  counts&=ModelInfo.at(m_model).MaxValue;
+  if(m_model==Model::AD5629)
+    counts<<=4;
+  counts&=0xFFFF;
+  m_com->write_block({0x3F,static_cast<uint8_t>((counts>>8)&0xFF),static_cast<uint8_t>((counts>>0)&0xFF)});
+}
+
+void AD56X9::setCount(uint8_t ch, int32_t counts)
+{
+  if(ch>7)
+    throw OutOfRangeException(ch,0,7);
+
+  if(m_model==Model::AD5629)
+    counts<<=4;
+  counts&=0xFFFF;
+
+  m_com->write_block({static_cast<uint8_t>(0x30|(ch&0xF)),static_cast<uint8_t>((counts>>8)&0xFF),static_cast<uint8_t>((counts>>0)&0xFF)});
+}
+
+void AD56X9::setCount(const std::vector<uint8_t>& chs, const std::vector<int32_t>& data)
+{
+  for(uint i=0;i<chs.size();i++)
+    setCount(chs[i],data[i]);
+}
+
+int32_t AD56X9::readCount()
+{
+  throw NotSupportedException("AD56X9 does not support reading.");
+}
+
+int32_t AD56X9::readCount(uint8_t ch)
+{
+  throw NotSupportedException("AD56X9 does not support reading.");
+}
+
+void AD56X9::readCount(const std::vector<uint8_t>& chs, std::vector<int32_t>& counts)
+{
+  throw NotSupportedException("AD56X9 does not support reading.");
+}
diff --git a/src/libDevCom/AD56X9.h b/src/libDevCom/AD56X9.h
new file mode 100644
index 00000000..ee8f4c20
--- /dev/null
+++ b/src/libDevCom/AD56X9.h
@@ -0,0 +1,43 @@
+#ifndef AD56X9_H
+#define AD56X9_H
+
+#include <stdint.h>
+
+#include <memory>
+#include <map>
+
+#include "I2CCom.h"
+#include "DACDevice.h"
+
+struct AD56X9ModelInfo
+{
+  int32_t MaxValue;
+};
+
+class AD56X9 : public DACDevice
+{
+public:
+  enum Model {AD5629, AD5669};
+
+  AD56X9(double reference, Model model, std::shared_ptr<I2CCom> com);
+  virtual ~AD56X9();
+
+  virtual void setCount(int32_t counts);
+  virtual void setCount(uint8_t ch, int32_t counts);
+  virtual void setCount(const std::vector<uint8_t>& chs, const std::vector<int32_t>& data);
+
+  virtual int32_t readCount();
+  virtual int32_t readCount(uint8_t ch);
+  virtual void    readCount(const std::vector<uint8_t>& chs, std::vector<int32_t>& data);
+
+private:
+  // Model information
+  static const std::map<Model, AD56X9ModelInfo> ModelInfo;
+  
+  // Properties of device
+  Model m_model;
+  
+  std::shared_ptr<I2CCom> m_com;
+};
+
+#endif // AD56X9_H
diff --git a/src/libDevCom/CMakeLists.txt b/src/libDevCom/CMakeLists.txt
index 8322b220..89d795d2 100644
--- a/src/libDevCom/CMakeLists.txt
+++ b/src/libDevCom/CMakeLists.txt
@@ -26,7 +26,7 @@ target_sources(DevCom
   DAC5571.cpp
   DAC5574.cpp
   MCP4801.cpp
-  #LTC2666.cpp
+  AD56X9.cpp
 
   ADCDevice.cpp
   AD799X.cpp
diff --git a/src/libDevCom/DACDevice.h b/src/libDevCom/DACDevice.h
index 7394e298..1a6625ff 100644
--- a/src/libDevCom/DACDevice.h
+++ b/src/libDevCom/DACDevice.h
@@ -24,7 +24,7 @@ public:
 
   virtual int32_t readCount() =0;
   virtual int32_t readCount(uint8_t ch) =0;
-  virtual void readCount(const std::vector<uint8_t>& chs, std::vector<int32_t>& data) =0;
+  virtual void    readCount(const std::vector<uint8_t>& chs, std::vector<int32_t>& data) =0;
 
   double set(double value);
   double set(uint8_t ch, double value);
@@ -32,7 +32,7 @@ public:
 
   double read();
   double read(uint8_t ch);
-  void read(const std::vector<uint8_t>& chs, std::vector<double>& data);
+  void   read(const std::vector<uint8_t>& chs, std::vector<double>& data);
 
 private:
   std::shared_ptr<DeviceCalibration> findCalibration(uint8_t ch) const;
-- 
GitLab