9
9
module Clash.Cores.SPI
10
10
( SPIMode (.. )
11
11
-- * SPI master
12
+ , SpiMasterIn (.. )
13
+ , SpiMasterOut (.. )
12
14
, spiMaster
13
15
-- * SPI slave
16
+ , SpiSlaveIn (.. )
17
+ , SpiSlaveOut (.. )
14
18
, SPISlaveConfig (.. )
15
19
, spiSlave
16
20
-- ** Vendor configured SPI slaves
@@ -26,6 +30,53 @@ import Clash.Sized.Internal.BitVector
26
30
27
31
import Clash.Cores.LatticeSemi.ICE40.IO
28
32
import 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
+ spiMasterMiso :: " MISO" ::: Signal dom (BitVector misoLanes )
76
+ -- ^ Master-in, slave-out
77
+ }
78
+
79
+ type instance TryDomain t (SpiMasterIn dom misoLanes mosiLanes ) = 'Found dom
29
80
30
81
-- | SPI mode
31
82
--
@@ -184,35 +235,29 @@ spiSlave
184
235
. (HiddenClockResetEnable dom , KnownNat n , 1 <= n )
185
236
=> SPISlaveConfig ds dom
186
237
-- ^ 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
197
240
-> Signal dom (BitVector n )
198
- -- ^ Data to send from master to slave
241
+ -- ^ Data to send from slave to master.
199
242
--
200
243
-- Input is latched the moment slave select goes low
201
- -> ( BiSignalOut ds dom 1
244
+ -> ( SpiSlaveOut ds dom 1 1
202
245
, Signal dom Bool
203
246
, Signal dom (Maybe (BitVector n )))
204
247
-- ^ Parts of the tuple:
205
248
--
206
249
-- 1. The "out" part of the inout port of the MISO; used only for simulation.
207
250
--
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 =
210
255
let ssL = if latch then delay undefined ss else ss
211
256
mosiL = if latch then delay undefined mosi else mosi
212
257
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)
216
261
217
262
-- | SPI master configurable in the SPI mode and clock divider
218
263
--
@@ -237,11 +282,8 @@ spiMaster
237
282
-> Signal dom (Maybe (BitVector n ))
238
283
-- ^ Data to send from master to slave, transmission starts when receiving
239
284
-- /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
245
287
, Signal dom Bool -- Busy
246
288
, Signal dom Bool -- Acknowledge
247
289
, Signal dom (Maybe (BitVector n )) -- Data: Slave -> Master
@@ -254,15 +296,15 @@ spiMaster
254
296
-- 4. Busy signal indicating that a transmission is in progress, new words on
255
297
-- the data line will be ignored when /True/
256
298
-- 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
259
301
(fromMaybe undefined # <$> din)
260
302
latch = snatToInteger fN /= 1
261
303
ssL = if latch then delay undefined ss else ss
262
304
misoL = if latch then delay undefined miso else miso
263
305
sclkL = if latch then delay undefined sclk else sclk
264
306
(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)
266
308
267
309
-- | Generate slave select and SCK
268
310
spiGen
@@ -339,21 +381,12 @@ spiSlaveLatticeSBIO
339
381
-- Clock: 2*SCK < Core
340
382
--
341
383
-- * 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
352
385
-> Signal dom (BitVector n )
353
386
-- ^ Data to send from slave to master
354
387
--
355
388
-- Input is latched the moment slave select goes low
356
- -> ( BiSignalOut 'Floating dom 1
389
+ -> ( SpiSlaveOut 'Floating dom 1 1
357
390
, Signal dom Bool
358
391
, Signal dom (Maybe (BitVector n )))
359
392
-- ^ Parts of the tuple:
@@ -385,21 +418,12 @@ spiSlaveLatticeBB
385
418
-- Clock: 2*SCK < Core
386
419
--
387
420
-- * 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
398
422
-> Signal dom (BitVector n )
399
423
-- ^ Data to send from slave to master
400
424
--
401
425
-- Input is latched the moment slave select goes low
402
- -> ( BiSignalOut 'Floating dom 1
426
+ -> ( SpiSlaveOut 'Floating dom 1 1
403
427
, Signal dom Bool
404
428
, Signal dom (Maybe (BitVector n )))
405
429
-- ^ Parts of the tuple:
0 commit comments