Skip to content

Commit

Permalink
added spi 1-bit mode, code from litex
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkucera committed Jul 29, 2018
1 parent 1325aff commit dae037c
Showing 1 changed file with 86 additions and 1 deletion.
87 changes: 86 additions & 1 deletion misoc/cores/spi_flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def _format_cmd(cmd, spi_width):
return c


class SpiFlash(Module, AutoCSR):
class SpiFlashDualQuad(Module, AutoCSR):
def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
"""
Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.
Expand Down Expand Up @@ -147,3 +147,88 @@ def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
t += dt

self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)

class SpiFlashSingle(Module, AutoCSR):
def __init__(self, pads, dummy=15, div=2):
"""
Simple SPI flash.
Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0).
"""
self.bus = bus = wishbone.Interface()

# # #

if hasattr(pads, "wp"):
self.comb += pads.wp.eq(1)

if hasattr(pads, "hold"):
self.comb += pads.hold.eq(1)

cs_n = Signal(reset=1)
clk = Signal()
wbone_width = len(bus.dat_r)

read_cmd = _FAST_READ
cmd_width = 8
addr_width = 24

sr = Signal(max(cmd_width, addr_width, wbone_width))
self.comb += bus.dat_r.eq(sr)

self.comb += [
pads.clk.eq(clk),
pads.cs_n.eq(cs_n),
pads.mosi.eq(sr[-1:])
]

if div < 2:
raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
else:
i = Signal(max=div)
miso = Signal()
self.sync += [
If(i == div//2 - 1,
clk.eq(1),
miso.eq(pads.miso),
),
If(i == div - 1,
i.eq(0),
clk.eq(0),
sr.eq(Cat(miso, sr[:-1]))
).Else(
i.eq(i + 1),
),
]

# spi is byte-addressed, prefix by zeros
z = Replicate(0, log2_int(wbone_width//8))

seq = [
(cmd_width*div,
[cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
(addr_width*div,
[sr[-addr_width:].eq(Cat(z, bus.adr))]),
((dummy + wbone_width)*div,
[]),
(1,
[bus.ack.eq(1), cs_n.eq(1)]),
(div, # tSHSL!
[bus.ack.eq(0)]),
(0,
[]),
]

# accumulate timeline deltas
t, tseq = 0, []
for dt, a in seq:
tseq.append((t, a))
t += dt

self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)


def SpiFlash(pads, *args, **kw):
if hasattr(pads, "mosi"):
return SpiFlashSingle(pads, *args, **kw)
else:
return SpiFlashDualQuad(pads, *args, **kw)

0 comments on commit dae037c

Please sign in to comment.