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
18extern "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 */
27typedef struct dif_spi_host_config {
28 /** Desired SPI clock frequency (SCK). */
29 uint32_t spi_clock;
30 /** Peripheral clock frequency (ie: kClockFreqPeripheralHz). */
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. */
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). */
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). */
53
54/**
55 * Width of SPI operations.
56 */
57typedef enum dif_spi_host_width {
58 /** Standard SPI mode (single lanes for send and recv). */
60 /** Dual SPI mode (use two lanes for send and recv). */
62 /** Quad SPI mode (use four lanes for send and recv). */
65
66/**
67 * Direction of SPI operations.
68 *
69 * This describes which direction a given SPI operation will use.
70 */
72 /** The SPI host neither transmits or receives. */
74 /** The SPI host receives data. */
76 /** The SPI host transmits data. */
78 /** The SPI host transmits and receives data. */
81
82/**
83 * Segment types for segments in a transaction.
84 */
86 /** The segment is a SPI opcode. */
88 /** The segment is a SPI address. */
90 /** The segment is a SPI dummy cycle. */
92 /** The segment is a SPI transmit (from a memory buffer). */
94 /** The segment is a SPI receive (into a memory buffer). */
96 /** The segment is a simultaneous transmit and receieve. */
99
100/**
101 * Address mode for the address segment in a transaction.
102 */
104 /** The address is a 3-byte address. */
106 /** The address is a 4-byte address. */
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 */
116typedef struct dif_spi_host_segment {
117 /** The segment type for this segment. */
119 union {
120 struct {
122 uint8_t opcode;
123 } opcode;
124 struct {
127 uint32_t address;
128 } address;
129 struct {
131 size_t length;
132 } dummy;
133 struct {
135 const void *buf;
136 size_t length;
137 } tx;
138 struct {
140 void *buf;
141 size_t length;
142 } rx;
143 struct {
145 const void *txbuf;
146 void *rxbuf;
147 size_t length;
148 } bidir;
149 };
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 */
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 */
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 */
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 */
198dif_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 */
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 */
227 uint32_t csid,
228 dif_spi_host_segment_t *segments,
229 size_t length);
230
232 /**
233 * Enable IRQ to be fired when `STATUS.RXFULL` goes high.
234 */
236 /**
237 * Enable IRQ to be fired when `STATUS.TXEMPTY` goes high.
238 */
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 */
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 */
250 /**
251 * Enable IRQ to be fired when `STATUS.READY` goes high.
252 */
254 /**
255 * Enable IRQ to be fired when `STATUS.ACTIVE` goes low.
256 */
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 */
267typedef 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 */
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 */
292 dif_spi_host_events_t *events);
293
294typedef 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 */
307 /**
308 * Indicates that the transmit data fifo is empty.
309 */
311 /**
312 * If true, signifies that an ongoing transaction has stalled due to lack of
313 * data in the`TX FIFO`.
314 */
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 */
321 /**
322 * Indicates that the receive fifo is full. Any ongoing transactions will
323 * stall until firmware reads some data from `RXDATA`.
324 */
326 /**
327 * Indicates that the receive fifo is empty. Any reads from `RX FIFO` will
328 * cause an error interrupt.
329 */
331 /**
332 * If true, signifies that an ongoing transaction has stalled due to lack of
333 * available space in the `RX FIFO`.
334 */
336 /**
337 * If true the least significant bits will be transmitted first.
338 */
340 /**
341 * If true, the number of 32-bits in the `RX FIFO` now exceeds the
342 * `CONTROL.RX_WATERMARK`entries (32b each).
343 */
345 /**
346 * Indicates how many unread 32-bit words are currently in the command
347 * segment queue.
348 */
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 */
356 /**
357 * Indicates how many unsent 32-bit words are currently in the`TX FIFO`.
358 */
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 */
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 */
387 uint16_t length,
389 dif_spi_host_direction_t direction,
390 bool last_segment);
391
393 /**
394 * Indicates a write to `COMMAND` when `STATUS.READY = 0`.
395 */
397 /**
398 * Indicates that firmware has overflowed the `TX FIFO`.
399 */
401 /**
402 * Indicates that firmware has attempted to read from `RXDATA` when the `RX
403 * FIFO` is empty.
404 */
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 */
412 /**
413 * Indicates a command was attempted with an invalid value for `CSID`.
414 */
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 */
422 /**
423 * All the errors that can generate an IRQ.
424 */
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 */
435typedef 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 */
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 */
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 */
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 */
481
482#ifdef __cplusplus
483} // extern "C"
484#endif // __cplusplus
485
486#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_