Skip to content

Commit c86c6c0

Browse files
committed
Support 1-pixel strips
.. this calls for a different memory layout to save memory size in the 'background' buffer
1 parent 377e59b commit c86c6c0

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

adafruit_neopxl8.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,33 @@
7474
jmp top
7575
"""
7676

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+
77104
# Pixel color order constants
78105
RGB = "RGB"
79106
"""Red Green Blue"""
@@ -150,19 +177,31 @@ def __init__(
150177
n, brightness=brightness, byteorder=pixel_order, auto_write=auto_write
151178
)
152179

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
154190
padding_count = -data_len % 4
155191

192+
self._num_strands = num_strands
156193
self._data = bytearray(8 + data_len + padding_count)
157194
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)
161198

162199
self._num_strands = num_strands
163200

164201
if num_strands == 8:
165202
assembled = adafruit_pioasm.assemble(_PROGRAM8)
203+
elif num_strands == 1:
204+
assembled = adafruit_pioasm.assemble(_PROGRAM1)
166205
else:
167206
program = _PROGRAMN.format(num_strands, 8 - num_strands)
168207
assembled = adafruit_pioasm.assemble(program)
@@ -174,7 +213,7 @@ def __init__(
174213
out_pin_count=num_strands,
175214
first_set_pin=data0,
176215
auto_pull=False,
177-
out_shift_right=True,
216+
out_shift_right=osr,
178217
)
179218

180219
def deinit(self):
@@ -209,5 +248,9 @@ def num_strands(self):
209248
def _transmit(self, buffer):
210249
while self._sm.pending:
211250
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

Comments
 (0)