Array access testing ...

master
kaqu 2 years ago
parent 925e68b824
commit 18bfecde54
  1. 64
      neopixelar.py
  2. 67
      neopixelengine.py
  3. 84924
      npe.vcd
  4. 76
      remotetest.py

@ -333,43 +333,43 @@ class BaseSoC(SoCCore):
self.submodules.npe = NeoPixelEngine()
self.add_csr("npe")
sw_gpio = Signal(24)
self.submodules.npe_data = GPIOOut(sw_gpio)
self.comb += self.npe.b24GRBArray[0].eq(sw_gpio) # 1st LED G(reen) Bit4
self.add_csr("npe_data")
# Working def.
#sw_gpio = Signal(24)
#self.submodules.npe_data = GPIOOut(sw_gpio)
#self.comb += self.npe.b24GRBArray[0].eq(sw_gpio) # 1st LED G(reen) Bit4
#self.add_csr("npe_data")
# Inputs 1st
#self.comb += self.npe.b24GRBArray[0].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[1].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[2].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[3].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[4].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[5].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[6].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[7].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[8].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[9].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[10].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[11].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[12].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[13].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[14].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[15].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[16].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[17].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[18].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[19].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[20].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[21].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[22].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[23].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[24].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[25].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[26].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[27].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[1].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[2].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[3].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[4].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[5].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[6].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[7].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[8].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[9].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[10].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[11].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[12].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[13].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[14].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[15].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[16].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[17].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[18].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[19].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[20].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[21].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[22].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[23].eq(0x000055) # 3rd: B
#self.comb += self.npe.b24Data.fields.fields[24].eq(0x330000) # 1st: G
#self.comb += self.npe.b24Data.fields.fields[25].eq(0x004400) # 2nd: R
#self.comb += self.npe.b24Data.fields.fields[26].eq(0x000055) # 3rd: B
self.comb += self.npe.b8Len.eq(27) # 27 24-bit 'words'
self.comb += self.npe.bStart.eq(True) # Start pulse
self.comb += self.npe.bEnable.eq(True) # Free running
# Outputs 2nd
# Do output on J4
for i in range(42,56):

@ -3,7 +3,9 @@
#
# neopixelengine.py
#
# NeoPixel protocol engine (wanna-be)
# NeoPixel protocol engine (wanna-be), see:
# http://www.adafruit.com/datasheets/WS2812.pdf
# https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
#
# History:
# --------
@ -15,15 +17,35 @@
#
from migen import *
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage, CSRField
class NeoPixelEngine(Module, AutoCSR):
def __init__(self):
self.output = CSRStorage(32,reset_less=True,write_from_dev=True)
"""NeoPixelEngine class provides the protocol logic to drive NeoPixel LED strips
self.bStart = Signal() # External input: Start pulse
Inputs:
b24GRBArray[256] 24-bit data entries (one per NeoPixel)
b8Len length of actual 24-bit data entries (i.e. # of NeoPixels)
bEnable to enable running (after data preparation)
Output:
bDataPin NeoPixel 'Din' pin output
"""
def __init__(self):
#self.b24GRBArray = Array(Signal(24) for word24 in range(255)) # External input: 24-bit data Array
n_words = 27
self.b24Data = CSRStorage(n_words*24, reset_less=True, fields=
#Array(CSRField("_{:03d}".format(word24), size=24, description="G/R/B entry #{}".format(word24)) for word24 in range(n_words)),
Array(CSRField("_{:03d}".format(word24), size=24, description="G/R/B entry #{}".format(word24)) for word24 in range(n_words-1,-1,-1)),
#[
# CSRField("_0", size=24, description="24-bit entry #0"),
# CSRField("_1", size=24, description="24-bit entry #1"),
# CSRField("_2", size=24, description="24-bit entry #2"),
# CSRField("_3", size=24, description="24-bit entry #3"),
#],
description="24-bit data entry table"
)
self.b8Len = Signal(8) # External input: No. of 24-bit data to transfer (unsigned)
self.b24GRBArray = Array(Signal(24) for word24 in range(255)) # External input: 24-bit data Array
self.bEnable = Signal() # External input: Enable free run signal (start & abort)
self.b8Offset = Signal(8) # Local: Array rover
self.b24GRB = Signal(24) # Local: Current 24-bit data to send
@ -32,17 +54,15 @@ class NeoPixelEngine(Module, AutoCSR):
self.bDataPin = Signal() # Output: To be wired to data pin ...
###
self.comb += self.output.re.eq(0x12345678) # Assign a defined value to memory
###
fsm = FSM(reset_state="IDLE") # FSM starts idling ...
self.submodules += fsm
self.submodules += fsm
fsm.act("IDLE",
If((self.bStart==True) and (self.b8Len > 0),
NextValue(self.bStart, False),
If((self.bEnable==True) and (self.b8Len > 0),
NextValue(self.b8Offset, 0), # Start @ 1st 24-bit data
NextValue(self.b24GRB, self.b24GRBArray[0]), # ... but load 1st right away!
#NextValue(self.b24GRB, self.b24GRBArray[0]), # ... but load 1st right away!
NextValue(self.b24GRB, self.b24Data.fields.fields[0]), # ... but load 1st right away!
NextValue(self.b5Count24,0), # Bit count 0..23
NextState("PREPAREBIT")
)
@ -105,8 +125,12 @@ class NeoPixelEngine(Module, AutoCSR):
)
)
fsm.act("NEXTWORD",
If(self.b8Offset < self.b8Len, # Still more words to come?
NextValue(self.b24GRB, self.b24GRBArray[self.b8Offset]), # Load in advance
#If(self.bEnable==False, # Exit requested?
# NextState("RST") # Yap!
#).El
If((self.b8Offset < self.b8Len) & (self.bEnable==True), # Still more words to come (& no exit request)?
#NextValue(self.b24GRB, self.b24GRBArray[self.b8Offset]), # Load in advance
NextValue(self.b24GRB, self.b24Data.fields.fields[self.b8Offset]),
NextState("PREPAREBIT")
).Else(
NextValue(self.b12PulseLen, 4095), # >50µs required (3000 not ok!)
@ -123,15 +147,18 @@ class NeoPixelEngine(Module, AutoCSR):
def npe_testbench(npe):
print("----- npe testbench -----")
yield npe.b24GRBArray[0].eq(0x123456)
#yield npe.b24GRBArray[0].eq(0x123456)
yield npe.b24Data.fields.fields[0].eq(0x123456)
yield
yield npe.b24GRBArray[1].eq(0x223344)
#yield npe.b24GRBArray[1].eq(0x223344)
yield npe.b24Data.fields.fields[1].eq(0x223344)
yield
yield npe.b24GRBArray[2].eq(0x654321)
#yield npe.b24GRBArray[2].eq(0x654321)
yield npe.b24Data.fields.fields[2].eq(0x654321)
yield
yield npe.b8Len.eq(3)
yield
yield npe.bStart.eq(True)
yield npe.bEnable.eq(True)
yield
#
for i in range(10000): # Send the whole data & restart ...
@ -139,7 +166,7 @@ def npe_testbench(npe):
print((yield npe.bDataPin)) # Actual pin to move
yield
if i == 5000:
yield npe.bStart.eq(True) # Enable quickest restart ...
yield npe.bEnable.eq(True) # Enable quickest restart ...
yield
if __name__ == "__main__":

84924
npe.vcd

File diff suppressed because it is too large Load Diff

@ -20,9 +20,81 @@ def test(csr_csv):
print("NeoPixel #0 on & off test: ")
for i in range(10):
print(".",end="")
wb.regs.npe_data_out.write(0x100000)
#Added manually: ~/fpga/litex/litex/litex/tools/remote/csr_builder.py
# def writearray(self, value): #21.09.20/KQ
# if self.mode not in ["rw", "wo"]:
# raise KeyError(self.name + "register not writable")
# self.writefn(self.addr, value)
#wb.regs.npe_data_out.write(0x100000)
wb.regs.npe_b24Data.writearray(
[
#00,00,15,
#0,19,0,
#20,0,0, #25
#00,00,15,
#0,19,0,
#20,0,0, #22
#00,00,15,
#0,19,0,
#20,0,0, #19
#00,00,15,
#0,19,0,
#20,0,0, #16
#00,00,15,
#0,19,0,
#20,0,0, #13
#00,00,15,
#0,19,0,
#20,0,0, #10
#00,00,15,
#0,19,0,
#20,0,0, #7
#00,00,15,
#0,19,0,
20,0,0, #4
00,00,15,
0,19,0,
20,0,0 #1
]
) # Width 27
#wb.regs.npe_b24Datawrite(0x001000)
#wb.regs.npe_b24Data.write(0x000010)
time.sleep(0.5)
wb.regs.npe_data_out.write(0)
#wb.regs.npe_data_out.write(0)
wb.regs.npe_b24Data.writearray(
[
#0,0,0,
#0,0,0,
#0,0,0, #25
#0,0,0,
#0,0,0,
#0,0,0, #22
#0,0,0,
#0,0,0,
#0,0,0, #19
#0,0,0,
#0,0,0,
#0,0,0, #16
#0,0,0,
#0,0,0,
#0,0,0, #13
#0,0,0,
#0,0,0,
#0,0,0, #10
#0,0,0,
#0,0,0,
#0,0,0, #7
#0,0,0,
#0,0,0,
0,0,0, #4
0,0,0,
0,0,0,
0,0,0 #1
]
)
#wb.regs.npe_b24Data_1.write(0)
#wb.regs.npe_b24Data_2.write(0)
time.sleep(0.5)
wb.close() # Close wishbone access

Loading…
Cancel
Save