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
17extern "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 */
26typedef 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. */
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). */
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). */
52
53/**
54 * Width of SPI operations.
55 */
56typedef 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 */
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 */
115typedef struct dif_spi_host_segment {
116 /** The segment type for this segment. */
118 union {
119 struct {
121 uint8_t opcode;
122 } opcode;
123 struct {
126 uint32_t address;
127 } address;
128 struct {
130 size_t length;
131 } dummy;
132 struct {
134 const void *buf;
135 size_t length;
136 } tx;
137 struct {
139 void *buf;
140 size_t length;
141 } rx;
142 struct {
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 */
197dif_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 */
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 */
226 uint32_t csid,
227 dif_spi_host_segment_t *segments,
228 size_t length);
229
231 /**
232 * Enable IRQ to be fired when `STATUS.RXFULL` goes high.
233 */
235 /**
236 * Enable IRQ to be fired when `STATUS.TXEMPTY` goes high.
237 */
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 */
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 */
249 /**
250 * Enable IRQ to be fired when `STATUS.READY` goes high.
251 */
253 /**
254 * Enable IRQ to be fired when `STATUS.ACTIVE` goes low.
255 */
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 */
266typedef 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 */
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 */
291 dif_spi_host_events_t *events);
292
293typedef 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 */
306 /**
307 * Indicates that the transmit data fifo is empty.
308 */
310 /**
311 * If true, signifies that an ongoing transaction has stalled due to lack of
312 * data in the`TX FIFO`.
313 */
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 */
320 /**
321 * Indicates that the receive fifo is full. Any ongoing transactions will
322 * stall until firmware reads some data from `RXDATA`.
323 */
325 /**
326 * Indicates that the receive fifo is empty. Any reads from `RX FIFO` will
327 * cause an error interrupt.
328 */
330 /**
331 * If true, signifies that an ongoing transaction has stalled due to lack of
332 * available space in the `RX FIFO`.
333 */
335 /**
336 * If true the least significant bits will be transmitted first.
337 */
339 /**
340 * If true, the number of 32-bits in the `RX FIFO` now exceeds the
341 * `CONTROL.RX_WATERMARK`entries (32b each).
342 */
344 /**
345 * Indicates how many unread 32-bit words are currently in the command
346 * segment queue.
347 */
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 */
355 /**
356 * Indicates how many unsent 32-bit words are currently in the`TX FIFO`.
357 */
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 */
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 */
386 uint16_t length,
388 dif_spi_host_direction_t direction,
389 bool last_segment);
390
392 /**
393 * Indicates a write to `COMMAND` when `STATUS.READY = 0`.
394 */
396 /**
397 * Indicates that firmware has overflowed the `TX FIFO`.
398 */
400 /**
401 * Indicates that firmware has attempted to read from `RXDATA` when the `RX
402 * FIFO` is empty.
403 */
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 */
411 /**
412 * Indicates a command was attempted with an invalid value for `CSID`.
413 */
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 */
421 /**
422 * All the errors that can generate an IRQ.
423 */
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 */
434typedef 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 */
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 */
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 */
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 */
480
481#ifdef __cplusplus
482} // extern "C"
483#endif // __cplusplus
484
485#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_