-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcedargrove_ad5293.py
executable file
·132 lines (103 loc) · 4.87 KB
/
cedargrove_ad5293.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# SPDX-FileCopyrightText: Copyright (c) 2023 JG for Cedar Grove Maker Studios
#
# SPDX-License-Identifier: MIT
"""
`cedargrove_ad5293`
================================================================================
A CircuitPython driver for the AD5293 digital potentiometer.
* Author(s): JG
Implementation Notes
--------------------
**Hardware:**
* Cedar Grove Studios AD5293 breakout or equivalent
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://circuitpython.org/downloads
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
"""
import time
import digitalio
from adafruit_bus_device.spi_device import SPIDevice
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/CedarGroveStudios/Cedargrove_CircuitPython_AD5293.git"
class AD5293:
"""Class representing the Cedar Grove AD5293, an SPI digital linear taper
potentiometer breakout module.
The AD5293 Digital Potentiometer is an SPI, 10-bit, 100K-ohm device. The
device operates with a digital logic power source of 2.7v to 5.5v and a
dual analog power source of +/-9v to +/-16.5v. The potentiometer pins act
similarly to a passive resistive potentiometer, but requires that voltages
placed on any of the three pins not exceed the analog power supply voltage.
The CircuitPython driver supports a single SPI potentiometer device per
instance. Connecting the SDO pin to the SPI host input pin is not required
nor recommended since the SDO pin could interfere with other SPI-connected
devices.
This driver does not work with daisy-chained devices.
The Cedar Grove AD5293 custom breakout board provides power and signal
connections for SPI and the potentiometer chip. The AD5293 is also used in
the AD9833-based Cedar Grove Precision VCO Eurorack module."""
def __init__(self, spi=None, select=None, wiper=0):
"""Initialize the AD5293 device instance. During initialization, the
potentiometer is reset, writing is enabled, and the wiper is set to the
specified initialization value.
:param busio.SPI spi: The `busio.SPI` definition. Defaults to None.
:param board select: The chip select pin designation. Defaults to None.
:param int wiper: The initial 10-bit potentiometer wiper integer value,
range from 0 to 1023. Defaults to 0."""
# Define the SPI bus connection
self._spi = spi
chip_sel = digitalio.DigitalInOut(select)
self._device = SPIDevice(
self._spi, chip_sel, baudrate=1000000, polarity=0, phase=1
)
# Power on delay (2ms minimum)
time.sleep(0.03)
# Place device into normal mode (not powered-down)
self._send_data(0x2000)
# Reset the device and disable write-protect
self.reset()
# Set initial wiper value
if wiper < 0 or wiper > 1023:
raise ValueError("Raw wiper value must be from 0 to 1023")
self._wiper = wiper
self._normalized_wiper = self._wiper / 1023.0
self._send_data(0x0400 | wiper)
@property
def wiper(self):
"""The raw value of the potentiometer's wiper."""
return self._wiper
@wiper.setter
def wiper(self, new_wiper=0):
"""Set the raw value of the potentiometer's wiper.
:param new_wiper: The raw wiper value from 0 to 1023."""
if new_wiper < 0 or new_wiper > 1023:
raise ValueError("Raw wiper value must be from 0 to 1023")
self._send_data(0x0400 | int(new_wiper))
self._wiper = new_wiper
@property
def normalized_wiper(self):
"""The normalized value of the potentiometer's wiper."""
return self._normalized_wiper
@normalized_wiper.setter
def normalized_wiper(self, new_norm_wiper):
"""Set the normalized value of the potentiometer's wiper.
:param new_norm_wiper: The normalized wiper value from 0.0 to 1.0."""
if new_norm_wiper < 0 or new_norm_wiper > 1.0:
raise ValueError("Normalized wiper value must be from 0.0 to 1.0")
self._send_data(0x0400 | int(new_norm_wiper * 1023.0))
self._normalized_wiper = new_norm_wiper
def shutdown(self):
"""Connects the W pin to the B pin and opens the A pin. The content
of the wiper register is not changed."""
self._send_data(0x2001)
def reset(self):
"""Reset the potentiometer. Refresh RDAC with mid-scale value. Disable
write-protect."""
self._send_data(0x1000) # Reset
time.sleep(0.002) # Reset delay (1.5ms min)
self._send_data(0x1802) # Disable write-protect
def _send_data(self, data):
"""Send a 16-bit word through SPI bus as two 8-bit bytes.
:param int data: The 16-bit data value to write to the SPI device."""
with self._device:
self._spi.write(bytes([data >> 8, data & 0xFF]))