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 
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). */
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;
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). */
59  /** Dual SPI mode (use two lanes for send and recv). */
61  /** Quad SPI mode (use four lanes for send and recv). */
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. */
73  /** The SPI host receives data. */
75  /** The SPI host transmits data. */
77  /** The SPI host transmits and receives data. */
80 
81 /**
82  * Segment types for segments in a transaction.
83  */
85  /** The segment is a SPI opcode. */
87  /** The segment is a SPI address. */
89  /** The segment is a SPI dummy cycle. */
91  /** The segment is a SPI transmit (from a memory buffer). */
93  /** The segment is a SPI receive (into a memory buffer). */
95  /** The segment is a simultaneous transmit and receieve. */
98 
99 /**
100  * Address mode for the address segment in a transaction.
101  */
103  /** The address is a 3-byte address. */
105  /** The address is a 4-byte address. */
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. */
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;
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  };
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  */
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  */
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  */
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  */
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  */
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  */
220  /**
221  * Enable IRQ to be fired when `STATUS.TXEMPTY` goes high.
222  */
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  */
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  */
234  /**
235  * Enable IRQ to be fired when `STATUS.READY` goes high.
236  */
238  /**
239  * Enable IRQ to be fired when `STATUS.ACTIVE` goes low.
240  */
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  */
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  */
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  */
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  */
324  /**
325  * If true, the number of 32-bits in the `RX FIFO` now exceeds the
326  * `CONTROL.RX_WATERMARK`entries (32b each).
327  */
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;
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  */
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  */
371  uint16_t length,
372  dif_spi_host_width_t speed,
373  dif_spi_host_direction_t direction,
374  bool last_segment);
375 
377  /**
378  * Indicates a write to `COMMAND` when `STATUS.READY = 0`.
379  */
381  /**
382  * Indicates that firmware has overflowed the `TX FIFO`.
383  */
385  /**
386  * Indicates that firmware has attempted to read from `RXDATA` when the `RX
387  * FIFO` is empty.
388  */
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  */
396  /**
397  * Indicates a command was attempted with an invalid value for `CSID`.
398  */
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  */
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  */
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  */
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  */
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  */
465 
466 #ifdef __cplusplus
467 } // extern "C"
468 #endif // __cplusplus
469 
470 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_