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