49
49
from time import sleep
50
50
import adafruit_bus_device .i2c_device as i2c_device
51
51
from adafruit_register .i2c_struct import UnaryStruct
52
+ import traceback
52
53
53
54
_MCP4728_DEFAULT_ADDRESS = 0x60
54
55
55
- """
56
- # DAC1, DAC0 DAC Channel Selection bits:
57
- # 00 = Channel A
58
- # 01 = Channel B
59
- # 10 = Channel C
60
- # 11 = Channel D
61
-
62
- 0 = slave addr(auto)
63
- 0 1 0 0 0 DAC1 DAC0 UDAC[A]
64
- 01000 + 00 + UDAC =
65
- 0b01000000 = 0x40 (+2 for each successive)
66
- VREF PD1 PD0 Gx D11 D10 D9 D8 [A]
67
- D7 D6 D5 D4 D3 D2 D1 D0 [A]
68
-
69
- 0 1 0 0 0 Multi-Write for DAC
70
- 0 1 0 1 0 Sequential Write for DAC Input Registers and EEPROM
71
- 0 1 0 1 1 Single Write for DAC Input Register and EEPROM
72
-
73
- 1 0 0 0 0 Write Reference (VREF) selection bits to Input Registers
74
- 1 1 0 0 0 Write Gain selection bits to Input Registers
75
- 1 0 1 0 0 Write Power-Down bits to Input Registers
76
- """
77
-
78
56
_MCP4728_CH_A_MULTI_IB = 0x40
79
57
_MCP4728_CH_B_MULTI_IB = 0x42
80
58
_MCP4728_CH_C_MULTI_IB = 0x44
87
65
88
66
_MCP4728_CH_A_MULTI_EEPROM = 0x50
89
67
90
- #TODO: REMOVE THIS
91
- #pylint: disable=unused-variable,no-self-use,invalid-name,too-few-public-methods
68
+ class CV :
69
+ """struct helper"""
70
+
71
+ @classmethod
72
+ def add_values (cls , value_tuples ):
73
+ "creates CV entires"
74
+ cls .string = {}
75
+ cls .lsb = {}
76
+
77
+ for value_tuple in value_tuples :
78
+ name , value , string , lsb = value_tuple
79
+ setattr (cls , name , value )
80
+ cls .string [value ] = string
81
+ cls .lsb [value ] = lsb
82
+
83
+ @classmethod
84
+ def is_valid (cls , value ):
85
+ "Returns true if the given value is a member of the CV"
86
+ return value in cls .string
87
+
88
+ class Vref (CV ):
89
+ """Options for ``vref``"""
90
+ pass #pylint: disable=unnecessary-pass
91
+
92
+ Vref .add_values ((
93
+ ('VDD' , 0 , "VDD" , None ),
94
+ ('INTERNAL' , 1 , "Internal 2.048V" , None ),
95
+ ))
96
+
92
97
class MCP4728 :
93
98
"""Helper library for the Microchip MCP4728 I2C 12-bit Quad DAC.
94
99
@@ -111,16 +116,13 @@ class MCP4728:
111
116
def __init__ (self , i2c_bus , address = _MCP4728_DEFAULT_ADDRESS ):
112
117
113
118
self .i2c_device = i2c_device .I2CDevice (i2c_bus , address )
114
- self ._create_channels ()
115
-
116
- def _chunk (self , l , n ):
117
- # For item i in a range that is a length of l,
118
- for i in range (0 , len (l ), n ):
119
- # Create an index range for l of n items:
120
- yield l [i :i + n ]
119
+
120
+ raw_registers = self ._read_registers ()
121
121
122
- def _lzb (self , byte_val ): # leading zero bin
123
- return format (byte_val , '#010b' )
122
+ self .channel_a = Channel (self , self ._cache_page (* raw_registers [0 ]), 0 )
123
+ self .channel_b = Channel (self , self ._cache_page (* raw_registers [1 ]), 1 )
124
+ self .channel_c = Channel (self , self ._cache_page (* raw_registers [2 ]), 2 )
125
+ self .channel_d = Channel (self , self ._cache_page (* raw_registers [3 ]), 3 )
124
126
125
127
def _get_flags (self , high_byte ):
126
128
vref = (high_byte & 1 << 7 ) > 0
@@ -131,14 +133,6 @@ def _get_flags(self, high_byte):
131
133
def _cache_page (self , value , vref , gain , pd ):
132
134
return {"value" : value , "vref" : vref , "gain" : gain , "pd" : pd }
133
135
134
- def _create_channels (self ):
135
- raw_registers = self ._read_registers ()
136
-
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 )
141
-
142
136
def _read_registers (self ):
143
137
buf = bytearray (24 )
144
138
@@ -182,36 +176,51 @@ def _write_multi_eeprom(self, byte_list):
182
176
buffer_list += byte_list
183
177
184
178
buf = bytearray (buffer_list )
185
- print ("buffers to eeprom:" )
186
179
self ._print_buffer (buf )
187
180
with self .i2c_device as i2c :
188
181
i2c .write (buf )
189
182
190
183
sleep (0.015 ) # the better to write you with
191
184
192
- def _set_vrefs (self ):
193
- base_values = 0b100000000
185
+ def _sync_vrefs (self ):
186
+ base_values = 0b10000000
194
187
base_values |= (self .channel_a .vref << 3 )
195
188
base_values |= (self .channel_b .vref << 2 )
196
189
base_values |= (self .channel_c .vref << 1 )
197
190
base_values |= (self .channel_d .vref )
198
- print ("VREP VALUES: %s" % (self ._lzb (base_values )))
199
-
191
+
192
+ print ("vref values:" )
193
+ print (base_values )
194
+ print (self ._lzb (base_values ))
195
+
196
+ buf = bytearray (1 )
197
+ pack_into (">B" , buf , 0 , base_values )
198
+ print ("buf bytes:" )
199
+ self ._print_buffer (buf )
200
200
with self .i2c_device as i2c :
201
- i2c .write (bytearray ( base_values ) )
201
+ i2c .write (buf )
202
202
203
- def _set_gains (self ):
203
+ def _sync_gains (self ):
204
204
# [S] 1 1 0 0 A2 A1 A0 0
205
205
# [A] 1 1 0 X GXA GXB GXC GXD [A] [P]
206
- base_values = 0b110000000
206
+ base_values = 0b11000000
207
207
base_values |= (self .channel_a .gain << 3 )
208
208
base_values |= (self .channel_b .gain << 2 )
209
209
base_values |= (self .channel_c .gain << 1 )
210
210
base_values |= (self .channel_d .gain )
211
- print ("GAINZ VALUES: %s" % (self ._lzb (base_values )))
211
+
212
+
213
+ print ("gain values:" )
214
+ print (base_values )
215
+ print (self ._lzb (base_values ))
216
+
217
+ buf = bytearray (1 )
218
+ pack_into (">B" , buf , 0 , base_values )
219
+ print ("buf bytes:" )
220
+ self ._print_buffer (buf )
212
221
213
222
with self .i2c_device as i2c :
214
- i2c .write (bytearray ( base_values ) )
223
+ i2c .write (buf )
215
224
216
225
def _set_value (self , channel ):
217
226
@@ -221,28 +230,33 @@ def _set_value(self, channel):
221
230
write_command_byte |= (channel ._channel_index << 1 )
222
231
223
232
channel_bytes .insert (0 , write_command_byte )
224
- # print("sending buffer:")
225
- # self._print_buffer(channel_bytes)
233
+
226
234
with self .i2c_device as i2c :
227
235
i2c .write (bytearray (channel_bytes ))
228
236
229
237
def _generate_bytes_with_flags (self , channel ):
230
238
buf = bytearray (2 )
231
239
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
240
236
241
buf [0 ] |= channel .vref << 7
237
242
buf [0 ] |= channel .gain << 4
238
- # print("after setting of flags:")
239
- # self._print_buffer(buf)
243
+
240
244
return buf
241
245
246
+ def _chunk (self , l , n ):
247
+ # For item i in a range that is a length of l,
248
+ for i in range (0 , len (l ), n ):
249
+ # Create an index range for l of n items:
250
+ yield l [i :i + n ]
251
+
252
+ def _lzb (self , byte_val ): # leading zero bin
253
+ return format (byte_val , '#010b' )
254
+ def _bt (self ):
255
+ for line in traceback .format_stack ():
256
+ print (line .strip ())
242
257
class Channel :
243
258
"""An instance of a single channel for a multi-channel DAC"""
244
259
def __init__ (self , dac_instance , cache_page , index ):
245
- print ("Channel" , index , "cache_page:" , cache_page )
246
260
self ._vref = cache_page ['vref' ]
247
261
self ._gain = cache_page ['gain' ]
248
262
self ._raw_value = cache_page ['value' ]
@@ -289,16 +303,15 @@ def raw_value(self, value):
289
303
290
304
@property
291
305
def gain (self ):
292
- """Sets the gain of the channel. Must be 1 or 2"""
306
+ """Sets the gain of the channel if the Vref for the channel is ``Vref.INTERNAL``. *The gain setting has no effect if the Vref for the channel is `Vref.VDD`*. With gain set to 1, the output voltage goes from 0v to 2.048V. If a channe's gain is set to 2, the voltage goes from 0v to 4.096V. `gain` Must be 1 or 2"""
293
307
return self ._gain
294
308
295
309
@gain .setter
296
310
def gain (self , value ):
297
- if value < 1 or value > 2 :
311
+ if value != 1 and value != 2 :
298
312
raise AttributeError ("`gain` must be 1 or 2" )
299
313
self ._gain = value - 1
300
- # needs to call gain setter with all gains.
301
- self ._dac ._set_gains ()
314
+ self ._dac ._sync_gains ()
302
315
303
316
@property
304
317
def vref (self ):
@@ -307,7 +320,7 @@ def vref(self):
307
320
308
321
@vref .setter
309
322
def vref (self , value ):
310
- if value < 0 or value > 3 :
311
- raise AttributeError ("`vref` must be a ``VREF` `" )
323
+ if not Vref . is_valid ( value ) :
324
+ raise AttributeError ("range must be a `Vref `" )
312
325
self ._vref = value
313
- self ._dac ._set_vrefs ()
326
+ self ._dac ._sync_vrefs ()
0 commit comments