Software APIs
dif_spi_device.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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_DEVICE_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_DEVICE_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/spi_device/doc/">SPI Device</a> Device Interface
11  * Functions
12  */
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif // __cplusplus
23 
24 /**
25  * A signal edge type: positive or negative.
26  */
27 typedef enum dif_spi_device_edge {
28  /**
29  * Represents a positive edge (i.e., from low to high).
30  */
32  /**
33  * Represents a negative edge (i.e., from high to low).
34  */
37 
38 /**
39  * A bit ordering within a byte.
40  */
42  /**
43  * Represents the most-significant-bit to least-significant-bit order.
44  */
46  /**
47  * Represents the least-significant-bit to most-significant-bit order.
48  */
51 
52 /**
53  * A toggle state: enabled, or disabled.
54  *
55  * This enum may be used instead of a `bool` when describing an enabled/disabled
56  * state.
57  */
58 typedef enum dif_spi_device_toggle {
59  /*
60  * The "enabled" state.
61  */
62  kDifSpiDeviceToggleEnabled,
63  /**
64  * The "disabled" state.
65  */
68 
69 /**
70  * Hardware instantiation parameters for SPI.
71  *
72  * This struct describes information about the underlying hardware that is
73  * not determined until the hardware design is used as part of a top-level
74  * design.
75  */
76 typedef struct dif_spi_device_params {
77  /**
78  * The base address for the SPI hardware registers.
79  */
82 
83 /**
84  * Runtime configuration for SPI.
85  *
86  * This struct describes runtime information for one-time configuration of the
87  * hardware.
88  */
89 typedef struct dif_spi_device_config {
90  dif_spi_device_edge_t clock_polarity;
91  dif_spi_device_edge_t data_phase;
92  dif_spi_device_bit_order_t tx_order;
93  dif_spi_device_bit_order_t rx_order;
94  uint8_t rx_fifo_timeout;
95  /**
96  * The length, in bytes, that should be reserved for the RX FIFO.
97  *
98  * `kDifSpiDeviceBufferLen / 2` is a good default for this value.
99  */
100  uint16_t rx_fifo_len;
101  /**
102  * The length, in bytes, that should be reserved for the TX FIFO.
103  *
104  * `kDifSpiDeviceBufferLen / 2` is a good default for this value.
105  */
106  uint16_t tx_fifo_len;
108 
109 /**
110  * A handle to a SPI device.
111  *
112  * This type should be treated as opaque by users.
113  */
114 typedef struct dif_spi_device {
116  uint16_t rx_fifo_len;
117  uint16_t tx_fifo_len;
119 
120 /**
121  * The result of a SPI operation.
122  */
123 typedef enum dif_spi_device_result {
124  /**
125  * Indicates that the operation succeeded.
126  */
128  /**
129  * Indicates some unspecified failure.
130  */
132  /**
133  * Indicates that some parameter passed into a function failed a
134  * precondition.
135  *
136  * When this value is returned, no hardware operations occurred.
137  */
140 
141 /**
142  * A SPI interrupt request type.
143  */
144 typedef enum dif_spi_device_irq {
145  /**
146  * Indicates that the RX FIFO is full.
147  */
149  /**
150  * Indicates that the RX FIFO is above the configured level.
151  */
153  /**
154  * Indicates that the TX FIFO is below the configured level.
155  */
157  /**
158  * Indicates an error in the RX FIFO.
159  */
161  /**
162  * Indicates that overflow has occurred in the RX FIFO.
163  */
165  /**
166  * Indicates that underflow has occurred in the RX FIFO.
167  */
170 
171 /**
172  * A snapshot of the enablement state of the interrupts for SPI.
173  *
174  * This is an opaque type, to be used with the
175  * `dif_spi_device_irq_disable_all()` and
176  * `dif_spi_device_irq_restore_all()` functions.
177  */
179 
180 /**
181  * The length of the SPI device FIFO buffer, in bytes.
182  *
183  * Useful for initializing FIFO lengths: for example, for equally-sized FIFOs,
184  * `rx_fifo_len` and `tx_fifo_len` would be set to `kDifSpiDeviceBufferLen / 2`.
185  */
186 extern const uint16_t kDifSpiDeviceBufferLen;
187 
188 /**
189  * Creates a new handle for SPI.
190  *
191  * This function does not actuate the hardware.
192  *
193  * @param params Hardware instantiation parameters.
194  * @param[out] spi Out param for the initialized handle.
195  * @return The result of the operation.
196  */
199  dif_spi_device_t *spi);
200 
201 /**
202  * Configures SPI with runtime information.
203  *
204  * This function should need to be called once for the lifetime of `handle`.
205  *
206  * @param spi A SPI handle.
207  * @param config Runtime configuration parameters.
208  * @return The result of the operation.
209  */
213 
214 /**
215  * Issues an "abort" to the given SPI device, causing all in-progress IO to
216  * halt.
217  *
218  * @param spi A SPI handle.
219  * @return The result of the operation.
220  */
223 
224 /**
225  * Returns whether a particular interrupt is currently pending.
226  *
227  * @param spi A SPI handle.
228  * @param irq An interrupt type.
229  * @param[out] is_pending Out-param for whether the interrupt is pending.
230  * @return The result of the operation.
231  */
234  const dif_spi_device_t *spi, dif_spi_device_irq_t irq, bool *is_pending);
235 
236 /**
237  * Acknowledges a particular interrupt, indicating to the hardware that it has
238  * been successfully serviced.
239  *
240  * @param spi A SPI handle.
241  * @param irq An interrupt type.
242  * @return The result of the operation.
243  */
246  const dif_spi_device_t *spi, dif_spi_device_irq_t irq);
247 
248 /**
249  * Checks whether a particular interrupt is currently enabled or disabled.
250  *
251  * @param spi A SPI handle.
252  * @param irq An interrupt type.
253  * @param[out] state Out-param toggle state of the interrupt.
254  * @return The result of the operation.
255  */
258  const dif_spi_device_t *spi, dif_spi_device_irq_t irq,
259  dif_spi_device_toggle_t *state);
260 
261 /**
262  * Sets whether a particular interrupt is currently enabled or disabled.
263  *
264  * @param spi A SPI handle.
265  * @param irq An interrupt type.
266  * @param state The new toggle state for the interrupt.
267  * @return The result of the operation.
268  */
271  const dif_spi_device_t *spi, dif_spi_device_irq_t irq,
272  dif_spi_device_toggle_t state);
273 
274 /**
275  * Forces a particular interrupt, causing it to be serviced as if hardware had
276  * asserted it.
277  *
278  * @param spi A SPI handle.
279  * @param irq An interrupt type.
280  * @return The result of the operation.
281  */
284  dif_spi_device_irq_t irq);
285 
286 /**
287  * Disables all interrupts, optionally snapshotting all toggle state for later
288  * restoration.
289  *
290  * @param spi A SPI handle.
291  * @param[out] snapshot Out-param for the snapshot; may be `NULL`.
292  * @return The result of the operation.
293  */
296  const dif_spi_device_t *spi, dif_spi_device_irq_snapshot_t *snapshot);
297 
298 /**
299  * Restores interrupts from the given snapshot.
300  *
301  * This function can be used with `dif_spi_device_irq_disable_all()` to
302  * temporary
303  * interrupt save-and-restore.
304  *
305  * @param spi A SPI handle.
306  * @param snapshot A snapshot to restore from.
307  * @return The result of the operation.
308  */
311  const dif_spi_device_t *spi, const dif_spi_device_irq_snapshot_t *snapshot);
312 
313 /**
314  * Sets up the "FIFO level" (that is, number of bytes present in a particular
315  * FIFO) at which the TxLevel and RxLevel IRQs will fire.
316  *
317  * For the reciept side, when the FIFO overflows `rx_level` (i.e., goes over
318  * the set level), an interrupt is fired. This can be used to detect that more
319  * data should be read from the RX FIFO. This is the
320  * `Spi Buffer -> Main Memory` case.
321  *
322  * Conversely, for the transmission side, when the FIFO underflows `tx_level`
323  * (i.e., goes below the set level), an interrupt is fired. This can be used
324  * to detect that there is free space to write more data to the TX FIFO.
325  * This is the `Main Memory -> Spi Buffer` case.
326  *
327  * @param spi A SPI handle.
328  * @param rx_level The new RX level, as described above.
329  * @param tx_level The new TX level, as described above.
330  * @return The result of the operation.
331  */
334  const dif_spi_device_t *spi, uint16_t rx_level, uint16_t tx_level);
335 
336 /**
337  * Returns the number of bytes still pending receipt by software in the RX FIFO.
338  *
339  * @param spi A SPI handle.
340  * @param[out] bytes_pending The number of bytes pending
341  * @return The result of the operation.
342  */
345  size_t *bytes_pending);
346 
347 /**
348  * Returns the number of bytes still pending transmission by hardware in the TX
349  * FIFO.
350  *
351  * @param spi A SPI handle.
352  * @param[out] bytes_pending The number of bytes pending
353  * @return The result of the operation.
354  */
357  size_t *bytes_pending);
358 
359 /**
360  * Reads at most `buf_len` bytes from the RX FIFO; the number of bytes read
361  * will be written to `bytes_received`.
362  *
363  * @param spi A SPI device.
364  * @param[out] buf A pointer to valid memory.
365  * @param buf_len The length of the buffer `buf` points to.
366  * @param[out] bytes_received The number of bytes successfully read; may be
367  * null.
368  * @return The result of the operation.
369  */
372  void *buf, size_t buf_len,
373  size_t *bytes_received);
374 
375 /**
376  * Writes at most `buf_len` bytes to the TX FIFO; the number of bytes actually
377  * written will be written to `bytes_sent`.
378  *
379  * @param spi A SPI device.
380  * @param buf A pointer to bytes to be written.
381  * @param buf_len The length of the buffer `buf` points to.
382  * @param[out] bytes_sent The number of bytes successfully written; may be null.
383  * @return The result of the operation.
384  */
387  const void *buf, size_t buf_len,
388  size_t *bytes_sent);
389 
390 #ifdef __cplusplus
391 } // extern "C"
392 #endif // __cplusplus
393 
394 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_DEVICE_H_