diff --git a/Sharpi/Pot.cs b/Sharpi/Pot.cs
new file mode 100644
index 0000000..87cf706
--- /dev/null
+++ b/Sharpi/Pot.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Sharpi
+{
+ public partial class Pot
+ {
+ // pot (common interface)
+
+ [DllImport("sharpi")]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ internal static extern string pot_get_description(IntPtr sensor);
+
+ [DllImport("sharpi")]
+ internal static extern void pot_delete(IntPtr sensor);
+
+
+ // pot (special functions for each type)
+
+
+ // AMG8833
+ [DllImport("sharpi")]
+ internal static extern IntPtr pot_ds3502_new(byte i2cAddress);
+
+ [DllImport("sharpi")]
+ internal static extern IntPtr pot_ds3502_new_x(byte i2cAddress, [MarshalAs(UnmanagedType.LPStr)] string i2cDevice);
+
+
+ [DllImport("sharpi")]
+ internal static extern void pot_ds3502_power_on(IntPtr sensor);
+
+ [DllImport("sharpi")]
+ internal static extern void pot_ds3502_power_off(IntPtr sensor);
+
+ [DllImport("sharpi")]
+ internal static extern byte pot_ds3502_get_wiper(IntPtr pot);
+
+ [DllImport("sharpi")]
+ internal static extern void pot_ds3502_set_wiper(IntPtr pot, byte value);
+
+ [DllImport("sharpi")]
+ internal static extern void pot_ds3502_set_wiper_persistent(IntPtr pot, byte value);
+ }
+
+ // sensor
+
+ public abstract class PotBase : IDisposable
+ {
+ protected IntPtr _handle = IntPtr.Zero;
+
+ public PotBase(IntPtr handle)
+ {
+ _handle = handle;
+ }
+
+ public void Dispose()
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ Pot.pot_delete(_handle);
+ _handle = IntPtr.Zero;
+ }
+ }
+
+ public string Description
+ {
+ get
+ {
+ if (_handle != IntPtr.Zero)
+ {
+ return Pot.pot_get_description(_handle);
+ }
+ else
+ {
+ return "";
+ }
+ }
+ }
+ }
+
+
+ public static partial class Pot
+ {
+ public class Ds3502 : PotBase
+ {
+ ///
+ /// Ds3502 digipot, standard i2caddress 0x28
+ ///
+ public Ds3502(byte i2caddress)
+ : base(pot_ds3502_new(i2caddress))
+ {
+ }
+
+ public Ds3502(byte i2caddress, string i2cdevice)
+ : base(pot_ds3502_new_x(i2caddress, i2cdevice))
+ {
+ }
+
+ public void PowerOn()
+ {
+ pot_ds3502_power_on(_handle);
+ }
+
+ public void PowerOff()
+ {
+ pot_ds3502_power_off(_handle);
+ }
+
+ public byte GetWiper()
+ {
+ return pot_ds3502_get_wiper(_handle);
+ }
+
+ ///
+ /// sets the wiper value
+ ///
+ /// 0..127
+ public void SetWiper(byte value)
+ {
+ pot_ds3502_set_wiper(_handle, value);
+ }
+
+ ///
+ /// sets the wiper value and stores it in the EEPROM (~50000 writes)
+ ///
+ /// 0..127
+ public void SetWiperPersistent(byte value)
+ {
+ pot_ds3502_set_wiper_persistent(_handle, value);
+ }
+ }
+
+ }
+
+
+}
diff --git a/Sharpi/Sharpi.csproj b/Sharpi/Sharpi.csproj
index ff0bc99..83851a4 100644
--- a/Sharpi/Sharpi.csproj
+++ b/Sharpi/Sharpi.csproj
@@ -14,7 +14,7 @@
img\sharpi.png
1.0.3.1
1.0.3.1
- 1.0.3.4
+ 1.0.3.5
Raspberry;Pi;iot;
https://github.com/A-J-Bauer/sharpi
diff --git a/Sharpi/cpp/sharpi/CMakeLists.txt b/Sharpi/cpp/sharpi/CMakeLists.txt
index 5419288..1638084 100644
--- a/Sharpi/cpp/sharpi/CMakeLists.txt
+++ b/Sharpi/cpp/sharpi/CMakeLists.txt
@@ -37,6 +37,9 @@ add_library(sharpi SHARED
SensorAmg8833.cpp
SensorIr28khz.h
SensorIr28khz.cpp
+ Pot.h
+ PotDs3502.h
+ PotDs3502.cpp
)
target_include_directories(sharpi
diff --git a/Sharpi/cpp/sharpi/Pot.h b/Sharpi/cpp/sharpi/Pot.h
new file mode 100644
index 0000000..6476f81
--- /dev/null
+++ b/Sharpi/cpp/sharpi/Pot.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include
+
+///
+/// The base class for pots, all pots participating in the C-Api have to derive from this
+///
+class Pot
+{
+
+public:
+ Pot() {};
+ virtual ~Pot() {};
+ virtual std::string GetDescription() = 0;
+ virtual const char* GetDescriptionC() = 0;
+ virtual void PowerOn() = 0;
+ virtual void PowerOff() = 0;
+};
+
+
diff --git a/Sharpi/cpp/sharpi/PotDs3502.cpp b/Sharpi/cpp/sharpi/PotDs3502.cpp
new file mode 100644
index 0000000..d9c7183
--- /dev/null
+++ b/Sharpi/cpp/sharpi/PotDs3502.cpp
@@ -0,0 +1,136 @@
+#include "PotDs3502.h"
+
+string PotDs3502::description =
+"----------------------------------------------\n"
+" Maxim DS3502 \n"
+" \n"
+" The DS3502 is a 7-bit, nonvolatile (NV) \n"
+" digital potentiometer (POT) featuring an \n"
+" output voltage range of up to 15.5V. \n"
+" Programming is accomplished by an I2C- \n"
+" compatible interface, which can operate at \n"
+" speeds of up to 400kHz.External voltages are \n"
+" applied at the RL and RH inputs to define the\n"
+" lowest and highest potentiometer outputs. \n"
+" (10 uSOP package) \n"
+" \n"
+" I2c slave address adjustable via A0 and A1 \n"
+" \n"
+" A convenient breakout board is available \n"
+" from Adafruit. \n"
+" \n"
+"config: \n"
+" \n"
+" edit /boot/config.txt \n"
+" dtparam=i2c_arm=on,i2c_arm_baudrate=400000 \n"
+" \n"
+"wiring: \n"
+" \n"
+" rpi physical pins \n"
+" \n"
+" vin -- 1 2 \n"
+" sda -- 3 4 \n"
+" scl -- 5 6 \n"
+" 7 8 \n"
+" gnd -- 9 10 ---------- \n"
+" (int) -- 11 12 sda -| + |- scl \n"
+" 13 14 gnd -| |- v+ \n"
+" 15 16 vcc -| ds3502 |- rl \n"
+" 17 18 a1 -| |- rw \n"
+" 19 20 a0 -| |- rh \n"
+" 21 22 ---------- \n"
+" 23 24 \n"
+" 25 26 \n"
+" 27 28 \n"
+" 29 30 \n"
+" 31 32 \n"
+" 33 34 \n"
+" 35 36 \n"
+" 37 38 \n"
+" 39 40 \n"
+" \n"
+"----------------------------------------------\n"
+;
+
+const string PotDs3502::I2CDEVICE = "/dev/i2c-1";
+
+PotDs3502::PotDs3502(uint8_t i2cAddress)
+ : PotDs3502::PotDs3502(i2cAddress, I2CDEVICE)
+{
+}
+
+PotDs3502::PotDs3502(uint8_t i2cAddress, string i2cDevice)
+{
+ _i2cAddress = i2cAddress;
+ _i2cDevice = i2cDevice;
+}
+
+PotDs3502::~PotDs3502()
+{
+}
+
+string PotDs3502::GetDescription()
+{
+ return description;
+};
+
+const char* PotDs3502::GetDescriptionC()
+{
+ return description.c_str();
+}
+
+void PotDs3502::PowerOn()
+{
+ if (_devI2c == NULL)
+ {
+ _devI2c = new DevI2c(_i2cDevice, _i2cAddress);
+ if (!_devI2c->Open())
+ {
+ delete _devI2c;
+ _devI2c = NULL;
+ }
+
+ _devI2c->WriteRegU8(Regs::CR::addr, Regs::CR::Modes::Mode_1_WR_ONLY);
+ }
+}
+
+void PotDs3502::PowerOff()
+{
+ if (_devI2c != NULL)
+ {
+ _devI2c->Close();
+ delete _devI2c;
+ _devI2c = NULL;
+ }
+}
+
+
+uint8_t PotDs3502::GetWiper(void)
+{
+ if (_devI2c == NULL) { return 0; };
+
+ uint8_t value;
+ _devI2c->ReadRegU8(Regs::WR::addr, &value);
+ return value;
+}
+
+void PotDs3502::SetWiper(uint8_t value)
+{
+ if (_devI2c == NULL) { return; };
+
+ if (value > 127) { return; }
+
+ _devI2c->WriteRegU8(Regs::WR::addr, value);
+}
+
+void PotDs3502::SetWiperPersistent(uint8_t value)
+{
+ if (_devI2c == NULL) { return; };
+
+ if (value > 127) { return; }
+
+ _devI2c->WriteRegU8(Regs::CR::addr, Regs::CR::Modes::Mode_0_WR_IVR);
+ _devI2c->WriteRegU8(Regs::WR::addr, value);
+ usleep(20000); // max EEPROM write time 20ms
+ _devI2c->WriteRegU8(Regs::CR::addr, Regs::CR::Modes::Mode_1_WR_ONLY);
+}
\ No newline at end of file
diff --git a/Sharpi/cpp/sharpi/PotDs3502.h b/Sharpi/cpp/sharpi/PotDs3502.h
new file mode 100644
index 0000000..5c67b8d
--- /dev/null
+++ b/Sharpi/cpp/sharpi/PotDs3502.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "Pot.h"
+#include "DevI2c.h"
+
+using namespace std;
+
+class PotDs3502 : Pot
+{
+private:
+ static string description;
+
+private:
+ static const string I2CDEVICE;
+
+ string _i2cDevice = I2CDEVICE;
+ DevI2c* _devI2c = NULL;
+ uint8_t _i2cAddress;
+
+public:
+ PotDs3502(uint8_t i2cAddress);
+ PotDs3502(uint8_t i2cAddress, string i2cDevice);
+ ~PotDs3502();
+
+ string GetDescription();
+ const char* GetDescriptionC();
+
+ void PowerOn();
+ void PowerOff();
+
+ uint8_t GetWiper(void);
+ void SetWiper(uint8_t value);
+ void SetWiperPersistent(uint8_t value); // 50000 - 200000 EEPROM writes
+
+public:
+ class Regs
+ {
+ public:
+ ///
+ /// Control Register
+ ///
+ class CR
+ {
+ public:
+ static const uint8_t addr = 0x02;
+ class Modes
+ {
+ public:
+ enum : uint8_t
+ {
+ ///
+ /// mode0: write to memory address 00h, write to both WR (Wiper Register) and IVR (Initial Value Register), read from WR
+ /// mode1: write to memory address 00h, write to WR, read from WR, for writing from SRAM to EEPROM an i2c stop must occur
+ ///
+ Mode_0_WR_IVR = 0x00,
+ Mode_1_WR_ONLY = 0x80
+ };
+ };
+ };
+
+ ///
+ /// Wiper Register
+ ///
+ class WR
+ {
+ public:
+ static const uint8_t addr = 0x00;
+
+ };
+ };
+};
\ No newline at end of file
diff --git a/Sharpi/cpp/sharpi/sharpi.cpp b/Sharpi/cpp/sharpi/sharpi.cpp
index 2df8684..67c5100 100644
--- a/Sharpi/cpp/sharpi/sharpi.cpp
+++ b/Sharpi/cpp/sharpi/sharpi.cpp
@@ -698,4 +698,57 @@ SHARPI void sensor_ir28khz_power_on(csensor* handle)
SHARPI void sensor_ir28khz_power_off(csensor* handle)
{
((SensorIr28khz*)handle)->PowerOff();
+}
+
+
+// pot common
+
+typedef struct cpot cpot;
+
+SHARPI const char* pot_get_description(cpot* handle)
+{
+ return ((Pot*)handle)->GetDescriptionC();
+}
+
+SHARPI void pot_delete(cpot* handle)
+{
+ delete ((Pot*)handle);
+}
+
+// pot specific
+
+
+SHARPI cpot* pot_ds3502_new(uint8_t i2cAddress)
+{
+ return (cpot*)new PotDs3502(i2cAddress);
+}
+
+SHARPI cpot* pot_ds3502_new_x(uint8_t i2cAddress, string i2cDevice)
+{
+ return (cpot*)new PotDs3502(i2cAddress, i2cDevice);
+}
+
+SHARPI void pot_ds3502_power_on(cpot* handle)
+{
+ ((PotDs3502*)handle)->PowerOn();
+}
+
+SHARPI void pot_ds3502_power_off(cpot* handle)
+{
+ ((PotDs3502*)handle)->PowerOff();
+}
+
+SHARPI uint8_t pot_ds3502_get_wiper(cpot* handle)
+{
+ return ((PotDs3502*)handle)->GetWiper();
+}
+
+SHARPI void pot_ds3502_set_wiper(cpot* handle, uint8_t value)
+{
+ ((PotDs3502*)handle)->SetWiper(value);
+}
+
+SHARPI void pot_ds3502_set_wiper_persistent(cpot* handle, uint8_t value)
+{
+ ((PotDs3502*)handle)->SetWiperPersistent(value);
}
\ No newline at end of file
diff --git a/Sharpi/cpp/sharpi/sharpi.h b/Sharpi/cpp/sharpi/sharpi.h
index 0cb8029..4a249a3 100644
--- a/Sharpi/cpp/sharpi/sharpi.h
+++ b/Sharpi/cpp/sharpi/sharpi.h
@@ -17,6 +17,8 @@
#include "AdcMcp3008.h"
#include "SensorAmg8833.h"
#include "SensorIr28khz.h"
+#include "Pot.h"
+#include "PotDs3502.h"
#include "include/core/SkImageEncoder.h"
#include "include/core/SkColor.h"
@@ -234,6 +236,25 @@ extern "C" {
SHARPI void sensor_ir28khz_power_on(csensor* handle);
SHARPI void sensor_ir28khz_power_off(csensor* handle);
+ // pot common
+
+ typedef struct cpot cpot;
+
+ SHARPI const char* pot_get_description(cpot* handle);
+ SHARPI void pot_delete(cpot* handle);
+
+ // pot specific
+
+ SHARPI cpot* pot_ds3502_new(uint8_t i2cAddress);
+ SHARPI cpot* pot_ds3502_new_x(uint8_t i2cAddress, string i2cDevice);
+
+ SHARPI void pot_ds3502_power_on(cpot* handle);
+ SHARPI void pot_ds3502_power_off(cpot* handle);
+
+ SHARPI uint8_t pot_ds3502_get_wiper(cpot* handle);
+ SHARPI void pot_ds3502_set_wiper(cpot* handle, uint8_t value);
+ SHARPI void pot_ds3502_set_wiper_persistent(cpot* handle, uint8_t value);
+
#ifdef __cplusplus
}
#endif
diff --git a/Sharpi/native/libsharpi.so b/Sharpi/native/libsharpi.so
index da07a13..2556453 100644
Binary files a/Sharpi/native/libsharpi.so and b/Sharpi/native/libsharpi.so differ