Skip to content

Commit

Permalink
squishy: gateware: peripherals: Added SPI Interface
Browse files Browse the repository at this point in the history
Added a `SPIInterface` module that allows for a single SPI bus resource to be used as both a `SPIController` and/or a `SPIPeripheral` depending on the `SPIInterfaceMode` flag option.

This is mainly useful for the rev2 platform where we need to act as a peripheral to the supervisor and a controller to the PSRAM that are both on the same SPI bus
  • Loading branch information
lethalbit committed Nov 18, 2024
1 parent c605ec4 commit fbcbb99
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions squishy/gateware/peripherals/spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,78 @@
from ..platform import SquishyPlatformType

__all__ = (
'SPIInterface',
'SPIInterfaceMode',
'SPIController',
'SPIPeripheral'
)

@unique
class SPIInterfaceMode(Flag):
CONTROLLER = auto()
PERIPHERAL = auto()
BOTH = CONTROLLER | PERIPHERAL

class SPIInterface(Elaboratable):
'''
Generic SPI interface.
Attributes
----------
active_mode: Signal
'''

def __init__(
self, *,
clk: Subsignal, cipo: Subsignal, copi: Subsignal, cs_peripheral: Subsignal, cs_controller: Subsignal,
mode: SPIInterfaceMode = SPIInterfaceMode.BOTH, reg_map: Multiplexer | None = None
) -> None:

# Subsignals for SPI Bus from SPI Resource
self._clk = clk
self._cipo = cipo
self._copi = copi
self._cs_peripheral = cs_peripheral
self._cs_controller = cs_controller

self._mode = mode

if self._mode == SPIInterfaceMode.BOTH:
self.active_mode = Signal(decoder = lambda i: 'ctrl' if i == 1 else 'perh')

if self._mode & SPIInterfaceMode.CONTROLLER:
self.controller = SPIController(
clk = self._clk.o, cipo = self._cipo.i, copi = self._copi.o, cs = self._cs_controller.o
)

if self._mode & SPIInterfaceMode.PERIPHERAL:
self.peripheral = SPIPeripheral(
clk = self._clk.i, cipo = self._cipo.o, copi = self._copi.i, cs = self._cs_peripheral.i,
reg_map = reg_map
)

def elaborate(self, _: SquishyPlatformType | None) -> Module:
m = Module()

if self._mode & SPIInterfaceMode.CONTROLLER:
m.submodules.ctrl = self.controller

if self._mode & SPIInterfaceMode.PERIPHERAL:
m.submodules.perh = self.peripheral

if self._mode == SPIInterfaceMode.BOTH:
# active_mode: 1 = Controller; 0 = Peripheral
m.d.comb += [
self._clk.oe.eq(self.active_mode),
self._cipo.oe.eq(~self.active_mode),
self._copi.oe.eq(self.active_mode),
]

return m


class SPIController(Elaboratable):
'''
Expand Down

0 comments on commit fbcbb99

Please sign in to comment.