|
| 1 | +import collections |
| 2 | +from operator import or_ |
| 3 | +from functools import reduce |
| 4 | + |
1 | 5 | from migen import *
|
2 | 6 | from migen.genlib.fsm import FSM, NextState
|
3 | 7 | from misoc.interconnect.csr import *
|
@@ -225,12 +229,17 @@ class SPIMaster(Module, AutoCSR):
|
225 | 229 | * If desired, write data queuing the next (possibly chained) transfer.
|
226 | 230 | """
|
227 | 231 | 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 | + |
228 | 237 | # CSR
|
229 | 238 | self._data_read = CSRStatus(data_width)
|
230 | 239 | self._data_write = CSRStorage(data_width, atomic_write=True)
|
231 | 240 | self._xfer_len_read = CSRStorage(bits_width)
|
232 | 241 | 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)) |
234 | 243 | self._offline = CSRStorage(reset=1)
|
235 | 244 | self._cs_polarity = CSRStorage()
|
236 | 245 | self._clk_polarity = CSRStorage()
|
@@ -293,28 +302,37 @@ def __init__(self, pads, data_width=32, clock_width=8, bits_width=6):
|
293 | 302 | ]
|
294 | 303 |
|
295 | 304 | # 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: |
297 | 310 | cs_n_t = TSTriple(len(pads.cs_n))
|
298 | 311 | self.specials += cs_n_t.get_tristate(pads.cs_n)
|
299 | 312 | self.comb += [
|
300 | 313 | 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:]), |
303 | 315 | ]
|
| 316 | + offset += len(pads.cs_n) |
304 | 317 |
|
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 | + ] |
311 | 325 |
|
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