Software APIs
dif_i2c.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_I2C_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_I2C_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/i2c/doc/">I2C</a> Device Interface Functions
11  */
12 
13 #include <stdbool.h>
14 #include <stdint.h>
15 
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * A toggle state: enabled, or disabled.
25  *
26  * This enum may be used instead of a `bool` when describing an enabled/disabled
27  * state.
28  */
29 typedef enum dif_i2c_toggle {
30  /*
31  * The "enabled" state.
32  */
33  kDifI2cToggleEnabled,
34  /**
35  * The "disabled" state.
36  */
39 
40 /**
41  * Represents a speed setting for an I2C component: standard, fast, and
42  * fast plus, corresponding to 100 kbaud, 400 kbaud, and 1 Mbaud,
43  * respectively.
44  */
45 typedef enum dif_i2c_speed {
46  /**
47  * Standard speed, 100 kilobaud.
48  */
50  /**
51  * Fast speed, 400 kilobaud.
52  */
54  /**
55  * Fast plus speed, 1 megabaud.
56  */
59 
60 /**
61  * Timing configuration parameters for I2C.
62  *
63  * While the I2C device requires ten parameters to describe its timing
64  * configuration, the degrees of freedom of those parameters is constrained to
65  * the ones in this struct.
66  *
67  * See `dif_i2c_compute_timing()`
68  */
69 typedef struct dif_i2c_timing_config {
70  /**
71  * The lowest speed at which an I2C target connected to this host will
72  * operate.
73  *
74  * In other words, this is the maximum speed at which the host can operate
75  * without going over what the target devices can handle.
76  */
77  dif_i2c_speed_t lowest_target_device_speed;
78  /**
79  * The period of the clock driving this device, in nanoseconds.
80  *
81  * This value should not be zero, since it is used as a divisor for
82  * division.
83  */
85  /**
86  * The expected time it takes for the I2C bus signal to rise, in nanoseconds.
87  *
88  * This value is dependent on properties of the hardware's interconnect, and
89  * not under actual firmware control.
90  */
91  uint32_t sda_rise_nanos;
92  /**
93  * The expected time for the bus signal to fall, similar to `sda_rise_nanos`.
94  */
95  uint32_t sda_fall_nanos;
96  /**
97  * The desired period of the SCL line, in nanoseconds.
98  *
99  * Normally, this should just be `1'000'000 / lowest_target_device_speed`,
100  * but the period may be larger if desired.
101  *
102  * Setting this value to zero will result in the minimum period being used.
103  */
106 
107 /**
108  * Hardware instantiation parameters for I2C.
109  *
110  * This struct describes information about the underlying hardware that is
111  * not determined until the hardware design is used as part of a top-level
112  * design.
113  */
114 typedef struct dif_i2c_params {
115  /**
116  * The base address for the I2C hardware registers.
117  */
120 
121 /**
122  * Runtime configuration for I2C.
123  *
124  * This struct describes runtime timing parameters. Computing these values is
125  * somewhat complicated, so these fields should be initialized using the
126  * `dif_i2c_compute_timing()` function. A caller is, however, free to compute
127  * these values themselves if they prefer, so long as the I2C spec is
128  * respected.
129  *
130  * These values correspond to those in Table 10 of the I2C spec, and are given
131  * in units of input clock cycles.
132  */
133 typedef struct dif_i2c_config {
134  uint16_t scl_time_high_cycles;
135  uint16_t scl_time_low_cycles;
136  uint16_t rise_cycles;
137  uint16_t fall_cycles;
138  uint16_t start_signal_setup_cycles;
139  uint16_t start_signal_hold_cycles;
140  uint16_t data_signal_setup_cycles;
141  uint16_t data_signal_hold_cycles;
142  uint16_t stop_signal_setup_cycles;
143  /**
144  * This parameter is referred to in the I2C documents as the
145  * "bus free time".
146  */
149 
150 /**
151  * A handle to I2C.
152  *
153  * This type should be treated as opaque by users.
154  */
155 typedef struct dif_i2c { dif_i2c_params_t params; } dif_i2c_t;
156 
157 /**
158  * The result of a I2C operation.
159  */
160 typedef enum dif_i2c_result {
161  /**
162  * Indicates that the operation succeeded.
163  */
165  /**
166  * Indicates some unspecified failure.
167  */
169  /**
170  * Indicates that some parameter passed into a function failed a
171  * precondition.
172  *
173  * When this value is returned, no hardware operations occurred.
174  */
177 
178 /**
179  * Represents an I2C-related interrupt type.
180  */
181 typedef enum dif_i2c_irq {
182  /**
183  * Fired when the FMT FIFO underflows its watermark.
184  */
186  /**
187  * Fired when the RX FIFO overflows its watermark.
188  */
190  /**
191  * Fired when the FMT FIFO overflows.
192  */
194  /**
195  * Fired when the RX FIFO overflows.
196  */
198  /**
199  * Fired when there is no ACK in response to an address or data write.
200  */
202  /**
203  * Fired when the SCL line seems to have interference.
204  */
206  /**
207  * Fired when the SDA line seems to have interference.
208  */
210  /**
211  * Fired when the target stretches the clock beyond the allowed period.
212  */
214  /**
215  * Fired when the target does not maintain a stable SDA line.
216  */
218 } dif_i2c_irq_t;
219 
220 /**
221  * A snapshot of the entablement state of the interrupts for I2C.
222  *
223  * This is an opaque type, to be used with the `dif_i2c_irq_disable_all()` and
224  * `dif_i2c_irq_restore_all()` functions.
225  */
226 typedef uint32_t dif_i2c_irq_snapshot_t;
227 
228 /**
229  * Represents a valid watermark level for one of the I2C FIFOs.
230  */
232  /**
233  * A one-byte watermark.
234  */
236  /**
237  * A four-byte watermark.
238  */
240  /**
241  * An eight-byte watermark.
242  */
244  /**
245  * A sixteen-byte watermark.
246  */
248  /**
249  * A thirty-byte watermark.
250  *
251  * Note that this watermark is only supported for RX, and not for FMT.
252  */
255 
256 /**
257  * Flags for a formatted I2C byte, used by the `dif_i2c_write_byte_raw()`
258  * function.
259  */
260 typedef struct dif_i2c_fmt_flags {
261  /**
262  * Causes a start signal to be sent before the byte.
263  *
264  * If a start has been issued during the current transaction, this will issue
265  * a repeated start.
266  */
267  bool start;
268  /**
269  * Causes a stop signal to be sent after the byte.
270  *
271  * This flag cannot be set when both `read` and `read_cont` are set.
272  */
273  bool stop;
274  /**
275  * Causes the byte to be interpreted as an unsigned number of bytes to read
276  * from the target; 0 is interpreted as 256.
277  */
278  bool read;
279  /**
280  * Requires `read` to be set; if so, once the final byte associated with this
281  * read is received, it will be acknowledged, allowing the read operation to
282  * continue.
283  */
284  bool read_cont;
285  /**
286  * By default, the hardware expects an ACK after every byte sent, and raises
287  * an exception (surfaced as the `kDifi2cIrqNak` interrupt). This flag
288  * disables that behavior.
289  *
290  * This flag cannot be set along with `read` or `read_cont`.
291  */
294 
295 /**
296  * Available formatting codes for `dif_i2c_write_byte_raw()`.
297  *
298  * Each code describes how to interpret the `byte` parameter, referred to below
299  * as "the byte".
300  *
301  * It is the caller's responsibility to observe the state transitions in the
302  * comments below.
303  */
304 typedef enum dif_i2c_fmt {
305  /**
306  * Start a transaction. This sends a START signal followed by the byte.
307  * The byte sent will form (potentially part of) the target address for the
308  * transaction.
309  *
310  * May be followed by any format code.
311  */
313  /**
314  * Transmit byte. This simply sends the byte. It may need to be used in
315  * conjunction with `Start` to send a multi-byte target address.
316  *
317  * May be followed by any format code.
318  */
320  /**
321  * Transmit byte and stop. This sends the byte, and then sends a stop
322  * signal, completing a transaction.
323  *
324  * Only `Start` may follow this code.
325  */
327  /**
328  * Request `n` bytes, where `n` is the byte interpreted as an unsigned
329  * integer; a byte value of `0` will be interpreted as requesting `256`
330  * bytes. This will NAK the last byte.
331  *
332  * Only `Start` may follow this code (this code does not stop a transaction;
333  * see `RxStop`).
334  */
336  /**
337  * Request `n` bytes, same as `Rx`, but ACK the last byte so that more data
338  * can be requested.
339  *
340  * May be followed by `RxContinue`, `Rx`, or `RxStop`.
341  */
343  /**
344  * Request `n` bytes, same as `Rx`, but, after NAKing the last byte, send a
345  * stop signal to end the transaction.
346  *
347  * Only `Start` may follow this code.
348  */
350 } dif_i2c_fmt_t;
351 
352 /**
353  * Computes timing parameters for an I2C device and stores them in `config`.
354  *
355  * The values returned may be tweaked by callers that require finer control over
356  * some of the calculations, such as how the allocation of a lengthened SCL
357  * period.
358  *
359  * @param timing_config Configuration values for producing timing parameters.
360  * @param[out] config I2C configuration to which to apply the computed
361  * parameters.
362  * @return The result of the operation.
363  */
366  dif_i2c_config_t *config);
367 /**
368  * Creates a new handle for I2C.
369  *
370  * This function does not actuate the hardware.
371  *
372  * @param params Hardware instantiation parameters.
373  * @param[out] i2c Out param for the initialized handle.
374  * @return The result of the operation.
375  */
378 
379 /**
380  * Configures I2C with runtime information.
381  *
382  * This function should need to be called once for the lifetime of `handle`.
383  *
384  * @param i2c An I2C handle.
385  * @param config Runtime configuration parameters.
386  * @return The result of the operation.
387  */
390  dif_i2c_config_t config);
391 
392 /**
393  * Returns whether a particular interrupt is currently pending.
394  *
395  * @param i2c An I2C handle.
396  * @param irq An interrupt type.
397  * @param[out] is_pending Out-param for whether the interrupt is pending.
398  * @return The result of the operation.
399  */
401 dif_i2c_result_t dif_i2c_irq_is_pending(const dif_i2c_t *i2c, dif_i2c_irq_t irq,
402  bool *is_pending);
403 
404 /**
405  * Acknowledges a particular interrupt, indicating to the hardware that it has
406  * been successfully serviced.
407  *
408  * @param i2c An I2C handle.
409  * @param irq An interrupt type.
410  * @return The result of the operation.
411  */
414  dif_i2c_irq_t irq);
415 
416 /**
417  * Checks whether a particular interrupt is currently enabled or disabled.
418  *
419  * @param i2c An I2C handle.
420  * @param irq An interrupt type.
421  * @param[out] state Out-param toggle state of the interrupt.
422  * @return The result of the operation.
423  */
426  dif_i2c_irq_t irq,
427  dif_i2c_toggle_t *state);
428 
429 /**
430  * Sets whether a particular interrupt is currently enabled or disabled.
431  *
432  * @param i2c An I2C handle.
433  * @param irq An interrupt type.
434  * @param state The new toggle state for the interrupt.
435  * @return The result of the operation.
436  */
439  dif_i2c_irq_t irq,
440  dif_i2c_toggle_t state);
441 
442 /**
443  * Forces a particular interrupt, causing it to be serviced as if hardware had
444  * asserted it.
445  *
446  * @param i2c An I2C handle.
447  * @param irq An interrupt type.
448  * @return The result of the operation.
449  */
451 dif_i2c_result_t dif_i2c_irq_force(const dif_i2c_t *i2c, dif_i2c_irq_t irq);
452 
453 /**
454  * Disables all interrupts, optionally snapshotting all toggle state for later
455  * restoration.
456  *
457  * @param i2c An I2C handle.
458  * @param[out] snapshot Out-param for the snapshot; may be `NULL`.
459  * @return The result of the operation.
460  */
463  dif_i2c_irq_snapshot_t *snapshot);
464 
465 /**
466  * Restores interrupts from the given snapshot.
467  *
468  * This function can be used with `dif_i2c_irq_disable_all()` to temporary
469  * interrupt save-and-restore.
470  *
471  * @param i2c An I2C handle.
472  * @param snapshot A snapshot to restore from.
473  * @return The result of the operation.
474  */
477  const dif_i2c_t *i2c, const dif_i2c_irq_snapshot_t *snapshot);
478 
479 /**
480  * Resets the state of the RX FIFO, essentially dropping all received bytes.
481  *
482  * @param i2c An I2c handle.
483  * @return The result of the operation.
484  */
487 
488 /**
489  * Resets the state of the FMT FIFO, essentially dropping all scheduled
490  * operations.
491  *
492  * @param i2c An I2c handle.
493  * @return The result of the operation.
494  */
497 
498 /**
499  * Sets watermarks for for the RX and FMT FIFOs, which will fire the respective
500  * interrupts when each fifo exceeds, or falls below, the set level.
501  *
502  * Note that the 30-byte level is only supported for the RX FIFO: trying to use
503  * it with the FMT FIFO is an error.
504  *
505  * @param i2c An I2C handle.
506  * @param rx_level The desired watermark level for the RX FIFO.
507  * @param fmt_level The desired watermark level for the FMT FIFO.
508  * @return The result of the operation.
509  */
512  dif_i2c_level_t rx_level,
513  dif_i2c_level_t fmt_level);
514 
515 /**
516  * Enables or disables the "Host I2C" functionality, effectively turning the
517  * I2C device on or off. This function should be called to enable the device
518  * once timings, interrupts, and watermarks are all configured.
519  *
520  * @param i2c An I2C handle.
521  * @param state The new toggle state for the host functionality.
522  * @return The result of the operation.
523  */
526  dif_i2c_toggle_t state);
527 
528 /**
529  * Enables or disables the "override mode". In override mode, software is able
530  * to directly control the driven values of the SCL and SDA lines using
531  * `dif_i2c_override_drive_pins()`.
532  *
533  * @param i2c An I2C handle.
534  * @param state The new toggle state for override mode.'
535  * @return The result of the operation.
536  */
539  dif_i2c_toggle_t state);
540 
541 /**
542  * Drives the SCL and SDA pins to the given values when "override mode" is
543  * enabled.
544  *
545  * @param i2c An I2C handle.
546  * @param scl The value to drive SCL to.
547  * @param sda The value to drive SDA to.
548  * @return The result of the operation.
549  */
552  bool sda);
553 
554 /**
555  * Returns oversampling of the last 16 values of the SCL and SDA pins, with the
556  * zeroth bit being the most recent.
557  *
558  * @param i2c An I2C handle.
559  * @param[out] scl_samples SCL sample bits; may be `NULL`.
560  * @param[out] sda_samples SDA sample bits; may be `NULL`.
561  * @return The result of the operation.
562  */
565  uint16_t *scl_samples,
566  uint16_t *sda_samples);
567 
568 /**
569  * Returns the current levels, i.e., number of entries, in the FMT and RX FIFOs.
570  * These values represent the number of entries pending for send by hardware,
571  * and entries pending for read by software, respectively.
572  *
573  * @param i2c An I2C handle.
574  * @param[out] fmt_fifo_level The number of unsent FMT bytes; may be `NULL`.
575  * @param[out] rx_fifo_level The number of unread RX bytes; may be `NULL`.
576  * @return The result of the operation.
577  */
580  uint8_t *fmt_fifo_level,
581  uint8_t *rx_fifo_level);
582 
583 /**
584  * Pops an entry (a byte) off of the RX FIFO. Passing in `NULL` to the out-param
585  * will still trigger a byte pop.
586  *
587  * @param i2c An I2C handle.
588  * @param[out] byte The popped byte; may be `NULL`.
589  * @return The result of the operation.
590  */
592 dif_i2c_result_t dif_i2c_read_byte(const dif_i2c_t *i2c, uint8_t *byte);
593 
594 /**
595  * Pushes a raw write entry onto the FMT FIFO, consisting of a byte and format
596  * flags. This function can be called in sequence to enqueue an I2C
597  * transmission.
598  *
599  * Callers should prefer `dif_i2c_write_byte()` instead, since that function
600  * provides clearer semantics. This function should only really be used for
601  * testing or troubleshooting a device.
602  *
603  * @param i2c An I2C handle.
604  * @param byte The value to push onto the FIFO.
605  * @param flags The flags to use for this write.
606  * @return The result of the operation.
607  */
609 dif_i2c_result_t dif_i2c_write_byte_raw(const dif_i2c_t *i2c, uint8_t byte,
610  dif_i2c_fmt_flags_t flags);
611 
612 /**
613  * Pushes a write entry onto the FMT FIFO, consisting of a byte and a format
614  * code. This function can be called in sequence to enqueue an I2C
615  * transmission.
616  *
617  * @param i2c An I2C handle.
618  * @param byte The value to push onto the FIFO.
619  * @param code The code to use for this write.
620  * @param suppress_nak_irq Whether to supress the NAK IRQ for this one byte.
621  * May not be used in combination with `Rx` codes.
622  * @return The result of the operation.
623  */
625 dif_i2c_result_t dif_i2c_write_byte(const dif_i2c_t *i2c, uint8_t byte,
626  dif_i2c_fmt_t code, bool suppress_nak_irq);
627 
628 #ifdef __cplusplus
629 } // extern "C"
630 #endif // __cplusplus
631 
632 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_I2C_H_