74
74
jmp top
75
75
"""
76
76
77
+ _PROGRAM1 = """
78
+ .program piopixl8
79
+ top:
80
+ mov pins, null ; always-low part (last cycle is the 'pull ifempty' after wrap)
81
+ pull block ; wait for fresh data
82
+ out y, 32 ; get count of NeoPixel bits
83
+
84
+ ; NeoPixels are 800khz bit streams. We are choosing zeros as <312ns hi, 936 lo>
85
+ ; and ones as <700 ns hi, 546 ns lo> and a clock of 16*800kHz, so the always-high
86
+ ; time is 4 cycles, the variable time is 5 cycles, and the always-low time is 7 cycles
87
+ bitloop:
88
+ pull ifempty [1] ; don't start outputting HIGH unless data is available (always-low part)
89
+ mov pins, ~ null [3] ; always-high part
90
+ out pins, 1 [4] ; variable part
91
+ mov pins, null ; always-low part (last cycle is the 'pull ifempty' after wrap)
92
+
93
+ jmp y--, bitloop ; always-low part
94
+
95
+ ; A minimum delay is required so that the next pixel starts refreshing the front of the strands
96
+ pull block
97
+ out y, 32
98
+
99
+ wait_reset:
100
+ jmp y--, wait_reset
101
+ jmp top
102
+ """
103
+
77
104
# Pixel color order constants
78
105
RGB = "RGB"
79
106
"""Red Green Blue"""
@@ -150,19 +177,31 @@ def __init__(
150
177
n , brightness = brightness , byteorder = pixel_order , auto_write = auto_write
151
178
)
152
179
153
- data_len = bpp * n * 8 // num_strands
180
+ if num_strands == 1 :
181
+ data_len = bpp * n
182
+ pack = ">L"
183
+ osr = False
184
+ n = (8 * data_len ) - 1
185
+ else :
186
+ data_len = bpp * n * 8 // num_strands
187
+ pack = "<L"
188
+ osr = True
189
+ n = data_len - 1
154
190
padding_count = - data_len % 4
155
191
192
+ self ._num_strands = num_strands
156
193
self ._data = bytearray (8 + data_len + padding_count )
157
194
self ._data32 = memoryview (self ._data ).cast ("L" )
158
- self ._transposed = memoryview (self ._data )[4 : 4 + data_len ]
159
- self ._data [:4 ] = struct .pack ("<L" , data_len - 1 )
160
- self ._data [- 4 :] = struct .pack ("<L" , 3840 * 2 )
195
+ self ._pixels = memoryview (self ._data )[4 : 4 + data_len ]
196
+ self ._data [:4 ] = struct .pack (pack , n )
197
+ self ._data [- 4 :] = struct .pack (pack , 3840 * 2 )
161
198
162
199
self ._num_strands = num_strands
163
200
164
201
if num_strands == 8 :
165
202
assembled = adafruit_pioasm .assemble (_PROGRAM8 )
203
+ elif num_strands == 1 :
204
+ assembled = adafruit_pioasm .assemble (_PROGRAM1 )
166
205
else :
167
206
program = _PROGRAMN .format (num_strands , 8 - num_strands )
168
207
assembled = adafruit_pioasm .assemble (program )
@@ -174,7 +213,7 @@ def __init__(
174
213
out_pin_count = num_strands ,
175
214
first_set_pin = data0 ,
176
215
auto_pull = False ,
177
- out_shift_right = True ,
216
+ out_shift_right = osr ,
178
217
)
179
218
180
219
def deinit (self ):
@@ -209,5 +248,9 @@ def num_strands(self):
209
248
def _transmit (self , buffer ):
210
249
while self ._sm .pending :
211
250
pass
212
- bitops .bit_transpose (buffer , self ._transposed , self ._num_strands )
213
- self ._sm .background_write (self ._data32 )
251
+ if self .num_strands == 1 :
252
+ self ._pixels [:] = buffer
253
+ self ._sm .background_write (self ._data32 , swap = True )
254
+ else :
255
+ bitops .bit_transpose (buffer , self ._pixels , self ._num_strands )
256
+ self ._sm .background_write (self ._data32 )
0 commit comments