26
26
CircuitPython module for the TLC5947 12-bit 24 channel LED PWM driver. See
27
27
examples/simpletest.py for a demo of the usage.
28
28
29
- * Author(s): Tony DiCola
29
+ * Author(s): Tony DiCola, Walter Haschka
30
30
31
31
Implementation Notes
32
32
--------------------
50
50
# access is by design for the internal class.
51
51
#pylint: disable=protected-access
52
52
53
+ _CHANNELS = 24
54
+ _STOREBYTES = _CHANNELS + _CHANNELS // 2
53
55
54
56
class TLC5947 :
55
57
"""TLC5947 12-bit 24 channel LED PWM driver. Create an instance of this by
@@ -66,6 +68,16 @@ class TLC5947:
66
68
single one is updated. If you set to false to disable then
67
69
you MUST call write after every channel update or when you
68
70
deem necessary to update the chip state.
71
+
72
+ :param num_drivers: This is an integer that defaults to 1. It stands for the
73
+ number of chained LED driver boards (DOUT of one board has
74
+ to be connected to DIN of the next). For each board added,
75
+ 36 bytes of RAM memory will be taken. The channel numbers
76
+ on the driver directly connected to the controller are 0 to
77
+ 23, and for each driver add 24 to the port number printed.
78
+ The more drivers are chained, the more viable it is to set
79
+ auto_write=false, and call write explicitly after updating
80
+ all the channels.
69
81
"""
70
82
71
83
class PWMOut :
@@ -115,14 +127,15 @@ def frequency(self, val):
115
127
#pylint: enable=no-self-use,unused-argument
116
128
117
129
118
- def __init__ (self , spi , latch , * , auto_write = True ):
130
+ def __init__ (self , spi , latch , * , auto_write = True , num_drivers = 1 ):
119
131
self ._spi = spi
120
132
self ._latch = latch
121
133
self ._latch .switch_to_output (value = False )
122
- # This device is just a big 36 byte long shift register. There's no
123
- # fancy protocol or other commands to send, just write out all 288
134
+ # This device is just a big 36*n byte long shift register. There's no
135
+ # fancy protocol or other commands to send, just write out all 288*n
124
136
# bits every time the state is updated.
125
- self ._shift_reg = bytearray (36 )
137
+ self ._n = num_drivers
138
+ self ._shift_reg = bytearray (_STOREBYTES * self ._n )
126
139
# Save auto_write state (i.e. push out shift register values on
127
140
# any channel value change).
128
141
self .auto_write = auto_write
@@ -141,7 +154,7 @@ def write(self):
141
154
# First ensure latch is low.
142
155
self ._latch .value = False
143
156
# Write out the bits.
144
- self ._spi .write (self ._shift_reg , start = 0 , end = 37 )
157
+ self ._spi .write (self ._shift_reg , start = 0 , end = _STOREBYTES * self . _n + 1 )
145
158
# Then toggle latch high and low to set the value.
146
159
self ._latch .value = True
147
160
self ._latch .value = False
@@ -152,10 +165,10 @@ def write(self):
152
165
def _get_gs_value (self , channel ):
153
166
# pylint: disable=no-else-return
154
167
# Disable should be removed when refactor can be tested
155
- assert 0 <= channel <= 23
168
+ assert 0 <= channel < _CHANNELS * self . _n
156
169
# Invert channel position as the last channel needs to be written first.
157
170
# I.e. is in the first position of the shift registr.
158
- channel = 23 - channel
171
+ channel = _CHANNELS * self . _n - 1 - channel
159
172
# Calculate exact bit position within the shift register.
160
173
bit_offset = channel * 12
161
174
# Now calculate the byte that this position falls within and any offset
@@ -177,11 +190,11 @@ def _get_gs_value(self, channel):
177
190
raise RuntimeError ('Unsupported bit offset!' )
178
191
179
192
def _set_gs_value (self , channel , val ):
180
- assert 0 <= channel <= 23
193
+ assert 0 <= channel < _CHANNELS * self . _n
181
194
assert 0 <= val <= 4095
182
195
# Invert channel position as the last channel needs to be written first.
183
196
# I.e. is in the first position of the shift registr.
184
- channel = 23 - channel
197
+ channel = _CHANNELS * self . _n - 1 - channel
185
198
# Calculate exact bit position within the shift register.
186
199
bit_offset = channel * 12
187
200
# Now calculate the byte that this position falls within and any offset
@@ -226,20 +239,22 @@ def create_pwm_out(self, channel):
226
239
# like when using the PWMOut mock class).
227
240
def __len__ (self ):
228
241
"""Retrieve the total number of PWM channels available."""
229
- return 24 # Always 24 channels on the chip .
242
+ return _CHANNELS * self . _n # number channels times number chips .
230
243
231
244
def __getitem__ (self , key ):
232
- """Retrieve the 12-bit PWM value for the specified channel (0-23).
245
+ """Retrieve the 12-bit PWM value for the specified channel (0-max).
246
+ max depends on the number of boards.
233
247
"""
234
- assert 0 <= key <= 23
248
+ assert 0 <= key < _CHANNELS * self . _n
235
249
return self ._get_gs_value (key )
236
250
237
251
def __setitem__ (self , key , val ):
238
- """Set the 12-bit PWM value (0-4095) for the specified channel (0-23).
252
+ """Set the 12-bit PWM value (0-4095) for the specified channel (0-max).
253
+ max depends on the number of boards.
239
254
If auto_write is enabled (the default) then the chip PWM state will
240
255
immediately be updated too, otherwise you must call write to update
241
256
the chip with the new PWM state.
242
257
"""
243
- assert 0 <= key <= 23
258
+ assert 0 <= key < _CHANNELS * self . _n
244
259
assert 0 <= val <= 4095
245
260
self ._set_gs_value (key , val )
0 commit comments