99module Clash.Cores.SPI
1010 ( SPIMode (.. )
1111 -- * SPI master
12+ , SpiMasterIn (.. )
13+ , SpiMasterOut (.. )
1214 , spiMaster
1315 -- * SPI slave
16+ , SpiSlaveIn (.. )
17+ , SpiSlaveOut (.. )
1418 , SPISlaveConfig (.. )
1519 , spiSlave
1620 -- ** Vendor configured SPI slaves
@@ -26,6 +30,53 @@ import Clash.Sized.Internal.BitVector
2630
2731import Clash.Cores.LatticeSemi.ICE40.IO
2832import Clash.Cores.LatticeSemi.ECP5.IO
33+ import Clash.Class.HasDomain
34+
35+ -- | Input signals of an SPI subordinate.
36+ data SpiSlaveIn (ds :: BiSignalDefault ) (dom :: Domain ) (misoLanes :: Nat ) (mosiLanes :: Nat ) =
37+ SpiSlaveIn {
38+ spiSlaveMosi :: " MOSI" ::: Signal dom (BitVector mosiLanes ),
39+ -- ^ Master-out, slave-in
40+ spiSlaveMisoIn :: " MISO" ::: BiSignalIn ds dom misoLanes ,
41+ -- ^ Master-in, slave-out
42+ spiSlaveSck :: " SCK" ::: Signal dom Bit ,
43+ -- ^ Serial Clock
44+ spiSlaveSs :: " SS" ::: Signal dom Bit
45+ -- ^ Slave select
46+ }
47+
48+ type instance TryDomain t (SpiSlaveIn ds dom misoLanes mosiLanes ) = 'Found dom
49+
50+ -- | Output signals of an SPI subordinate.
51+ data SpiSlaveOut (ds :: BiSignalDefault ) (dom :: Domain ) (misoLanes :: Nat ) (mosiLanes :: Nat ) =
52+ SpiSlaveOut {
53+ spiSlaveMisoOut :: " MISO" ::: BiSignalOut ds dom misoLanes
54+ -- ^ Master-in, slave-out
55+ }
56+
57+ type instance TryDomain t (SpiSlaveOut ds dom misoLanes mosiLanes ) = 'Found dom
58+
59+ -- | Output signals of an SPI master.
60+ data SpiMasterOut (dom :: Domain ) (misoLanes :: Nat ) (mosiLanes :: Nat ) =
61+ SpiMasterOut {
62+ spiMasterMosi :: " MOSI" ::: Signal dom (BitVector mosiLanes ),
63+ -- ^ Master-out, slave-in
64+ spiMasterSck :: " SCK" ::: Signal dom Bit ,
65+ -- ^ Serial Clock
66+ spiMasterSs :: " SS" ::: Signal dom Bit
67+ -- ^ Slave select
68+ }
69+
70+ type instance TryDomain t (SpiMasterOut dom misoLanes mosiLanes ) = 'Found dom
71+
72+ -- | Input signals of an SPI master.
73+ data SpiMasterIn (dom :: Domain ) (misoLanes :: Nat ) (mosiLanes :: Nat ) =
74+ SpiMasterIn {
75+ spiMasterMisoOut :: " MISO" ::: Signal dom (BitVector misoLanes )
76+ -- ^ Master-in, slave-out
77+ }
78+
79+ type instance TryDomain t (SpiMasterIn dom misoLanes mosiLanes ) = 'Found dom
2980
3081-- | SPI mode
3182--
@@ -184,35 +235,29 @@ spiSlave
184235 . (HiddenClockResetEnable dom , KnownNat n , 1 <= n )
185236 => SPISlaveConfig ds dom
186237 -- ^ Configure SPI mode and tri-state buffer
187- -> Signal dom Bool
188- -- ^ Serial Clock (SCLK)
189- -> Signal dom Bit
190- -- ^ Master Output Slave Input (MOSI)
191- -> BiSignalIn ds dom 1
192- -- ^ Master Input Slave Output (MISO)
193- --
194- -- Inout port connected to the tri-state buffer for the MISO
195- -> Signal dom Bool
196- -- ^ Slave select (SS)
238+ -> SpiSlaveIn ds dom 1 1
239+ -- ^ SPI interface
197240 -> Signal dom (BitVector n )
198- -- ^ Data to send from master to slave
241+ -- ^ Data to send from slave to master.
199242 --
200243 -- Input is latched the moment slave select goes low
201- -> ( BiSignalOut ds dom 1
244+ -> ( SpiSlaveOut ds dom 1 1
202245 , Signal dom Bool
203246 , Signal dom (Maybe (BitVector n )))
204247 -- ^ Parts of the tuple:
205248 --
206249 -- 1. The "out" part of the inout port of the MISO; used only for simulation.
207250 --
208- -- 2. (Maybe) the word send by the master
209- spiSlave (SPISlaveConfig mode latch buf) sclk mosi bin ss din =
251+ -- 2. the acknowledgement for the data sent from the master to the slave.
252+ --
253+ -- 2. (Maybe) the word sent by the master
254+ spiSlave (SPISlaveConfig mode latch buf) (SpiSlaveIn mosi bin sclk ss) din =
210255 let ssL = if latch then delay undefined ss else ss
211256 mosiL = if latch then delay undefined mosi else mosi
212257 sclkL = if latch then delay undefined sclk else sclk
213- (miso, ack, dout) = spiCommon mode ssL mosiL sclkL din
214- bout = buf bin (not <$> ssL) miso
215- in (bout, ack, dout)
258+ (miso, ack, dout) = spiCommon mode (bitToBool <$> ssL) ( head . bv2v <$> mosiL) (bitToBool <$> sclkL) din
259+ bout = buf bin (not . bitToBool <$> ssL) miso
260+ in (SpiSlaveOut bout, ack, dout)
216261
217262-- | SPI master configurable in the SPI mode and clock divider
218263--
@@ -237,11 +282,8 @@ spiMaster
237282 -> Signal dom (Maybe (BitVector n ))
238283 -- ^ Data to send from master to slave, transmission starts when receiving
239284 -- /Just/ a value
240- -> Signal dom Bit
241- -- ^ Master Input Slave Output (MISO)
242- -> ( Signal dom Bool -- SCK
243- , Signal dom Bit -- MOSI
244- , Signal dom Bool -- SS
285+ -> SpiMasterIn dom 1 1
286+ -> ( SpiMasterOut dom 1 1
245287 , Signal dom Bool -- Busy
246288 , Signal dom Bool -- Acknowledge
247289 , Signal dom (Maybe (BitVector n )) -- Data: Slave -> Master
@@ -254,15 +296,15 @@ spiMaster
254296 -- 4. Busy signal indicating that a transmission is in progress, new words on
255297 -- the data line will be ignored when /True/
256298 -- 5. (Maybe) the word send from the slave to the master
257- spiMaster mode fN fW din miso =
258- let (mosi, ack, dout) = spiCommon mode ssL misoL sclkL
299+ spiMaster mode fN fW din ( SpiMasterIn miso) =
300+ let (mosi, ack, dout) = spiCommon mode ssL ( head . bv2v <$> misoL) sclkL
259301 (fromMaybe undefined # <$> din)
260302 latch = snatToInteger fN /= 1
261303 ssL = if latch then delay undefined ss else ss
262304 misoL = if latch then delay undefined miso else miso
263305 sclkL = if latch then delay undefined sclk else sclk
264306 (ss, sclk, busy) = spiGen mode fN fW din
265- in (sclk, mosi, ss , busy, ack, dout)
307+ in (SpiMasterOut (v2bv . singleton <$> mosi) (boolToBit <$> sclk) (boolToBit <$> ss) , busy, ack, dout)
266308
267309-- | Generate slave select and SCK
268310spiGen
@@ -339,21 +381,12 @@ spiSlaveLatticeSBIO
339381 -- Clock: 2*SCK < Core
340382 --
341383 -- * Set to /False/ when core clock is twice as fast, or as fast, as the SCK
342- -> Signal dom Bool
343- -- ^ Serial Clock (SCLK)
344- -> Signal dom Bit
345- -- ^ Master Output Slave Input (MOSI)
346- -> BiSignalIn 'Floating dom 1
347- -- ^ Master Input Slave Output (MISO)
348- --
349- -- Inout port connected to the tri-state buffer for the MISO
350- -> Signal dom Bool
351- -- ^ Slave select (SS)
384+ -> SpiSlaveIn 'Floating dom 1 1
352385 -> Signal dom (BitVector n )
353386 -- ^ Data to send from slave to master
354387 --
355388 -- Input is latched the moment slave select goes low
356- -> ( BiSignalOut 'Floating dom 1
389+ -> ( SpiSlaveOut 'Floating dom 1 1
357390 , Signal dom Bool
358391 , Signal dom (Maybe (BitVector n )))
359392 -- ^ Parts of the tuple:
@@ -385,21 +418,12 @@ spiSlaveLatticeBB
385418 -- Clock: 2*SCK < Core
386419 --
387420 -- * Set to /False/ when core clock is twice as fast, or as fast, as the SCK
388- -> Signal dom Bool
389- -- ^ Serial Clock (SCLK)
390- -> Signal dom Bit
391- -- ^ Master Output Slave Input (MOSI)
392- -> BiSignalIn 'Floating dom 1
393- -- ^ Master Input Slave Output (MISO)
394- --
395- -- Inout port connected to the tri-state buffer for the MISO
396- -> Signal dom Bool
397- -- ^ Slave select (SS)
421+ -> SpiSlaveIn 'Floating dom 1 1
398422 -> Signal dom (BitVector n )
399423 -- ^ Data to send from slave to master
400424 --
401425 -- Input is latched the moment slave select goes low
402- -> ( BiSignalOut 'Floating dom 1
426+ -> ( SpiSlaveOut 'Floating dom 1 1
403427 , Signal dom Bool
404428 , Signal dom (Maybe (BitVector n )))
405429 -- ^ Parts of the tuple:
0 commit comments