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 
19 
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * Represents a speed setting for an I2C component: standard, fast, and
28  * fast plus, corresponding to 100 kbaud, 400 kbaud, and 1 Mbaud,
29  * respectively.
30  */
31 typedef enum dif_i2c_speed {
32  /**
33  * Standard speed, 100 kilobaud.
34  */
36  /**
37  * Fast speed, 400 kilobaud.
38  */
40  /**
41  * Fast plus speed, 1 megabaud.
42  */
45 
46 /**
47  * Timing configuration parameters for I2C.
48  *
49  * While the I2C device requires ten parameters to describe its timing
50  * configuration, the degrees of freedom of those parameters is constrained to
51  * the ones in this struct.
52  *
53  * See `dif_i2c_compute_timing()`
54  */
55 typedef struct dif_i2c_timing_config {
56  /**
57  * The lowest speed at which an I2C target connected to this host will
58  * operate.
59  *
60  * In other words, this is the maximum speed at which the host can operate
61  * without going over what the target devices can handle.
62  */
63  dif_i2c_speed_t lowest_target_device_speed;
64  /**
65  * The period of the clock driving this device, in nanoseconds.
66  *
67  * This value should not be zero, since it is used as a divisor for
68  * division.
69  */
71  /**
72  * The expected time it takes for the I2C bus signal to rise, in nanoseconds.
73  *
74  * This value is dependent on properties of the hardware's interconnect, and
75  * not under actual firmware control.
76  */
77  uint32_t sda_rise_nanos;
78  /**
79  * The expected time for the bus signal to fall, similar to `sda_rise_nanos`.
80  */
81  uint32_t sda_fall_nanos;
82  /**
83  * The desired period of the SCL line, in nanoseconds.
84  *
85  * Normally, this should just be `1'000'000 / lowest_target_device_speed`,
86  * but the period may be larger if desired.
87  *
88  * Setting this value to zero will result in the minimum period being used.
89  */
90  uint32_t scl_period_nanos;
92 
93 /**
94  * Runtime configuration for I2C.
95  *
96  * This struct describes runtime timing parameters. Computing these values is
97  * somewhat complicated, so these fields should be initialized using the
98  * `dif_i2c_compute_timing()` function. A caller is, however, free to compute
99  * these values themselves if they prefer, so long as the I2C spec is
100  * respected.
101  *
102  * These values correspond to those in Table 10 of the I2C spec, and are given
103  * in units of input clock cycles.
104  */
105 typedef struct dif_i2c_config {
106  uint16_t scl_time_high_cycles;
107  uint16_t scl_time_low_cycles;
108  uint16_t rise_cycles;
109  uint16_t fall_cycles;
110  uint16_t start_signal_setup_cycles;
111  uint16_t start_signal_hold_cycles;
112  uint16_t data_signal_setup_cycles;
113  uint16_t data_signal_hold_cycles;
114  uint16_t stop_signal_setup_cycles;
115  /**
116  * This parameter is referred to in the I2C documents as the
117  * "bus free time".
118  */
121 
122 /**
123  * Represents a valid watermark level for one of the I2C FIFOs.
124  */
126  /**
127  * A one-byte watermark.
128  */
130  /**
131  * A four-byte watermark.
132  */
134  /**
135  * An eight-byte watermark.
136  */
138  /**
139  * A sixteen-byte watermark.
140  */
142  /**
143  * A thirty-byte watermark.
144  *
145  * Note that this watermark is only supported for RX, and not for FMT.
146  */
149 
150 /**
151  * Flags for a formatted I2C byte, used by the `dif_i2c_write_byte_raw()`
152  * function.
153  */
154 typedef struct dif_i2c_fmt_flags {
155  /**
156  * Causes a start signal to be sent before the byte.
157  *
158  * If a start has been issued during the current transaction, this will issue
159  * a repeated start.
160  */
161  bool start;
162  /**
163  * Causes a stop signal to be sent after the byte.
164  *
165  * This flag cannot be set when both `read` and `read_cont` are set.
166  */
167  bool stop;
168  /**
169  * Causes the byte to be interpreted as an unsigned number of bytes to read
170  * from the target; 0 is interpreted as 256.
171  */
172  bool read;
173  /**
174  * Requires `read` to be set; if so, once the final byte associated with this
175  * read is received, it will be acknowledged, allowing the read operation to
176  * continue.
177  */
178  bool read_cont;
179  /**
180  * By default, the hardware expects an ACK after every byte sent, and raises
181  * an exception (surfaced as the `kDifi2cIrqNak` interrupt). This flag
182  * disables that behavior.
183  *
184  * This flag cannot be set along with `read` or `read_cont`.
185  */
188 
189 /**
190  * Available formatting codes for `dif_i2c_write_byte_raw()`.
191  *
192  * Each code describes how to interpret the `byte` parameter, referred to below
193  * as "the byte".
194  *
195  * It is the caller's responsibility to observe the state transitions in the
196  * comments below.
197  */
198 typedef enum dif_i2c_fmt {
199  /**
200  * Start a transaction. This sends a START signal followed by the byte.
201  * The byte sent will form (potentially part of) the target address for the
202  * transaction.
203  *
204  * May be followed by any format code.
205  */
207  /**
208  * Transmit byte. This simply sends the byte. It may need to be used in
209  * conjunction with `Start` to send a multi-byte target address.
210  *
211  * May be followed by any format code.
212  */
214  /**
215  * Transmit byte and stop. This sends the byte, and then sends a stop
216  * signal, completing a transaction.
217  *
218  * Only `Start` may follow this code.
219  */
221  /**
222  * Request `n` bytes, where `n` is the byte interpreted as an unsigned
223  * integer; a byte value of `0` will be interpreted as requesting `256`
224  * bytes. This will NAK the last byte.
225  *
226  * Only `Start` may follow this code (this code does not stop a transaction;
227  * see `RxStop`).
228  */
230  /**
231  * Request `n` bytes, same as `Rx`, but ACK the last byte so that more data
232  * can be requested.
233  *
234  * May be followed by `RxContinue`, `Rx`, or `RxStop`.
235  */
237  /**
238  * Request `n` bytes, same as `Rx`, but, after NAKing the last byte, send a
239  * stop signal to end the transaction.
240  *
241  * Only `Start` may follow this code.
242  */
244 } dif_i2c_fmt_t;
245 
246 /**
247  * Computes timing parameters for an I2C device and stores them in `config`.
248  *
249  * The values returned may be tweaked by callers that require finer control over
250  * some of the calculations, such as how the allocation of a lengthened SCL
251  * period.
252  *
253  * @param timing_config Configuration values for producing timing parameters.
254  * @param[out] config I2C configuration to which to apply the computed
255  * parameters.
256  * @return The result of the operation.
257  */
260  dif_i2c_config_t *config);
261 
262 /**
263  * Configures I2C with runtime information.
264  *
265  * This function should need to be called once for the lifetime of `handle`.
266  *
267  * @param i2c An I2C handle.
268  * @param config Runtime configuration parameters.
269  * @return The result of the operation.
270  */
273 
274 /**
275  * Resets the state of the RX FIFO, essentially dropping all received bytes.
276  *
277  * @param i2c An I2c handle.
278  * @return The result of the operation.
279  */
282 
283 /**
284  * Resets the state of the FMT FIFO, essentially dropping all scheduled
285  * operations.
286  *
287  * @param i2c An I2c handle.
288  * @return The result of the operation.
289  */
292 
293 /**
294  * Sets watermarks for for the RX and FMT FIFOs, which will fire the respective
295  * interrupts when each fifo exceeds, or falls below, the set level.
296  *
297  * Note that the 30-byte level is only supported for the RX FIFO: trying to use
298  * it with the FMT FIFO is an error.
299  *
300  * @param i2c An I2C handle.
301  * @param rx_level The desired watermark level for the RX FIFO.
302  * @param fmt_level The desired watermark level for the FMT FIFO.
303  * @return The result of the operation.
304  */
307  dif_i2c_level_t rx_level,
308  dif_i2c_level_t fmt_level);
309 
310 /**
311  * Enables or disables the "Host I2C" functionality, effectively turning the
312  * I2C device on or off. This function should be called to enable the device
313  * once timings, interrupts, and watermarks are all configured.
314  *
315  * @param i2c An I2C handle.
316  * @param state The new toggle state for the host functionality.
317  * @return The result of the operation.
318  */
321 
322 /**
323  * Enables or disables the "override mode". In override mode, software is able
324  * to directly control the driven values of the SCL and SDA lines using
325  * `dif_i2c_override_drive_pins()`.
326  *
327  * @param i2c An I2C handle.
328  * @param state The new toggle state for override mode.'
329  * @return The result of the operation.
330  */
333  dif_toggle_t state);
334 
335 /**
336  * Drives the SCL and SDA pins to the given values when "override mode" is
337  * enabled.
338  *
339  * @param i2c An I2C handle.
340  * @param scl The value to drive SCL to.
341  * @param sda The value to drive SDA to.
342  * @return The result of the operation.
343  */
346  bool sda);
347 
348 /**
349  * Returns oversampling of the last 16 values of the SCL and SDA pins, with the
350  * zeroth bit being the most recent.
351  *
352  * @param i2c An I2C handle.
353  * @param[out] scl_samples SCL sample bits; may be `NULL`.
354  * @param[out] sda_samples SDA sample bits; may be `NULL`.
355  * @return The result of the operation.
356  */
359  uint16_t *scl_samples,
360  uint16_t *sda_samples);
361 
362 /**
363  * Returns the current levels, i.e., number of entries, in the FMT and RX FIFOs.
364  * These values represent the number of entries pending for send by hardware,
365  * and entries pending for read by software, respectively.
366  *
367  * @param i2c An I2C handle.
368  * @param[out] fmt_fifo_level The number of unsent FMT bytes; may be `NULL`.
369  * @param[out] rx_fifo_level The number of unread RX bytes; may be `NULL`.
370  * @return The result of the operation.
371  */
374  uint8_t *fmt_fifo_level,
375  uint8_t *rx_fifo_level);
376 
377 /**
378  * Pops an entry (a byte) off of the RX FIFO. Passing in `NULL` to the out-param
379  * will still trigger a byte pop.
380  *
381  * @param i2c An I2C handle.
382  * @param[out] byte The popped byte; may be `NULL`.
383  * @return The result of the operation.
384  */
386 dif_result_t dif_i2c_read_byte(const dif_i2c_t *i2c, uint8_t *byte);
387 
388 /**
389  * Pushes a raw write entry onto the FMT FIFO, consisting of a byte and format
390  * flags. This function can be called in sequence to enqueue an I2C
391  * transmission.
392  *
393  * Callers should prefer `dif_i2c_write_byte()` instead, since that function
394  * provides clearer semantics. This function should only really be used for
395  * testing or troubleshooting a device.
396  *
397  * @param i2c An I2C handle.
398  * @param byte The value to push onto the FIFO.
399  * @param flags The flags to use for this write.
400  * @return The result of the operation.
401  */
403 dif_result_t dif_i2c_write_byte_raw(const dif_i2c_t *i2c, uint8_t byte,
404  dif_i2c_fmt_flags_t flags);
405 
406 /**
407  * Pushes a write entry onto the FMT FIFO, consisting of a byte and a format
408  * code. This function can be called in sequence to enqueue an I2C
409  * transmission.
410  *
411  * @param i2c An I2C handle.
412  * @param byte The value to push onto the FIFO.
413  * @param code The code to use for this write.
414  * @param suppress_nak_irq Whether to supress the NAK IRQ for this one byte.
415  * May not be used in combination with `Rx` codes.
416  * @return The result of the operation.
417  */
419 dif_result_t dif_i2c_write_byte(const dif_i2c_t *i2c, uint8_t byte,
420  dif_i2c_fmt_t code, bool suppress_nak_irq);
421 
422 #ifdef __cplusplus
423 } // extern "C"
424 #endif // __cplusplus
425 
426 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_I2C_H_