Skip to content

Commit 4333e2c

Browse files
committed
SPI: Represent inputs/outputs as records
1 parent a26bb9e commit 4333e2c

File tree

1 file changed

+62
-47
lines changed
  • clash-cores/src/Clash/Cores

1 file changed

+62
-47
lines changed

clash-cores/src/Clash/Cores/SPI.hs

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
module 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
@@ -27,6 +31,44 @@ import Clash.Sized.Internal.BitVector
2731
import Clash.Cores.LatticeSemi.ICE40.IO
2832
import Clash.Cores.LatticeSemi.ECP5.IO
2933

34+
-- | Input signals of an SPI subordinate.
35+
data SpiSlaveIn (ds :: BiSignalDefault) (dom :: Domain) (misoLanes :: Nat) (mosiLanes :: Nat) =
36+
SpiSlaveIn {
37+
spiSlaveMosi :: "MOSI" ::: Signal dom (BitVector mosiLanes),
38+
-- ^ Master-out, slave-in
39+
spiSlaveMisoIn :: "MISO" ::: BiSignalIn ds dom misoLanes,
40+
-- ^ Master-in, slave-out
41+
spiSlaveSck :: "SCK" ::: Signal dom Bit,
42+
-- ^ Serial Clock
43+
spiSlaveSs :: "SS" ::: Signal dom Bit
44+
-- ^ Slave select
45+
}
46+
47+
-- | Output signals of an SPI subordinate.
48+
data SpiSlaveOut (ds :: BiSignalDefault) (dom :: Domain) (misoLanes :: Nat) (mosiLanes :: Nat) =
49+
SpiSlaveOut {
50+
spiSlaveMisoOut :: "MISO" ::: BiSignalOut ds dom misoLanes
51+
-- ^ Master-in, slave-out
52+
}
53+
54+
-- | Output signals of an SPI master.
55+
data SpiMasterOut (dom :: Domain) (misoLanes :: Nat) (mosiLanes :: Nat) =
56+
SpiMasterOut {
57+
spiMasterMosi :: "MOSI" ::: Signal dom (BitVector mosiLanes),
58+
-- ^ Master-out, slave-in
59+
spiMasterSck :: "SCK" ::: Signal dom Bit,
60+
-- ^ Serial Clock
61+
spiMasterSs :: "SS" ::: Signal dom Bit
62+
-- ^ Slave select
63+
}
64+
65+
-- | Input signals of an SPI master.
66+
data SpiMasterIn (dom :: Domain) (misoLanes :: Nat) (mosiLanes :: Nat) =
67+
SpiMasterIn {
68+
spiMasterMisoOut :: "MISO" ::: Signal dom (BitVector misoLanes)
69+
-- ^ Master-in, slave-out
70+
}
71+
3072
-- | SPI mode
3173
--
3274
-- * CPOL: Clock POLarity
@@ -184,35 +226,29 @@ spiSlave
184226
. (HiddenClockResetEnable dom, KnownNat n, 1 <= n)
185227
=> SPISlaveConfig ds dom
186228
-- ^ 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)
229+
-> SpiSlaveIn ds dom 1 1
230+
-- ^ SPI interface
197231
-> Signal dom (BitVector n)
198-
-- ^ Data to send from master to slave
232+
-- ^ Data to send from slave to master.
199233
--
200234
-- Input is latched the moment slave select goes low
201-
-> ( BiSignalOut ds dom 1
235+
-> ( SpiSlaveOut ds dom 1 1
202236
, Signal dom Bool
203237
, Signal dom (Maybe (BitVector n)))
204238
-- ^ Parts of the tuple:
205239
--
206240
-- 1. The "out" part of the inout port of the MISO; used only for simulation.
207241
--
208-
-- 2. (Maybe) the word send by the master
209-
spiSlave (SPISlaveConfig mode latch buf) sclk mosi bin ss din =
242+
-- 2. the acknowledgement for the data sent from the master to the slave.
243+
--
244+
-- 2. (Maybe) the word sent by the master
245+
spiSlave (SPISlaveConfig mode latch buf) (SpiSlaveIn mosi bin sclk ss) din =
210246
let ssL = if latch then delay undefined ss else ss
211247
mosiL = if latch then delay undefined mosi else mosi
212248
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)
249+
(miso, ack, dout) = spiCommon mode (bitToBool <$> ssL) (head . bv2v <$> mosiL) (bitToBool <$> sclkL) din
250+
bout = buf bin (not . bitToBool <$> ssL) miso
251+
in (SpiSlaveOut bout, ack, dout)
216252

217253
-- | SPI master configurable in the SPI mode and clock divider
218254
--
@@ -237,11 +273,8 @@ spiMaster
237273
-> Signal dom (Maybe (BitVector n))
238274
-- ^ Data to send from master to slave, transmission starts when receiving
239275
-- /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
276+
-> SpiMasterIn dom 1 1
277+
-> ( SpiMasterOut dom 1 1
245278
, Signal dom Bool -- Busy
246279
, Signal dom Bool -- Acknowledge
247280
, Signal dom (Maybe (BitVector n)) -- Data: Slave -> Master
@@ -254,15 +287,15 @@ spiMaster
254287
-- 4. Busy signal indicating that a transmission is in progress, new words on
255288
-- the data line will be ignored when /True/
256289
-- 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
290+
spiMaster mode fN fW din (SpiMasterIn miso) =
291+
let (mosi, ack, dout) = spiCommon mode ssL (head . bv2v <$> misoL) sclkL
259292
(fromMaybe undefined# <$> din)
260293
latch = snatToInteger fN /= 1
261294
ssL = if latch then delay undefined ss else ss
262295
misoL = if latch then delay undefined miso else miso
263296
sclkL = if latch then delay undefined sclk else sclk
264297
(ss, sclk, busy) = spiGen mode fN fW din
265-
in (sclk, mosi, ss, busy, ack, dout)
298+
in (SpiMasterOut (v2bv . singleton <$> mosi) (boolToBit <$> sclk) (boolToBit <$> ss), busy, ack, dout)
266299

267300
-- | Generate slave select and SCK
268301
spiGen
@@ -339,21 +372,12 @@ spiSlaveLatticeSBIO
339372
-- Clock: 2*SCK < Core
340373
--
341374
-- * 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)
375+
-> SpiSlaveIn 'Floating dom 1 1
352376
-> Signal dom (BitVector n)
353377
-- ^ Data to send from slave to master
354378
--
355379
-- Input is latched the moment slave select goes low
356-
-> ( BiSignalOut 'Floating dom 1
380+
-> ( SpiSlaveOut 'Floating dom 1 1
357381
, Signal dom Bool
358382
, Signal dom (Maybe (BitVector n)))
359383
-- ^ Parts of the tuple:
@@ -385,21 +409,12 @@ spiSlaveLatticeBB
385409
-- Clock: 2*SCK < Core
386410
--
387411
-- * 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)
412+
-> SpiSlaveIn 'Floating dom 1 1
398413
-> Signal dom (BitVector n)
399414
-- ^ Data to send from slave to master
400415
--
401416
-- Input is latched the moment slave select goes low
402-
-> ( BiSignalOut 'Floating dom 1
417+
-> ( SpiSlaveOut 'Floating dom 1 1
403418
, Signal dom Bool
404419
, Signal dom (Maybe (BitVector n)))
405420
-- ^ Parts of the tuple:

0 commit comments

Comments
 (0)