groovylight/groovylight/hub75.py

122 lines
3.8 KiB
Python

# r0 g0 b0 gnd r1 g1 b1 e a b c d clk stb oe gnd
from litex.build.generic_platform import Signal, Subsignal, Pins
from litex.build.io import FSM, Module
from litex.gen import If, NextState, NextValue
from migen import Cat
def make_hub75_iodevice(index, basename):
b = basename
signals = ("hub75_iodev", index,
Subsignal("r0", Pins(f"{b}:0")),
Subsignal("g0", Pins(f"{b}:1")),
Subsignal("b0", Pins(f"{b}:2")),
Subsignal("r1", Pins(f"{b}:4")),
Subsignal("g1", Pins(f"{b}:5")),
Subsignal("b1", Pins(f"{b}:6")),
Subsignal("addr", Pins(f"{b}:8 {b}:9 {b}:10 {b}:11 {b}:7")),
Subsignal("clk", Pins(f"{b}:12")),
Subsignal("stb", Pins(f"{b}:13")),
Subsignal("oe", Pins(f"{b}:14")),
)
return [signals]
class Hub75Driver(Module):
def __init__(self, base_freq=60e6, linedepth=128):
if base_freq // 2 > 30e6:
raise RuntimeError("hi")
self.phase = Signal() # divider/counter
self.addr = Signal(5)
self.latch = Signal()
self.output_en = Signal()
self.rgb = Signal(6, reset=0b111010)
# clk-en acts as a gate.
clock_en = Signal()
self.clock_out = Signal()
self.fsm = fsm = FSM()
self.submodules += self.fsm
bcm_value = Signal(3)
counter = Signal(32)
fsm.act("WRITEROW",
self.output_en.eq(1),
If(counter < 256,
self.clock_out.eq(counter[0]),
NextValue(counter, counter + 1),
If(counter[0], NextValue(self.rgb, self.rgb + 3)),
).Else(
NextValue(counter, 0),
NextState("EXPOSE"),
),
)
fsm.act("EXPOSE",
self.output_en.eq(0),
If(counter < (1000 << bcm_value),
NextValue(counter, counter + 1),
).Else(
NextValue(counter, 0),
NextState("LATCH"),
),
)
fsm.act("LATCH",
self.latch.eq(1),
NextValue(counter, 0),
If(bcm_value == 7,
NextValue(bcm_value, 0),
NextValue(self.addr, self.addr + 1),
).Else(NextValue(bcm_value, 1)),
NextState("WRITEROW"),
)
# fsm.act("ready",
# NextValue(self.output_en, 1),
# NextValue(self.pixnum, linedepth - 1),
# NextValue(self.latch, 0),
# If(self.phase == 1,
# NextValue(self.addr, self.addr + 1),
# NextValue(clock_en, 1),
# NextState("transmit"),
# ),
# # If((self.state_count == 7), NextValue(clock_en, ~clock_en)),
# )
# fsm.act("transmit",
# If(self.phase == 1,
# NextValue(self.pixnum, self.pixnum - 1),
# If(self.pixnum == 0,
# NextState("latch_delay"),
# )
# )
# )
# fsm.act("latch_delay",
# NextValue(clock_en, 0),
# If(self.phase == 1,
# NextState("latchout")
# )
# )
# fsm.act("latchout",
# If(self.phase == 1,
# NextValue(self.latch, 1),
# NextValue(counter, 0),
# NextState("done")
# )
# )
# fsm.act("done",
# NextValue(self.output_en, 0),
# NextValue(self.latch, 0),
# NextValue(counter, counter + 1),
# If(counter == 255, NextState("ready"))
# )
#