Software APIs
dif_spi_host.h
Go to the documentation of this file.
1
// Copyright lowRISC contributors (OpenTitan project).
2
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
// SPDX-License-Identifier: Apache-2.0
4
5
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
6
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
7
/**
8
* @file
9
* @brief <a href="/book/hw/ip/spi_host/">SPI Host</a> Device Interface
10
* Functions
11
*/
12
13
#include <stdint.h>
14
15
#include "sw/device/lib/dif/autogen/dif_spi_host_autogen.h"
16
17
#ifdef __cplusplus
18
extern
"C"
{
19
#endif
// __cplusplus
20
21
/**
22
* Runtime configuration for SPI Host.
23
*
24
* This struct describes (SOFTWARE) runtime information for one-time
25
* configuration of the hardware.
26
*/
27
typedef
struct
dif_spi_host_config
{
28
/** Desired SPI clock frequency (SCK). */
29
uint32_t
spi_clock
;
30
/** Peripheral clock frequency (ie: kClockFreqPeripheralHz). */
31
uint32_t
peripheral_clock_freq_hz
;
32
struct
{
33
/** Minimum idle time between commands in SCK half-cycles. */
34
uint8_t
idle
;
35
/** Chip-select trailing time in SCK half-cycles. */
36
uint8_t
trail
;
37
/** Chip-select leading time in SCK half-cycles. */
38
uint8_t
lead
;
39
} chip_select;
40
/** Full-cycle sampling mode. */
41
bool
full_cycle
;
42
/** SPI clock phase. */
43
bool
cpha
;
44
/** SPI clock polarity. */
45
bool
cpol
;
46
/** If `EVENT_ENABLE.TXWM` is set, an interrupt will fire when the depth of
47
* the TX FIFO drops below `TX_WATERMARK` words (32b each). */
48
size_t
tx_watermark
;
49
/** If `EVENT_ENABLE.RXWM` is set, an interrupt will fire when the depth of
50
* the RX FIFO drops below `RX_WATERMARK` words (32b each). */
51
size_t
rx_watermark
;
52
}
dif_spi_host_config_t
;
53
54
/**
55
* Width of SPI operations.
56
*/
57
typedef
enum
dif_spi_host_width
{
58
/** Standard SPI mode (single lanes for send and recv). */
59
kDifSpiHostWidthStandard
= 0,
60
/** Dual SPI mode (use two lanes for send and recv). */
61
kDifSpiHostWidthDual
= 1,
62
/** Quad SPI mode (use four lanes for send and recv). */
63
kDifSpiHostWidthQuad
= 2,
64
}
dif_spi_host_width_t
;
65
66
/**
67
* Direction of SPI operations.
68
*
69
* This describes which direction a given SPI operation will use.
70
*/
71
typedef
enum
dif_spi_host_direction
{
72
/** The SPI host neither transmits or receives. */
73
kDifSpiHostDirectionDummy
= 0,
74
/** The SPI host receives data. */
75
kDifSpiHostDirectionRx
= 1,
76
/** The SPI host transmits data. */
77
kDifSpiHostDirectionTx
= 2,
78
/** The SPI host transmits and receives data. */
79
kDifSpiHostDirectionBidirectional
= 3,
80
}
dif_spi_host_direction_t
;
81
82
/**
83
* Segment types for segments in a transaction.
84
*/
85
typedef
enum
dif_spi_host_segment_type
{
86
/** The segment is a SPI opcode. */
87
kDifSpiHostSegmentTypeOpcode
,
88
/** The segment is a SPI address. */
89
kDifSpiHostSegmentTypeAddress
,
90
/** The segment is a SPI dummy cycle. */
91
kDifSpiHostSegmentTypeDummy
,
92
/** The segment is a SPI transmit (from a memory buffer). */
93
kDifSpiHostSegmentTypeTx
,
94
/** The segment is a SPI receive (into a memory buffer). */
95
kDifSpiHostSegmentTypeRx
,
96
/** The segment is a simultaneous transmit and receieve. */
97
kDifSpiHostSegmentTypeBidirectional
,
98
}
dif_spi_host_segment_type_t
;
99
100
/**
101
* Address mode for the address segment in a transaction.
102
*/
103
typedef
enum
dif_spi_host_addr_mode
{
104
/** The address is a 3-byte address. */
105
kDifSpiHostAddrMode3b
,
106
/** The address is a 4-byte address. */
107
kDifSpiHostAddrMode4b
,
108
}
dif_spi_host_addr_mode_t
;
109
110
/**
111
* Segment descriptor for each segment in a transaction.
112
*
113
* This struct is a tagged union: the `type` field determines
114
* which field of the union is relevant.
115
*/
116
typedef
struct
dif_spi_host_segment
{
117
/** The segment type for this segment. */
118
dif_spi_host_segment_type_t
type
;
119
union
{
120
struct
{
121
dif_spi_host_width_t
width;
122
uint8_t opcode;
123
} opcode;
124
struct
{
125
dif_spi_host_width_t
width;
126
dif_spi_host_addr_mode_t
mode;
127
uint32_t address;
128
} address;
129
struct
{
130
dif_spi_host_width_t
width;
131
size_t
length;
132
} dummy;
133
struct
{
134
dif_spi_host_width_t
width;
135
const
void
*buf;
136
size_t
length;
137
} tx;
138
struct
{
139
dif_spi_host_width_t
width;
140
void
*buf;
141
size_t
length;
142
} rx;
143
struct
{
144
dif_spi_host_width_t
width;
145
const
void
*txbuf;
146
void
*rxbuf;
147
size_t
length;
148
} bidir;
149
};
150
}
dif_spi_host_segment_t
;
151
152
/**
153
* Configures SPI Host with runtime information.
154
*
155
* This function should only need to be called once for the lifetime of
156
* `handle`.
157
*
158
* @param spi_host A SPI Host handle.
159
* @param config Runtime configuration parameters.
160
* @return The result of the operation.
161
*/
162
OT_WARN_UNUSED_RESULT
163
dif_result_t
dif_spi_host_configure
(
const
dif_spi_host_t
*spi_host,
164
dif_spi_host_config_t
config);
165
166
/**
167
* Sets the enablement of the SPI host output buffers.
168
*
169
* @param spi_host A SPI Host handle.
170
* @param enabled Enable or disable the output buffers.
171
* @return The result of the operation.
172
*/
173
OT_WARN_UNUSED_RESULT
174
dif_result_t
dif_spi_host_output_set_enabled
(
const
dif_spi_host_t
*spi_host,
175
bool
enabled);
176
177
/**
178
* Write to the SPI Host transmit FIFO.
179
*
180
* @param spi_host A SPI Host handle.
181
* @param src A pointer to the buffer to transmit.
182
* @param len The length of the transmit buffer.
183
* @return The result of the operation.
184
*/
185
OT_WARN_UNUSED_RESULT
186
dif_result_t
dif_spi_host_fifo_write
(
const
dif_spi_host_t
*spi_host,
187
const
void
*src, uint16_t len);
188
189
/**
190
* Read from the SPI Host receive FIFO.
191
*
192
* @param spi_host A SPI Host handle.
193
* @param dst A pointer to the buffer to receive the data.
194
* @param len The length of the receive buffer.
195
* @return The result of the operation.
196
*/
197
OT_WARN_UNUSED_RESULT
198
dif_result_t
dif_spi_host_fifo_read
(
const
dif_spi_host_t
*spi_host,
void
*dst,
199
uint16_t len);
200
201
/**
202
* Begins a SPI Host transaction without reading the FIFOs.
203
*
204
* @param spi_host A SPI Host handle.
205
* @param csid The chip-select ID of the SPI target.
206
* @param segments The SPI segments to send in this transaction.
207
* @param length The number of SPI segments in this transaction.
208
* @return The result of the operation.
209
*/
210
OT_WARN_UNUSED_RESULT
211
dif_result_t
dif_spi_host_start_transaction
(
const
dif_spi_host_t
*spi_host,
212
uint32_t csid,
213
dif_spi_host_segment_t
*segments,
214
size_t
length);
215
216
/**
217
* Begins a SPI Host transaction.
218
*
219
* @param spi_host A SPI Host handle.
220
* @param csid The chip-select ID of the SPI target.
221
* @param segments The SPI segments to send in this transaction.
222
* @param length The number of SPI segments in this transaction.
223
* @return The result of the operation.
224
*/
225
OT_WARN_UNUSED_RESULT
226
dif_result_t
dif_spi_host_transaction
(
const
dif_spi_host_t
*spi_host,
227
uint32_t csid,
228
dif_spi_host_segment_t
*segments,
229
size_t
length);
230
231
typedef
enum
dif_spi_host_events
{
232
/**
233
* Enable IRQ to be fired when `STATUS.RXFULL` goes high.
234
*/
235
kDifSpiHostEvtRxFull
= 1 << 0,
236
/**
237
* Enable IRQ to be fired when `STATUS.TXEMPTY` goes high.
238
*/
239
kDifSpiHostEvtTxEmpty
= 1 << 1,
240
/**
241
* Enable IRQ to be fired when the number of 32-bit words in the RX FIFO is
242
* greater than `CONTROL.RX_WATERMARK`.
243
*/
244
kDifSpiHostEvtRxWm
= 1 << 2,
245
/**
246
* Enable IRQ to be fired when the number of 32-bit words in the TX FIFO is
247
* greater than `CONTROL.TX_WATERMARK`.
248
*/
249
kDifSpiHostEvtTxWm
= 1 << 3,
250
/**
251
* Enable IRQ to be fired when `STATUS.READY` goes high.
252
*/
253
kDifSpiHostEvtReady
= 1 << 4,
254
/**
255
* Enable IRQ to be fired when `STATUS.ACTIVE` goes low.
256
*/
257
kDifSpiHostEvtIdle
= 1 << 5,
258
/**
259
* All above together.
260
*/
261
kDifSpiHostEvtAll
= (1 << 6) - 1,
262
} dif_spi_host_events_code_t;
263
264
/**
265
* Bitmask with the `dif_spi_host_events_code_t` values.
266
*/
267
typedef
uint32_t
dif_spi_host_events_t
;
268
269
/**
270
* Set the enable state of the spi host events.
271
*
272
* @param spi_host A SPI Host handle.
273
* @param events A bitmask with the events to be enabled or disabled.
274
* @param enable True to enable the `events` or false to disable.
275
* @return The result of the operation.
276
*/
277
OT_WARN_UNUSED_RESULT
278
dif_result_t
dif_spi_host_event_set_enabled
(
const
dif_spi_host_t
*spi_host,
279
dif_spi_host_events_t
events,
280
bool
enable);
281
282
/**
283
* Get the enabled events.
284
*
285
* @param spi_host A SPI Host handle.
286
* @param[out] events A bitmask that will contain all the events that are
287
* enabled.
288
* @return The result of the operation.
289
*/
290
OT_WARN_UNUSED_RESULT
291
dif_result_t
dif_spi_host_event_get_enabled
(
const
dif_spi_host_t
*spi_host,
292
dif_spi_host_events_t
*events);
293
294
typedef
struct
dif_spi_host_status
{
295
/**
296
* Indicates the SPI host is ready to receive commands.
297
*/
298
bool
ready
;
299
/**
300
* Indicates the SPI host is processing a previously issued command.
301
*/
302
bool
active
;
303
/**
304
* Indicates that the transmit data fifo is full.
305
*/
306
bool
tx_full
;
307
/**
308
* Indicates that the transmit data fifo is empty.
309
*/
310
bool
tx_empty
;
311
/**
312
* If true, signifies that an ongoing transaction has stalled due to lack of
313
* data in the`TX FIFO`.
314
*/
315
bool
tx_stall
;
316
/**
317
* If true, the amount of data in the `TX FIFO` has fallen below the
318
* level of `CONTROL.TX_WATERMARK`words (32b each).
319
*/
320
bool
tx_water_mark
;
321
/**
322
* Indicates that the receive fifo is full. Any ongoing transactions will
323
* stall until firmware reads some data from `RXDATA`.
324
*/
325
bool
rx_full
;
326
/**
327
* Indicates that the receive fifo is empty. Any reads from `RX FIFO` will
328
* cause an error interrupt.
329
*/
330
bool
rx_empty
;
331
/**
332
* If true, signifies that an ongoing transaction has stalled due to lack of
333
* available space in the `RX FIFO`.
334
*/
335
bool
rx_stall
;
336
/**
337
* If true the least significant bits will be transmitted first.
338
*/
339
bool
least_significant_first
;
340
/**
341
* If true, the number of 32-bits in the `RX FIFO` now exceeds the
342
* `CONTROL.RX_WATERMARK`entries (32b each).
343
*/
344
bool
rx_water_mark
;
345
/**
346
* Indicates how many unread 32-bit words are currently in the command
347
* segment queue.
348
*/
349
uint32_t
cmd_queue_depth
;
350
/**
351
* Indicates how many unread 32-bit words are currently in the `RX FIFO`.
352
* When active, this result may an underestimate due to synchronization
353
* delays.
354
*/
355
uint32_t
rx_queue_depth
;
356
/**
357
* Indicates how many unsent 32-bit words are currently in the`TX FIFO`.
358
*/
359
uint32_t
tx_queue_depth
;
360
} dif_spi_host_status_t;
361
362
/**
363
* Read the current status of the spi host.
364
*
365
* @param spi_host A SPI Host handle.
366
* @param[out] status The status of the spi.
367
* @return The result of the operation.
368
*/
369
OT_WARN_UNUSED_RESULT
370
dif_result_t
dif_spi_host_get_status
(
const
dif_spi_host_t
*spi_host,
371
dif_spi_host_status_t *
status
);
372
373
/**
374
* Issues a command segment to a spi_host.
375
*
376
* @param spi_host A SPI Host handle.
377
* @param length The number of 1-byte burst for read and write segments, or the
378
* number of cycles for dummy segments.
379
* @param speed Which speed the transmission should use.
380
* @param direction Which direction the operation should use.
381
* @param last_segment If true the chip select line is raised after the
382
* transmission, otherwise it is kept low.
383
* @return The result of the operation.
384
*/
385
OT_WARN_UNUSED_RESULT
386
dif_result_t
dif_spi_host_write_command
(
const
dif_spi_host_t
*spi_host,
387
uint16_t length,
388
dif_spi_host_width_t
speed,
389
dif_spi_host_direction_t
direction,
390
bool
last_segment);
391
392
typedef
enum
dif_spi_host_error_code
{
393
/**
394
* Indicates a write to `COMMAND` when `STATUS.READY = 0`.
395
*/
396
kDifSpiHostErrorCmdBusy
= 1 << 0,
397
/**
398
* Indicates that firmware has overflowed the `TX FIFO`.
399
*/
400
kDifSpiHostErrorOverflow
= 1 << 1,
401
/**
402
* Indicates that firmware has attempted to read from `RXDATA` when the `RX
403
* FIFO` is empty.
404
*/
405
kDifSpiHostErrorUnderflow
= 1 << 2,
406
/**
407
* Indicates an invalid command segment, meaning either an invalid value of
408
* `COMMAND.SPEED` or a request for bidirectional data transfer at dual or
409
* quad speed.
410
*/
411
kDifSpiHostErrorCmdInval
= 1 << 3,
412
/**
413
* Indicates a command was attempted with an invalid value for `CSID`.
414
*/
415
kDifSpiHostErrorCsIdIval
= 1 << 4,
416
/**
417
* Indicates that TL-UL attempted to write to `TXDATA` with no bytes enabled.
418
* Such ‘zero byte’ writes are not supported. Note: This error does not
419
* generate IRQ.
420
*/
421
kDifSpiHostErrorAccessIval
= 1 << 5,
422
/**
423
* All the errors that can generate an IRQ.
424
*/
425
kDifSpiHostIrqErrorAll
= (1 << 5) - 1,
426
/**
427
* All the errors above together.
428
*/
429
kDifSpiHostErrorAll
= (1 << 6) - 1,
430
} dif_spi_host_error_code_t;
431
432
/**
433
* Bitmask with the `dif_spi_host_error_code_t` values.
434
*/
435
typedef
uint32_t
dif_spi_host_errors_t
;
436
437
/**
438
* Set the enable state of the spi host errors.
439
*
440
* @param spi_host A SPI Host handle.
441
* @param errors A bitmask with the errors to be enabled or disabled.
442
* @param enable True to enable the `events` or false to disable.
443
* @return The result of the operation.
444
*/
445
OT_WARN_UNUSED_RESULT
446
dif_result_t
dif_spi_host_error_set_enabled
(
const
dif_spi_host_t
*spi_host,
447
dif_spi_host_errors_t
errors,
448
bool
enable);
449
450
/**
451
* Get the enabled errors.
452
*
453
* @param spi_host A SPI Host handle.
454
* @param[out] errors A bitmask that will contain all the errors that are
455
* enabled.
456
* @return The result of the operation.
457
*/
458
OT_WARN_UNUSED_RESULT
459
dif_result_t
dif_spi_host_error_get_enabled
(
const
dif_spi_host_t
*spi_host,
460
dif_spi_host_errors_t
*errors);
461
462
/**
463
* Read the current error status of the spi host.
464
*
465
* @param spi_host A SPI Host handle.
466
* @param[out] errors The error status of the spi.
467
* @return The result of the operation.
468
*/
469
OT_WARN_UNUSED_RESULT
470
dif_result_t
dif_spi_host_get_error
(
const
dif_spi_host_t
*spi_host,
471
dif_spi_host_errors_t
*errors);
472
473
/**
474
* Wait until the SPI Host is idle.
475
*
476
* @param spi_host A SPI Host handle.
477
* @return The result of the operation.
478
*/
479
OT_WARN_UNUSED_RESULT
480
dif_result_t
dif_spi_host_wait_until_idle
(
const
dif_spi_host_t
*spi_host);
481
482
#ifdef __cplusplus
483
}
// extern "C"
484
#endif
// __cplusplus
485
486
#endif
// OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
sw
device
lib
dif
dif_spi_host.h
Return to
OpenTitan Documentation