45
45
__version__ = "0.0.0-auto.0"
46
46
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MCP4728.git"
47
47
48
+ from struct import pack_into
48
49
from time import sleep
49
50
import adafruit_bus_device .i2c_device as i2c_device
50
51
from adafruit_register .i2c_struct import UnaryStruct
@@ -133,22 +134,18 @@ def _cache_page(self, value, vref, gain, pd):
133
134
def _create_channels (self ):
134
135
raw_registers = self ._read_registers ()
135
136
136
- self .channel_a = Channel (self ._cache_page (* raw_registers [0 ]))
137
- self .channel_b = Channel (self ._cache_page (* raw_registers [1 ]))
138
- self .channel_c = Channel (self ._cache_page (* raw_registers [2 ]))
139
- self .channel_d = Channel (self ._cache_page (* raw_registers [3 ]))
137
+ self .channel_a = Channel (self , self ._cache_page (* raw_registers [0 ]), 0 )
138
+ self .channel_b = Channel (self , self ._cache_page (* raw_registers [1 ]), 1 )
139
+ self .channel_c = Channel (self , self ._cache_page (* raw_registers [2 ]), 2 )
140
+ self .channel_d = Channel (self , self ._cache_page (* raw_registers [3 ]), 3 )
140
141
141
142
def _read_registers (self ):
142
143
buf = bytearray (24 )
143
144
144
145
with self .i2c_device as i2c :
145
146
i2c .readinto (buf )
146
- index = 0
147
- for index , value in enumerate (buf ):
148
- if index % 3 == 0 :
149
- print ("\n %4s\t " % index , end = "" )
150
- print ("%s %s " % (format (value , '#010b' ), hex (value )), end = "" )
151
- print ()
147
+
148
+ self ._print_buffer (buf )
152
149
153
150
# stride is 6 because we get 6 bytes for each channel; 3 for the output regs
154
151
# and 3 for the eeprom. here we only care about the output buffer so we throw out
@@ -161,37 +158,108 @@ def _read_registers(self):
161
158
162
159
return current_values
163
160
161
+ def _print_buffer (self , buf ):
162
+ print ()
163
+ for index , value in enumerate (buf ):
164
+ if index % 3 == 0 :
165
+ print ("\n %4s\t " % index , end = "" )
166
+ print ("%s %s " % (format (value , '#010b' ), hex (value )), end = "" )
167
+ print ()
168
+
169
+
170
+ def save_settings (self ):
171
+ """Saves the currently selected values, Vref, and gain selections for each channel to the EEPROM, setting them as defaults on power up"""
172
+ byte_list = []
173
+ byte_list += self ._generate_bytes_with_flags (self .channel_a )
174
+ byte_list += self ._generate_bytes_with_flags (self .channel_b )
175
+ byte_list += self ._generate_bytes_with_flags (self .channel_c )
176
+ byte_list += self ._generate_bytes_with_flags (self .channel_d )
177
+ self ._write_multi_eeprom (byte_list )
164
178
165
179
# TODO: add the ability to set an offset
166
180
def _write_multi_eeprom (self , byte_list ):
167
181
buffer_list = [_MCP4728_CH_A_MULTI_EEPROM ]
168
182
buffer_list += byte_list
169
183
170
184
buf = bytearray (buffer_list )
185
+ print ("buffers to eeprom:" )
186
+ self ._print_buffer (buf )
171
187
with self .i2c_device as i2c :
172
188
i2c .write (buf )
173
189
174
190
sleep (0.015 ) # the better to write you with
175
191
192
+ def _set_vrefs (self ):
193
+ base_values = 0b100000000
194
+ base_values |= (self .channel_a .vref << 3 )
195
+ base_values |= (self .channel_b .vref << 2 )
196
+ base_values |= (self .channel_c .vref << 1 )
197
+ base_values |= (self .channel_d .vref )
198
+ print ("VREP VALUES: %s" % (self ._lzb (base_values )))
199
+
200
+ with self .i2c_device as i2c :
201
+ i2c .write (bytearray (base_values ))
202
+
203
+ def _set_gains (self ):
204
+ # [S] 1 1 0 0 A2 A1 A0 0
205
+ # [A] 1 1 0 X GXA GXB GXC GXD [A] [P]
206
+ base_values = 0b110000000
207
+ base_values |= (self .channel_a .gain << 3 )
208
+ base_values |= (self .channel_b .gain << 2 )
209
+ base_values |= (self .channel_c .gain << 1 )
210
+ base_values |= (self .channel_d .gain )
211
+ print ("GAINZ VALUES: %s" % (self ._lzb (base_values )))
212
+
213
+ with self .i2c_device as i2c :
214
+ i2c .write (bytearray (base_values ))
215
+
216
+ def _set_value (self , channel ):
217
+
218
+ channel_bytes = self ._generate_bytes_with_flags (channel )
219
+
220
+ write_command_byte = 0b01000000 # 0 1 0 0 0 DAC1 DAC0 UDAC
221
+ write_command_byte |= (channel ._channel_index << 1 )
222
+
223
+ channel_bytes .insert (0 , write_command_byte )
224
+ # print("sending buffer:")
225
+ # self._print_buffer(channel_bytes)
226
+ with self .i2c_device as i2c :
227
+ i2c .write (bytearray (channel_bytes ))
228
+
229
+ def _generate_bytes_with_flags (self , channel ):
230
+ buf = bytearray (2 )
231
+ pack_into (">H" , buf , 0 , channel .raw_value )
232
+ # print("Value is ", channel.raw_value)
233
+ # print("packed into buffer:")
234
+ # self._print_buffer(buf)
235
+
236
+ buf [0 ] |= channel .vref << 7
237
+ buf [0 ] |= channel .gain << 4
238
+ # print("after setting of flags:")
239
+ # self._print_buffer(buf)
240
+ return buf
176
241
177
242
class Channel :
178
243
"""An instance of a single channel for a multi-channel DAC"""
179
- def __init__ (self , cache_page ):
244
+ def __init__ (self , dac_instance , cache_page , index ):
245
+ print ("Channel" , index , "cache_page:" , cache_page )
180
246
self ._vref = cache_page ['vref' ]
181
247
self ._gain = cache_page ['gain' ]
182
248
self ._raw_value = cache_page ['value' ]
249
+ self ._dac = dac_instance
250
+ self ._channel_index = index
183
251
184
252
@property
185
253
def normalized_value (self ):
186
254
"""The DAC value as a floating point number in the range 0.0 to 1.0."""
187
- return self ._raw_value / (2 ** 12 - 1 )
255
+ return self .raw_value / (2 ** 12 - 1 )
188
256
189
257
@normalized_value .setter
190
258
def normalized_value (self , value ):
191
259
if value < 0.0 or value > 1.0 :
192
260
raise AttributeError ("`normalized_value` must be between 0.0 and 1.0" )
193
261
194
- self ._raw_value = int (value * 4095.0 )
262
+ self .raw_value = int (value * 4095.0 )
195
263
196
264
@property
197
265
def value (self ):
@@ -205,7 +273,7 @@ def value(self, value):
205
273
raise AttributeError ("`value` must be a 16-bit integer between 0 and %s" % (2 ** 16 - 1 ))
206
274
207
275
# Scale from 16-bit to 12-bit value (quantization errors will occur!).
208
- self ._raw_value = value >> 4
276
+ self .raw_value = value >> 4
209
277
210
278
@property
211
279
def raw_value (self ):
@@ -217,6 +285,7 @@ def raw_value(self, value):
217
285
if value < 0 or value > (2 ** 12 - 1 ):
218
286
raise AttributeError ("`raw_value` must be a 12-bit integer between 0 and %s" % (2 ** 12 - 1 ))
219
287
self ._raw_value = value
288
+ self ._dac ._set_value (self )
220
289
221
290
@property
222
291
def gain (self ):
@@ -227,7 +296,9 @@ def gain(self):
227
296
def gain (self , value ):
228
297
if value < 1 or value > 2 :
229
298
raise AttributeError ("`gain` must be 1 or 2" )
230
- self ._vref = value
299
+ self ._gain = value - 1
300
+ # needs to call gain setter with all gains.
301
+ self ._dac ._set_gains ()
231
302
232
303
@property
233
304
def vref (self ):
@@ -239,3 +310,4 @@ def vref(self, value):
239
310
if value < 0 or value > 3 :
240
311
raise AttributeError ("`vref` must be a ``VREF``" )
241
312
self ._vref = value
313
+ self ._dac ._set_vrefs ()
0 commit comments