Skip to content

Commit 166a437

Browse files
committedAug 31, 2017
spi: support combining multiple buses into one
1 parent 517c25e commit 166a437

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed
 

‎misoc/cores/spi.py

+37-19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import collections
2+
from operator import or_
3+
from functools import reduce
4+
15
from migen import *
26
from migen.genlib.fsm import FSM, NextState
37
from misoc.interconnect.csr import *
@@ -225,12 +229,17 @@ class SPIMaster(Module, AutoCSR):
225229
* If desired, write data queuing the next (possibly chained) transfer.
226230
"""
227231
def __init__(self, pads, data_width=32, clock_width=8, bits_width=6):
232+
if isinstance(pads, collections.Iterable):
233+
pads_list = pads
234+
else:
235+
pads_list = [pads]
236+
228237
# CSR
229238
self._data_read = CSRStatus(data_width)
230239
self._data_write = CSRStorage(data_width, atomic_write=True)
231240
self._xfer_len_read = CSRStorage(bits_width)
232241
self._xfer_len_write = CSRStorage(bits_width)
233-
self._cs = CSRStorage(len(pads.cs_n))
242+
self._cs = CSRStorage(sum(len(pads.cs_n) for pads in pads_list))
234243
self._offline = CSRStorage(reset=1)
235244
self._cs_polarity = CSRStorage()
236245
self._clk_polarity = CSRStorage()
@@ -293,28 +302,37 @@ def __init__(self, pads, data_width=32, clock_width=8, bits_width=6):
293302
]
294303

295304
# I/O
296-
if hasattr(pads, "cs_n"):
305+
all_cs = Signal(len(cs))
306+
self.comb += all_cs.eq((cs & Replicate(spi.cs, len(cs))) ^
307+
Replicate(~self._cs_polarity.storage, len(cs)))
308+
offset = 0
309+
for pads in pads_list:
297310
cs_n_t = TSTriple(len(pads.cs_n))
298311
self.specials += cs_n_t.get_tristate(pads.cs_n)
299312
self.comb += [
300313
cs_n_t.oe.eq(~self._offline.storage),
301-
cs_n_t.o.eq((cs & Replicate(spi.cs, len(cs))) ^
302-
Replicate(~self._cs_polarity.storage, len(cs))),
314+
cs_n_t.o.eq(all_cs[offset:]),
303315
]
316+
offset += len(pads.cs_n)
304317

305-
clk_t = TSTriple()
306-
self.specials += clk_t.get_tristate(pads.clk)
307-
self.comb += [
308-
clk_t.oe.eq(~self._offline.storage),
309-
clk_t.o.eq((spi.cg.clk & spi.cs) ^ self._clk_polarity.storage),
310-
]
318+
for pads in pads_list:
319+
clk_t = TSTriple()
320+
self.specials += clk_t.get_tristate(pads.clk)
321+
self.comb += [
322+
clk_t.oe.eq(~self._offline.storage),
323+
clk_t.o.eq((spi.cg.clk & spi.cs) ^ self._clk_polarity.storage),
324+
]
311325

312-
mosi_t = TSTriple()
313-
self.specials += mosi_t.get_tristate(pads.mosi)
314-
self.comb += [
315-
mosi_t.oe.eq(~self._offline.storage & spi.cs &
316-
(spi.oe | ~self._half_duplex.storage)),
317-
mosi_t.o.eq(spi.reg.o),
318-
spi.reg.i.eq(Mux(self._half_duplex.storage, mosi_t.i,
319-
getattr(pads, "miso", mosi_t.i))),
320-
]
326+
mosi_t = TSTriple()
327+
self.specials += mosi_t.get_tristate(pads.mosi)
328+
self.comb += [
329+
mosi_t.oe.eq(~self._offline.storage & spi.cs &
330+
(spi.oe | ~self._half_duplex.storage)),
331+
mosi_t.o.eq(spi.reg.o),
332+
]
333+
334+
if all(hasattr(pads, "miso") for pads in pads_list):
335+
miso = reduce(or_, [pads.miso for pads in pads_list])
336+
else:
337+
miso = mosi_t.i
338+
self.comb += spi.reg.i.eq(Mux(self._half_duplex.storage, mosi_t.i, miso))

0 commit comments

Comments
 (0)
Please sign in to comment.