micropython control of SPI works (as far as I can tell)

This commit is contained in:
Peter McGoron 2024-03-12 10:01:46 +00:00
parent df9a7dcd8d
commit 3fac5747cc
6 changed files with 52 additions and 10 deletions

View File

@ -49,7 +49,12 @@ class Waveform(LiteXModule):
origin= 0x18, origin= 0x18,
bitwidth= 16, bitwidth= 16,
rw= True, rw= True,
) ),
"force_stop" : Register (
origin=0x1C,
bitwidth=1,
rw=True,
),
} }
width = 0x20 width = 0x20
@ -85,6 +90,7 @@ class Waveform(LiteXModule):
wform_size = Signal(counter_max_wid) wform_size = Signal(counter_max_wid)
timer = Signal(timer_wid) timer = Signal(timer_wid)
timer_spacing = Signal(timer_wid) timer_spacing = Signal(timer_wid)
force_stop = Signal()
self.sync += If(b.cyc & b.stb & ~b.ack, self.sync += If(b.cyc & b.stb & ~b.ack,
Case(b.adr, { Case(b.adr, {
@ -118,6 +124,11 @@ class Waveform(LiteXModule):
).Else( ).Else(
b.dat_r[0:timer_wid].eq(timer_spacing), b.dat_r[0:timer_wid].eq(timer_spacing),
), ),
0x1C: If(b.we,
force_stop.eq(b.dat_w[0]),
).Else(
b.dat_r[0].eq(force_stop),
),
# (W)A(V)EFO(RM) # (W)A(V)EFO(RM)
"default": b.dat_r.eq(0xAEF0AEF0), "default": b.dat_r.eq(0xAEF0AEF0),
} }
@ -136,6 +147,7 @@ class Waveform(LiteXModule):
i_clk = ClockSignal(), i_clk = ClockSignal(),
i_run = run, i_run = run,
i_force_stop = force_stop,
o_cntr = cntr, o_cntr = cntr,
i_do_loop = do_loop, i_do_loop = do_loop,
o_finished = finished, o_finished = finished,
@ -190,11 +202,11 @@ class SPIMaster(Module):
width = 0x20 width = 0x20
public_registers = { public_registers = {
# The first bit is the "finished" bit, when the master is # The first bit is the "ready" bit, when the master is
# armed and finished with a transmission.
# The second bit is the "ready" bit, when the master is
# not armed and ready to be armed. # not armed and ready to be armed.
"ready_or_finished": Register( # The second bit is the "finished" bit, when the master is
# armed and finished with a transmission.
"finished_or_ready": Register(
origin= 0, origin= 0,
bitwidth= 2, bitwidth= 2,
rw=False, rw=False,
@ -224,7 +236,7 @@ class SPIMaster(Module):
# Same as ready_or_finished, but halts until ready or finished # Same as ready_or_finished, but halts until ready or finished
# goes high. Dangerous, might cause cores to hang! # goes high. Dangerous, might cause cores to hang!
"wait_ready_or_finished": Register( "wait_finished_or_ready": Register(
origin=0x10, origin=0x10,
bitwidth=2, bitwidth=2,
rw= False, rw= False,
@ -333,7 +345,8 @@ class SPIMaster(Module):
p_PHASE = phase, p_PHASE = phase,
i_clk = ClockSignal(), i_clk = ClockSignal(),
i_rst_L = rst, # module_reset is active high
i_rst_L = ~rst,
i_miso = miso, i_miso = miso,
o_mosi = mosi, o_mosi = mosi,
o_sck_wire = sck, o_sck_wire = sck,

View File

@ -15,6 +15,7 @@ module waveform #(
/* Waveform output control */ /* Waveform output control */
input run, input run,
input force_stop,
output reg[COUNTER_MAX_WID-1:0] cntr, output reg[COUNTER_MAX_WID-1:0] cntr,
input do_loop, input do_loop,
output reg finished, output reg finished,
@ -57,7 +58,9 @@ localparam WAIT_PERIOD = 13;
reg [4-1:0] state = CHECK_START; reg [4-1:0] state = CHECK_START;
always @ (posedge clk) case (state) always @ (posedge clk) if (force_stop) begin
state <= CHECK_START;
end else case (state)
CHECK_START: if (run) begin CHECK_START: if (run) begin
cntr <= 0; cntr <= 0;
ready <= 0; ready <= 0;

View File

@ -15,6 +15,7 @@ module waveform_sim #(
/* Waveform output control */ /* Waveform output control */
input run, input run,
input force_stop,
output [COUNTER_MAX_WID-1:0] cntr, output [COUNTER_MAX_WID-1:0] cntr,
input do_loop, input do_loop,
output finished, output finished,
@ -52,6 +53,7 @@ waveform #(
) wf ( ) wf (
.clk(clk), .clk(clk),
.run(run), .run(run),
.force_stop(force_stop),
.cntr(cntr), .cntr(cntr),
.do_loop(do_loop), .do_loop(do_loop),
.finished(finished), .finished(finished),

View File

@ -274,7 +274,7 @@ class UpsilonSoC(SoCCore):
def f(csrs): def f(csrs):
wid = kwargs["spi_wid"] wid = kwargs["spi_wid"]
origin = csrs["memories"][name.lower() + "_pi"]['base'] origin = csrs["memories"][name.lower() + "_pi"]['base']
return f'{name} = SPI({wid}, {origin}, {spi.mmio(origin)})' return f'{name} = SPI({wid}, {name}_PI, {origin}, {spi.mmio(origin)})'
self.mmio_closures.append(f) self.mmio_closures.append(f)
return spi, pi return spi, pi

View File

@ -1,6 +1,26 @@
from registers import * from registers import *
class SPI(RegisterRegion): class SPI(RegisterRegion):
def __init__(self, spiwid, origin, **regs): def __init__(self, spiwid, spi_PI, origin, **regs):
self.spiwid = spiwid self.spiwid = spiwid
self.spi_PI = spi_PI
super().__init__(origin, **regs) super().__init__(origin, **regs)
def send(self, val, force=False):
if self.spi_PI.v != 0 and not force:
raise Exception("SPI is controlled by another master")
self.spi_PI.v = 0
self.arm.v = 0
while self.finished_or_ready.v == 0:
pass
self.to_slave.v = val
self.arm.v = 1
while self.finished_or_ready.v == 0:
pass
read_val = self.from_slave.v
self.arm.v = 0
return read_val

View File

@ -38,6 +38,10 @@ class Waveform(Immutable):
while self.regs.finished_or_ready == 0: while self.regs.finished_or_ready == 0:
pass pass
def force_stop(self):
self.regs.force_stop = 1
selff.regs.force_stop = 0
def dump(self): def dump(self):
""" Dump contents of control registers. """ """ Dump contents of control registers. """
return self.regs.dump() return self.regs.dump()