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="/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 without reading the FIFOs.
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_start_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
/**
216
* Begins a SPI Host transaction.
217
*
218
* @param spi_host A SPI Host handle.
219
* @param csid The chip-select ID of the SPI target.
220
* @param segments The SPI segments to send in this transaction.
221
* @param length The number of SPI segments in this transaction.
222
* @return The result of the operation.
223
*/
224
OT_WARN_UNUSED_RESULT
225
dif_result_t
dif_spi_host_transaction
(
const
dif_spi_host_t
*spi_host,
226
uint32_t csid,
227
dif_spi_host_segment_t
*segments,
228
size_t
length);
229
230
typedef
enum
dif_spi_host_events
{
231
/**
232
* Enable IRQ to be fired when `STATUS.RXFULL` goes high.
233
*/
234
kDifSpiHostEvtRxFull
= 1 << 0,
235
/**
236
* Enable IRQ to be fired when `STATUS.TXEMPTY` goes high.
237
*/
238
kDifSpiHostEvtTxEmpty
= 1 << 1,
239
/**
240
* Enable IRQ to be fired when the number of 32-bit words in the RX FIFO is
241
* greater than `CONTROL.RX_WATERMARK`.
242
*/
243
kDifSpiHostEvtRxWm
= 1 << 2,
244
/**
245
* Enable IRQ to be fired when the number of 32-bit words in the TX FIFO is
246
* greater than `CONTROL.TX_WATERMARK`.
247
*/
248
kDifSpiHostEvtTxWm
= 1 << 3,
249
/**
250
* Enable IRQ to be fired when `STATUS.READY` goes high.
251
*/
252
kDifSpiHostEvtReady
= 1 << 4,
253
/**
254
* Enable IRQ to be fired when `STATUS.ACTIVE` goes low.
255
*/
256
kDifSpiHostEvtIdle
= 1 << 5,
257
/**
258
* All above together.
259
*/
260
kDifSpiHostEvtAll
= (1 << 6) - 1,
261
} dif_spi_host_events_code_t;
262
263
/**
264
* Bitmask with the `dif_spi_host_events_code_t` values.
265
*/
266
typedef
uint32_t
dif_spi_host_events_t
;
267
268
/**
269
* Set the enable state of the spi host events.
270
*
271
* @param spi_host A SPI Host handle.
272
* @param events A bitmask with the events to be enabled or disabled.
273
* @param enable True to enable the `events` or false to disable.
274
* @return The result of the operation.
275
*/
276
OT_WARN_UNUSED_RESULT
277
dif_result_t
dif_spi_host_event_set_enabled
(
const
dif_spi_host_t
*spi_host,
278
dif_spi_host_events_t
events,
279
bool
enable);
280
281
/**
282
* Get the enabled events.
283
*
284
* @param spi_host A SPI Host handle.
285
* @param[out] events A bitmask that will contain all the events that are
286
* enabled.
287
* @return The result of the operation.
288
*/
289
OT_WARN_UNUSED_RESULT
290
dif_result_t
dif_spi_host_event_get_enabled
(
const
dif_spi_host_t
*spi_host,
291
dif_spi_host_events_t
*events);
292
293
typedef
struct
dif_spi_host_status
{
294
/**
295
* Indicates the SPI host is ready to receive commands.
296
*/
297
bool
ready
;
298
/**
299
* Indicates the SPI host is processing a previously issued command.
300
*/
301
bool
active
;
302
/**
303
* Indicates that the transmit data fifo is full.
304
*/
305
bool
tx_full
;
306
/**
307
* Indicates that the transmit data fifo is empty.
308
*/
309
bool
tx_empty
;
310
/**
311
* If true, signifies that an ongoing transaction has stalled due to lack of
312
* data in the`TX FIFO`.
313
*/
314
bool
tx_stall
;
315
/**
316
* If true, the amount of data in the `TX FIFO` has fallen below the
317
* level of `CONTROL.TX_WATERMARK`words (32b each).
318
*/
319
bool
tx_water_mark
;
320
/**
321
* Indicates that the receive fifo is full. Any ongoing transactions will
322
* stall until firmware reads some data from `RXDATA`.
323
*/
324
bool
rx_full
;
325
/**
326
* Indicates that the receive fifo is empty. Any reads from `RX FIFO` will
327
* cause an error interrupt.
328
*/
329
bool
rx_empty
;
330
/**
331
* If true, signifies that an ongoing transaction has stalled due to lack of
332
* available space in the `RX FIFO`.
333
*/
334
bool
rx_stall
;
335
/**
336
* If true the least significant bits will be transmitted first.
337
*/
338
bool
least_significant_first
;
339
/**
340
* If true, the number of 32-bits in the `RX FIFO` now exceeds the
341
* `CONTROL.RX_WATERMARK`entries (32b each).
342
*/
343
bool
rx_water_mark
;
344
/**
345
* Indicates how many unread 32-bit words are currently in the command
346
* segment queue.
347
*/
348
uint32_t
cmd_queue_depth
;
349
/**
350
* Indicates how many unread 32-bit words are currently in the `RX FIFO`.
351
* When active, this result may an underestimate due to synchronization
352
* delays.
353
*/
354
uint32_t
rx_queue_depth
;
355
/**
356
* Indicates how many unsent 32-bit words are currently in the`TX FIFO`.
357
*/
358
uint32_t
tx_queue_depth
;
359
} dif_spi_host_status_t;
360
361
/**
362
* Read the current status of the spi host.
363
*
364
* @param spi_host A SPI Host handle.
365
* @param[out] status The status of the spi.
366
* @return The result of the operation.
367
*/
368
OT_WARN_UNUSED_RESULT
369
dif_result_t
dif_spi_host_get_status
(
const
dif_spi_host_t
*spi_host,
370
dif_spi_host_status_t *
status
);
371
372
/**
373
* Issues a command segment to a spi_host.
374
*
375
* @param spi_host A SPI Host handle.
376
* @param length The number of 1-byte burst for read and write segments, or the
377
* number of cycles for dummy segments.
378
* @param speed Which speed the transmission should use.
379
* @param direction Which direction the operation should use.
380
* @param last_segment If true the chip select line is raised after the
381
* transmission, otherwise it is kept low.
382
* @return The result of the operation.
383
*/
384
OT_WARN_UNUSED_RESULT
385
dif_result_t
dif_spi_host_write_command
(
const
dif_spi_host_t
*spi_host,
386
uint16_t length,
387
dif_spi_host_width_t
speed,
388
dif_spi_host_direction_t
direction,
389
bool
last_segment);
390
391
typedef
enum
dif_spi_host_error_code
{
392
/**
393
* Indicates a write to `COMMAND` when `STATUS.READY = 0`.
394
*/
395
kDifSpiHostErrorCmdBusy
= 1 << 0,
396
/**
397
* Indicates that firmware has overflowed the `TX FIFO`.
398
*/
399
kDifSpiHostErrorOverflow
= 1 << 1,
400
/**
401
* Indicates that firmware has attempted to read from `RXDATA` when the `RX
402
* FIFO` is empty.
403
*/
404
kDifSpiHostErrorUnderflow
= 1 << 2,
405
/**
406
* Indicates an invalid command segment, meaning either an invalid value of
407
* `COMMAND.SPEED` or a request for bidirectional data transfer at dual or
408
* quad speed.
409
*/
410
kDifSpiHostErrorCmdInval
= 1 << 3,
411
/**
412
* Indicates a command was attempted with an invalid value for `CSID`.
413
*/
414
kDifSpiHostErrorCsIdIval
= 1 << 4,
415
/**
416
* Indicates that TL-UL attempted to write to `TXDATA` with no bytes enabled.
417
* Such ‘zero byte’ writes are not supported. Note: This error does not
418
* generate IRQ.
419
*/
420
kDifSpiHostErrorAccessIval
= 1 << 5,
421
/**
422
* All the errors that can generate an IRQ.
423
*/
424
kDifSpiHostIrqErrorAll
= (1 << 5) - 1,
425
/**
426
* All the errors above together.
427
*/
428
kDifSpiHostErrorAll
= (1 << 6) - 1,
429
} dif_spi_host_error_code_t;
430
431
/**
432
* Bitmask with the `dif_spi_host_error_code_t` values.
433
*/
434
typedef
uint32_t
dif_spi_host_errors_t
;
435
436
/**
437
* Set the enable state of the spi host errors.
438
*
439
* @param spi_host A SPI Host handle.
440
* @param errors A bitmask with the errors to be enabled or disabled.
441
* @param enable True to enable the `events` or false to disable.
442
* @return The result of the operation.
443
*/
444
OT_WARN_UNUSED_RESULT
445
dif_result_t
dif_spi_host_error_set_enabled
(
const
dif_spi_host_t
*spi_host,
446
dif_spi_host_errors_t
errors,
447
bool
enable);
448
449
/**
450
* Get the enabled errors.
451
*
452
* @param spi_host A SPI Host handle.
453
* @param[out] errors A bitmask that will contain all the errors that are
454
* enabled.
455
* @return The result of the operation.
456
*/
457
OT_WARN_UNUSED_RESULT
458
dif_result_t
dif_spi_host_error_get_enabled
(
const
dif_spi_host_t
*spi_host,
459
dif_spi_host_errors_t
*errors);
460
461
/**
462
* Read the current error status of the spi host.
463
*
464
* @param spi_host A SPI Host handle.
465
* @param[out] errors The error status of the spi.
466
* @return The result of the operation.
467
*/
468
OT_WARN_UNUSED_RESULT
469
dif_result_t
dif_spi_host_get_error
(
const
dif_spi_host_t
*spi_host,
470
dif_spi_host_errors_t
*errors);
471
472
/**
473
* Wait until the SPI Host is idle.
474
*
475
* @param spi_host A SPI Host handle.
476
* @return The result of the operation.
477
*/
478
OT_WARN_UNUSED_RESULT
479
dif_result_t
dif_spi_host_wait_until_idle
(
const
dif_spi_host_t
*spi_host);
480
481
#ifdef __cplusplus
482
}
// extern "C"
483
#endif
// __cplusplus
484
485
#endif
// OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
sw
device
lib
dif
dif_spi_host.h
Return to
OpenTitan Documentation