Software APIs
dif_i2c.c
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 
6 
11 
12 #include "i2c_regs.h" // Generated
13 
14 /**
15  * Performs a 32-bit integer unsigned division, rounding up. The bottom
16  * 16 bits of the result are then returned.
17  *
18  * As usual, a divisor of 0 is still Undefined Behavior.
19  */
20 static uint16_t round_up_divide(uint32_t a, uint32_t b) {
21  const uint32_t result = ((a - 1) / b) + 1;
22  return (uint16_t)result;
23 }
24 
25 static void spin_while_status_bit(const dif_i2c_t *i2c, uint32_t bit,
26  bool set) {
27  uint32_t reg = 0;
28  do {
29  reg = mmio_region_read32(i2c->base_addr, I2C_STATUS_REG_OFFSET);
30  } while (bitfield_bit32_read(reg, bit) == set);
31 }
32 
33 /**
34  * Reads i2c status bits from registers
35  */
38  if (i2c == NULL || status == NULL) {
39  return kDifBadArg;
40  }
41 
42  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
43  status->enable_host = bitfield_bit32_read(reg, I2C_CTRL_ENABLEHOST_BIT);
44  status->enable_target = bitfield_bit32_read(reg, I2C_CTRL_ENABLETARGET_BIT);
45  status->line_loopback = bitfield_bit32_read(reg, I2C_CTRL_LLPBK_BIT);
46  status->ack_control_en = bitfield_bit32_read(reg, I2C_CTRL_ACK_CTRL_EN_BIT);
47  reg = mmio_region_read32(i2c->base_addr, I2C_STATUS_REG_OFFSET);
48  status->fmt_fifo_full = bitfield_bit32_read(reg, I2C_STATUS_FMTFULL_BIT);
49  status->rx_fifo_full = bitfield_bit32_read(reg, I2C_STATUS_RXFULL_BIT);
50  status->fmt_fifo_empty = bitfield_bit32_read(reg, I2C_STATUS_FMTEMPTY_BIT);
51  status->rx_fifo_empty = bitfield_bit32_read(reg, I2C_STATUS_RXEMPTY_BIT);
52  status->host_idle = bitfield_bit32_read(reg, I2C_STATUS_HOSTIDLE_BIT);
53  status->target_idle = bitfield_bit32_read(reg, I2C_STATUS_TARGETIDLE_BIT);
54  status->tx_fifo_full = bitfield_bit32_read(reg, I2C_STATUS_TXFULL_BIT);
55  status->acq_fifo_full = bitfield_bit32_read(reg, I2C_STATUS_ACQFULL_BIT);
56  status->tx_fifo_empty = bitfield_bit32_read(reg, I2C_STATUS_TXEMPTY_BIT);
57  status->acq_fifo_empty = bitfield_bit32_read(reg, I2C_STATUS_ACQEMPTY_BIT);
58  status->ack_ctrl_stretch =
59  bitfield_bit32_read(reg, I2C_STATUS_ACK_CTRL_STRETCH_BIT);
60 
61  return kDifOk;
62 }
63 
65  const dif_i2c_t *i2c, dif_i2c_controller_halt_events_t *events) {
66  if (i2c == NULL || events == NULL) {
67  return kDifBadArg;
68  }
69  uint32_t reg =
70  mmio_region_read32(i2c->base_addr, I2C_CONTROLLER_EVENTS_REG_OFFSET);
71  events->nack_received =
72  bitfield_bit32_read(reg, I2C_CONTROLLER_EVENTS_NACK_BIT);
74  reg, I2C_CONTROLLER_EVENTS_UNHANDLED_NACK_TIMEOUT_BIT);
75  events->bus_timeout =
76  bitfield_bit32_read(reg, I2C_CONTROLLER_EVENTS_BUS_TIMEOUT_BIT);
77  events->arbitration_lost =
78  bitfield_bit32_read(reg, I2C_CONTROLLER_EVENTS_ARBITRATION_LOST_BIT);
79  return kDifOk;
80 }
81 
83  const dif_i2c_t *i2c, dif_i2c_controller_halt_events_t events) {
84  if (i2c == NULL) {
85  return kDifBadArg;
86  }
87  uint32_t reg = 0;
88  reg = bitfield_bit32_write(reg, I2C_CONTROLLER_EVENTS_NACK_BIT,
89  events.nack_received);
90  reg = bitfield_bit32_write(reg,
91  I2C_CONTROLLER_EVENTS_UNHANDLED_NACK_TIMEOUT_BIT,
92  events.unhandled_nack_timeout);
93  reg = bitfield_bit32_write(reg, I2C_CONTROLLER_EVENTS_BUS_TIMEOUT_BIT,
94  events.bus_timeout);
95  reg = bitfield_bit32_write(reg, I2C_CONTROLLER_EVENTS_ARBITRATION_LOST_BIT,
96  events.arbitration_lost);
97  mmio_region_write32(i2c->base_addr, I2C_CONTROLLER_EVENTS_REG_OFFSET, reg);
98  return kDifOk;
99 }
100 
102  const dif_i2c_t *i2c, dif_i2c_target_tx_halt_events_t *events) {
103  if (i2c == NULL || events == NULL) {
104  return kDifBadArg;
105  }
106  uint32_t reg =
107  mmio_region_read32(i2c->base_addr, I2C_TARGET_EVENTS_REG_OFFSET);
108  events->tx_pending =
109  bitfield_bit32_read(reg, I2C_TARGET_EVENTS_TX_PENDING_BIT);
110  events->bus_timeout =
111  bitfield_bit32_read(reg, I2C_TARGET_EVENTS_BUS_TIMEOUT_BIT);
112  events->arbitration_lost =
113  bitfield_bit32_read(reg, I2C_TARGET_EVENTS_ARBITRATION_LOST_BIT);
114  return kDifOk;
115 }
116 
118  const dif_i2c_t *i2c, dif_i2c_target_tx_halt_events_t events) {
119  if (i2c == NULL) {
120  return kDifBadArg;
121  }
122  uint32_t reg = 0;
123  reg = bitfield_bit32_write(reg, I2C_TARGET_EVENTS_TX_PENDING_BIT,
124  events.tx_pending);
125  reg = bitfield_bit32_write(reg, I2C_TARGET_EVENTS_BUS_TIMEOUT_BIT,
126  events.bus_timeout);
127  reg = bitfield_bit32_write(reg, I2C_TARGET_EVENTS_ARBITRATION_LOST_BIT,
128  events.arbitration_lost);
129  mmio_region_write32(i2c->base_addr, I2C_TARGET_EVENTS_REG_OFFSET, reg);
130  return kDifOk;
131 }
132 
133 /**
134  * Computes default timing parameters for a particular I2C speed, given the
135  * clock period, in nanoseconds.
136  *
137  * Returns an unspecified value for an invalid speed.
138  */
139 static dif_i2c_config_t default_timing_for_speed(dif_i2c_speed_t speed,
140  uint32_t clock_period_nanos) {
141  // NOTE: All constants below are lifted from Table 10 of the I2C spec.
142  // All literal values are given in nanoseconds; we don't bother putting
143  // these into constants since they are not used anywhere else.
144  switch (speed) {
146  return (dif_i2c_config_t){
147  .scl_time_high_cycles = round_up_divide(4000, clock_period_nanos),
148  .scl_time_low_cycles = round_up_divide(4700, clock_period_nanos),
149  .start_signal_setup_cycles =
150  round_up_divide(4700, clock_period_nanos),
151  .start_signal_hold_cycles = round_up_divide(4000, clock_period_nanos),
152  .data_signal_setup_cycles = round_up_divide(250, clock_period_nanos),
153  .data_signal_hold_cycles = 1,
154  .stop_signal_setup_cycles = round_up_divide(4000, clock_period_nanos),
155  .stop_signal_hold_cycles = round_up_divide(4700, clock_period_nanos),
156  };
157  case kDifI2cSpeedFast:
158  return (dif_i2c_config_t){
159  .scl_time_high_cycles = round_up_divide(600, clock_period_nanos),
160  .scl_time_low_cycles = round_up_divide(1300, clock_period_nanos),
161  .start_signal_setup_cycles = round_up_divide(600, clock_period_nanos),
162  .start_signal_hold_cycles = round_up_divide(600, clock_period_nanos),
163  .data_signal_setup_cycles = round_up_divide(100, clock_period_nanos),
164  .data_signal_hold_cycles = 1,
165  .stop_signal_setup_cycles = round_up_divide(600, clock_period_nanos),
166  .stop_signal_hold_cycles = round_up_divide(1300, clock_period_nanos),
167  };
169  return (dif_i2c_config_t){
170  .scl_time_high_cycles = round_up_divide(260, clock_period_nanos),
171  .scl_time_low_cycles = round_up_divide(500, clock_period_nanos),
172  .start_signal_setup_cycles = round_up_divide(260, clock_period_nanos),
173  .start_signal_hold_cycles = round_up_divide(260, clock_period_nanos),
174  .data_signal_setup_cycles = round_up_divide(50, clock_period_nanos),
175  .data_signal_hold_cycles = 1,
176  .stop_signal_setup_cycles = round_up_divide(260, clock_period_nanos),
177  .stop_signal_hold_cycles = round_up_divide(500, clock_period_nanos),
178  };
179  default:
180  return (dif_i2c_config_t){0};
181  }
182 }
183 
184 static const uint32_t kNanosPerKBaud = 1000000; // One million.
185 
187  dif_i2c_config_t *config) {
188  if (config == NULL) {
189  return kDifBadArg;
190  }
191  uint32_t lowest_target_device_speed_khz;
192  switch (timing_config.lowest_target_device_speed) {
194  lowest_target_device_speed_khz = 100;
195  break;
196  case kDifI2cSpeedFast:
197  lowest_target_device_speed_khz = 400;
198  break;
200  lowest_target_device_speed_khz = 1000;
201  break;
202  default:
203  return kDifBadArg;
204  }
205 
206  // This code follows the algorithm given in
207  // https://docs.opentitan.org/hw/ip/i2c/doc/index.html#initialization
208 
209  *config = default_timing_for_speed(timing_config.lowest_target_device_speed,
210  timing_config.clock_period_nanos);
211 
212  config->rise_cycles = round_up_divide(timing_config.sda_rise_nanos,
213  timing_config.clock_period_nanos);
214  config->fall_cycles = round_up_divide(timing_config.sda_fall_nanos,
215  timing_config.clock_period_nanos);
216 
217  uint32_t scl_period_nanos = timing_config.scl_period_nanos;
218  uint32_t slowest_scl_period_nanos =
219  kNanosPerKBaud / lowest_target_device_speed_khz;
220  if (scl_period_nanos < slowest_scl_period_nanos) {
221  scl_period_nanos = slowest_scl_period_nanos;
222  }
223  uint16_t scl_period_cycles =
224  round_up_divide(scl_period_nanos, timing_config.clock_period_nanos);
225 
226  // Lengthen the SCL high period to accommodate the desired SCL period.
227  int32_t lengthened_high_cycles = scl_period_cycles -
228  config->scl_time_low_cycles -
229  config->rise_cycles - config->fall_cycles;
230  if (lengthened_high_cycles > (int32_t)config->scl_time_high_cycles) {
231  if (lengthened_high_cycles < 0 || lengthened_high_cycles > UINT16_MAX) {
232  return kDifOutOfRange;
233  }
234  config->scl_time_high_cycles = (uint16_t)lengthened_high_cycles;
235  }
236 
237  // For clock stretching detection to work, the SCL high and low time must be
238  // at least 4 cycles.
239  if (config->scl_time_high_cycles < kDifI2cInputDelayCycles) {
240  config->scl_time_high_cycles = kDifI2cInputDelayCycles;
241  }
242  if (config->scl_time_low_cycles < kDifI2cInputDelayCycles) {
243  config->scl_time_low_cycles = kDifI2cInputDelayCycles;
244  }
245 
246  return kDifOk;
247 }
248 
250  if (i2c == NULL) {
251  return kDifBadArg;
252  }
253 
254  uint32_t timing0 = 0;
255  timing0 = bitfield_field32_write(timing0, I2C_TIMING0_THIGH_FIELD,
256  config.scl_time_high_cycles);
257  timing0 = bitfield_field32_write(timing0, I2C_TIMING0_TLOW_FIELD,
258  config.scl_time_low_cycles);
259  mmio_region_write32(i2c->base_addr, I2C_TIMING0_REG_OFFSET, timing0);
260 
261  uint32_t timing1 = 0;
262  timing1 = bitfield_field32_write(timing1, I2C_TIMING1_T_R_FIELD,
263  config.rise_cycles);
264  timing1 = bitfield_field32_write(timing1, I2C_TIMING1_T_F_FIELD,
265  config.fall_cycles);
266  mmio_region_write32(i2c->base_addr, I2C_TIMING1_REG_OFFSET, timing1);
267 
268  uint32_t timing2 = 0;
269  timing2 = bitfield_field32_write(timing2, I2C_TIMING2_TSU_STA_FIELD,
270  config.start_signal_setup_cycles);
271  timing2 = bitfield_field32_write(timing2, I2C_TIMING2_THD_STA_FIELD,
272  config.start_signal_hold_cycles);
273  mmio_region_write32(i2c->base_addr, I2C_TIMING2_REG_OFFSET, timing2);
274 
275  uint32_t timing3 = 0;
276  timing3 = bitfield_field32_write(timing3, I2C_TIMING3_TSU_DAT_FIELD,
277  config.data_signal_setup_cycles);
278  timing3 = bitfield_field32_write(timing3, I2C_TIMING3_THD_DAT_FIELD,
279  config.data_signal_hold_cycles);
280  mmio_region_write32(i2c->base_addr, I2C_TIMING3_REG_OFFSET, timing3);
281 
282  uint32_t timing4 = 0;
283  timing4 = bitfield_field32_write(timing4, I2C_TIMING4_TSU_STO_FIELD,
284  config.stop_signal_setup_cycles);
285  timing4 = bitfield_field32_write(timing4, I2C_TIMING4_T_BUF_FIELD,
286  config.stop_signal_hold_cycles);
287  mmio_region_write32(i2c->base_addr, I2C_TIMING4_REG_OFFSET, timing4);
288 
289  return kDifOk;
290 }
291 
293  if (i2c == NULL) {
294  return kDifBadArg;
295  }
296 
297  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET);
298  reg = bitfield_bit32_write(reg, I2C_FIFO_CTRL_RXRST_BIT, true);
299  mmio_region_write32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET, reg);
300 
301  return kDifOk;
302 }
303 
305  if (i2c == NULL) {
306  return kDifBadArg;
307  }
308 
309  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET);
310  reg = bitfield_bit32_write(reg, I2C_FIFO_CTRL_FMTRST_BIT, true);
311  mmio_region_write32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET, reg);
312 
313  return kDifOk;
314 }
315 
317  if (i2c == NULL) {
318  return kDifBadArg;
319  }
320 
321  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET);
322  reg = bitfield_bit32_write(reg, I2C_FIFO_CTRL_TXRST_BIT, true);
323  mmio_region_write32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET, reg);
324 
325  return kDifOk;
326 }
327 
329  if (i2c == NULL) {
330  return kDifBadArg;
331  }
332 
333  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET);
334  reg = bitfield_bit32_write(reg, I2C_FIFO_CTRL_ACQRST_BIT, true);
335  mmio_region_write32(i2c->base_addr, I2C_FIFO_CTRL_REG_OFFSET, reg);
336 
337  return kDifOk;
338 }
339 
341  dif_i2c_level_t rx_level,
342  dif_i2c_level_t fmt_level) {
343  // Check that the FIFO levels are sensible; setting RX level equal to the
344  // depth deactivates its interrupt, but setting FMT level to that would result
345  // in continual interrupt assertion.
346  if (i2c == NULL || rx_level > I2C_PARAM_FIFO_DEPTH ||
347  fmt_level >= I2C_PARAM_FIFO_DEPTH) {
348  return kDifBadArg;
349  }
350 
351  uint32_t ctrl_value =
352  mmio_region_read32(i2c->base_addr, I2C_HOST_FIFO_CONFIG_REG_OFFSET);
353  ctrl_value = bitfield_field32_write(
354  ctrl_value, I2C_HOST_FIFO_CONFIG_RX_THRESH_FIELD, rx_level);
355  ctrl_value = bitfield_field32_write(
356  ctrl_value, I2C_HOST_FIFO_CONFIG_FMT_THRESH_FIELD, fmt_level);
357  mmio_region_write32(i2c->base_addr, I2C_HOST_FIFO_CONFIG_REG_OFFSET,
358  ctrl_value);
359 
360  return kDifOk;
361 }
362 
364  dif_i2c_level_t tx_level,
365  dif_i2c_level_t acq_level) {
366  // Check that the FIFO levels are sensible; setting ACQ level equal to the
367  // depth deactivates its interrupt, but setting TX level to that would result
368  // in continual interrupt assertion.
369  if (i2c == NULL || acq_level > I2C_PARAM_ACQ_FIFO_DEPTH ||
370  tx_level >= I2C_PARAM_FIFO_DEPTH) {
371  return kDifBadArg;
372  }
373 
374  uint32_t ctrl_value =
375  mmio_region_read32(i2c->base_addr, I2C_TARGET_FIFO_CONFIG_REG_OFFSET);
376  ctrl_value = bitfield_field32_write(
377  ctrl_value, I2C_TARGET_FIFO_CONFIG_TX_THRESH_FIELD, tx_level);
378  ctrl_value = bitfield_field32_write(
379  ctrl_value, I2C_TARGET_FIFO_CONFIG_ACQ_THRESH_FIELD, acq_level);
380  mmio_region_write32(i2c->base_addr, I2C_TARGET_FIFO_CONFIG_REG_OFFSET,
381  ctrl_value);
382 
383  return kDifOk;
384 }
385 
387  dif_toggle_t state) {
388  if (i2c == NULL) {
389  return kDifBadArg;
390  }
391 
392  if (!dif_is_valid_toggle(state)) {
393  return kDifBadArg;
394  }
395  bool flag = dif_toggle_to_bool(state);
396 
397  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
398  reg = bitfield_bit32_write(reg, I2C_CTRL_ENABLEHOST_BIT, flag);
399  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
400 
401  return kDifOk;
402 }
403 
405  dif_toggle_t state) {
406  if (i2c == NULL) {
407  return kDifBadArg;
408  }
409 
410  if (!dif_is_valid_toggle(state)) {
411  return kDifBadArg;
412  }
413  bool flag = dif_toggle_to_bool(state);
414 
415  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
416  reg = bitfield_bit32_write(reg, I2C_CTRL_ENABLETARGET_BIT, flag);
417  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
418 
419  return kDifOk;
420 }
421 
423  dif_toggle_t state) {
424  if (i2c == NULL) {
425  return kDifBadArg;
426  }
427 
428  if (!dif_is_valid_toggle(state)) {
429  return kDifBadArg;
430  }
431  bool flag = dif_toggle_to_bool(state);
432 
433  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
434  reg = bitfield_bit32_write(reg, I2C_CTRL_LLPBK_BIT, flag);
435  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
436 
437  return kDifOk;
438 }
439 
441  dif_toggle_t state) {
442  if (i2c == NULL) {
443  return kDifBadArg;
444  }
445 
446  if (!dif_is_valid_toggle(state)) {
447  return kDifBadArg;
448  }
449  bool flag = dif_toggle_to_bool(state);
450 
451  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
452  reg = bitfield_bit32_write(reg, I2C_CTRL_NACK_ADDR_AFTER_TIMEOUT_BIT, flag);
453  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
454 
455  return kDifOk;
456 }
457 
459  dif_toggle_t state) {
460  if (i2c == NULL) {
461  return kDifBadArg;
462  }
463 
464  if (!dif_is_valid_toggle(state)) {
465  return kDifBadArg;
466  }
467  bool flag = dif_toggle_to_bool(state);
468 
469  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
470  reg = bitfield_bit32_write(reg, I2C_CTRL_ACK_CTRL_EN_BIT, flag);
471  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
472 
473  return kDifOk;
474 }
475 
477  dif_toggle_t state) {
478  if (i2c == NULL) {
479  return kDifBadArg;
480  }
481 
482  if (!dif_is_valid_toggle(state)) {
483  return kDifBadArg;
484  }
485  bool flag = dif_toggle_to_bool(state);
486 
487  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
488  reg =
489  bitfield_bit32_write(reg, I2C_CTRL_MULTI_CONTROLLER_MONITOR_EN_BIT, flag);
490  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
491 
492  return kDifOk;
493 }
494 
496  dif_toggle_t state) {
497  if (i2c == NULL) {
498  return kDifBadArg;
499  }
500 
501  if (!dif_is_valid_toggle(state)) {
502  return kDifBadArg;
503  }
504  bool flag = dif_toggle_to_bool(state);
505 
506  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_CTRL_REG_OFFSET);
507  reg = bitfield_bit32_write(reg, I2C_CTRL_TX_STRETCH_CTRL_EN_BIT, flag);
508  mmio_region_write32(i2c->base_addr, I2C_CTRL_REG_OFFSET, reg);
509 
510  return kDifOk;
511 }
512 
514  dif_toggle_t state) {
515  if (i2c == NULL) {
516  return kDifBadArg;
517  }
518 
519  if (!dif_is_valid_toggle(state)) {
520  return kDifBadArg;
521  }
522  bool flag = dif_toggle_to_bool(state);
523 
524  uint32_t reg = mmio_region_read32(i2c->base_addr, I2C_OVRD_REG_OFFSET);
525  reg = bitfield_bit32_write(reg, I2C_OVRD_TXOVRDEN_BIT, flag);
526  mmio_region_write32(i2c->base_addr, I2C_OVRD_REG_OFFSET, reg);
527 
528  return kDifOk;
529 }
530 
532  bool sda) {
533  if (i2c == NULL) {
534  return kDifBadArg;
535  }
536 
537  uint32_t override_val =
538  mmio_region_read32(i2c->base_addr, I2C_OVRD_REG_OFFSET);
539  override_val = bitfield_bit32_write(override_val, I2C_OVRD_SCLVAL_BIT, scl);
540  override_val = bitfield_bit32_write(override_val, I2C_OVRD_SDAVAL_BIT, sda);
541  mmio_region_write32(i2c->base_addr, I2C_OVRD_REG_OFFSET, override_val);
542 
543  return kDifOk;
544 }
545 
547  uint16_t *scl_samples,
548  uint16_t *sda_samples) {
549  if (i2c == NULL) {
550  return kDifBadArg;
551  }
552 
553  uint32_t samples = mmio_region_read32(i2c->base_addr, I2C_VAL_REG_OFFSET);
554  if (scl_samples != NULL) {
555  *scl_samples =
556  (uint16_t)bitfield_field32_read(samples, I2C_VAL_SCL_RX_FIELD);
557  }
558 
559  if (sda_samples != NULL) {
560  *sda_samples =
561  (uint16_t)bitfield_field32_read(samples, I2C_VAL_SDA_RX_FIELD);
562  }
563 
564  return kDifOk;
565 }
566 
568  dif_i2c_level_t *fmt_fifo_level,
569  dif_i2c_level_t *rx_fifo_level,
570  dif_i2c_level_t *tx_fifo_level,
571  dif_i2c_level_t *acq_fifo_level) {
572  if (i2c == NULL) {
573  return kDifBadArg;
574  }
575 
576  // Host-side FIFO levels
577  uint32_t values =
578  mmio_region_read32(i2c->base_addr, I2C_HOST_FIFO_STATUS_REG_OFFSET);
579  if (fmt_fifo_level != NULL) {
580  *fmt_fifo_level = (dif_i2c_level_t)bitfield_field32_read(
581  values, I2C_HOST_FIFO_STATUS_FMTLVL_FIELD);
582  }
583  if (rx_fifo_level != NULL) {
584  *rx_fifo_level = (dif_i2c_level_t)bitfield_field32_read(
585  values, I2C_HOST_FIFO_STATUS_RXLVL_FIELD);
586  }
587 
588  // Target-side FIFO levels
589  values =
590  mmio_region_read32(i2c->base_addr, I2C_TARGET_FIFO_STATUS_REG_OFFSET);
591  if (tx_fifo_level != NULL) {
592  *tx_fifo_level = (dif_i2c_level_t)bitfield_field32_read(
593  values, I2C_TARGET_FIFO_STATUS_TXLVL_FIELD);
594  }
595  if (acq_fifo_level != NULL) {
596  *acq_fifo_level = (dif_i2c_level_t)bitfield_field32_read(
597  values, I2C_TARGET_FIFO_STATUS_ACQLVL_FIELD);
598  }
599 
600  return kDifOk;
601 }
602 
603 dif_result_t dif_i2c_get_auto_ack_count(const dif_i2c_t *i2c, uint16_t *count) {
604  if (i2c == NULL || count == NULL) {
605  return kDifBadArg;
606  }
607 
608  uint32_t reg =
609  mmio_region_read32(i2c->base_addr, I2C_TARGET_ACK_CTRL_REG_OFFSET);
610  *count =
611  (uint16_t)bitfield_field32_read(reg, I2C_TARGET_ACK_CTRL_NBYTES_FIELD);
612 
613  return kDifOk;
614 }
615 
616 dif_result_t dif_i2c_set_auto_ack_count(const dif_i2c_t *i2c, uint16_t count) {
617  if (i2c == NULL) {
618  return kDifBadArg;
619  }
620  if (count > I2C_TARGET_ACK_CTRL_NBYTES_MASK) {
621  return kDifBadArg;
622  }
623 
624  uint32_t reg =
625  bitfield_field32_write(0, I2C_TARGET_ACK_CTRL_NBYTES_FIELD, count);
626  mmio_region_write32(i2c->base_addr, I2C_TARGET_ACK_CTRL_REG_OFFSET, reg);
627 
628  return kDifOk;
629 }
630 
632  if (i2c == NULL) {
633  return kDifBadArg;
634  }
635 
636  uint32_t reg = bitfield_bit32_write(0, I2C_TARGET_ACK_CTRL_NACK_BIT, true);
637  mmio_region_write32(i2c->base_addr, I2C_TARGET_ACK_CTRL_REG_OFFSET, reg);
638 
639  return kDifOk;
640 }
641 
643  if (i2c == NULL || data == NULL) {
644  return kDifBadArg;
645  }
646 
647  *data = 0xffu &
648  mmio_region_read32(i2c->base_addr, I2C_ACQ_FIFO_NEXT_DATA_REG_OFFSET);
649 
650  return kDifOk;
651 }
652 
653 dif_result_t dif_i2c_read_byte(const dif_i2c_t *i2c, uint8_t *byte) {
654  if (i2c == NULL) {
655  return kDifBadArg;
656  }
657 
658  uint32_t values = mmio_region_read32(i2c->base_addr, I2C_RDATA_REG_OFFSET);
659  if (byte != NULL) {
660  *byte = (uint8_t)bitfield_field32_read(values, I2C_RDATA_RDATA_FIELD);
661  }
662 
663  return kDifOk;
664 }
665 
666 dif_result_t dif_i2c_read_bytes(const dif_i2c_t *i2c, size_t size,
667  uint8_t *buffer) {
668  if (i2c == NULL || buffer == NULL) {
669  return kDifBadArg;
670  }
671 
672  while (size--) {
673  spin_while_status_bit(i2c, I2C_STATUS_RXEMPTY_BIT, /*set*/ true);
674  uint32_t values = mmio_region_read32(i2c->base_addr, I2C_RDATA_REG_OFFSET);
675  *(buffer++) = (uint8_t)bitfield_field32_read(values, I2C_RDATA_RDATA_FIELD);
676  }
677 
678  return kDifOk;
679 }
680 
681 static inline dif_result_t parse_flags(dif_i2c_fmt_flags_t flags,
682  uint32_t *fmt_byte) {
683  // Validate that "write only" flags and "read only" flags are not set
684  // simultaneously.
685  bool has_write_flags = flags.start || flags.suppress_nak_irq;
686  bool has_read_flags = flags.read || flags.read_cont;
687  if (has_write_flags && has_read_flags) {
688  return kDifBadArg;
689  }
690  // Also, read_cont requires read.
691  if (flags.read_cont && !flags.read) {
692  return kDifBadArg;
693  }
694 
695  *fmt_byte = bitfield_bit32_write(*fmt_byte, 8, flags.start);
696  *fmt_byte = bitfield_bit32_write(*fmt_byte, I2C_FDATA_STOP_BIT, flags.stop);
697  *fmt_byte = bitfield_bit32_write(*fmt_byte, I2C_FDATA_READB_BIT, flags.read);
698  *fmt_byte =
699  bitfield_bit32_write(*fmt_byte, I2C_FDATA_RCONT_BIT, flags.read_cont);
700  *fmt_byte = bitfield_bit32_write(*fmt_byte, I2C_FDATA_NAKOK_BIT,
701  flags.suppress_nak_irq);
702 
703  return kDifOk;
704 }
706  const uint8_t *bytes,
707  dif_i2c_fmt_flags_t flags) {
708  if (i2c == NULL || bytes == NULL || size == 0) {
709  return kDifBadArg;
710  }
711  uint32_t fmt_byte = 0;
712  DIF_RETURN_IF_ERROR(parse_flags(flags, &fmt_byte));
713 
714  for (size_t i = 0; i < size; ++i) {
715  uint32_t reg =
716  bitfield_field32_write(fmt_byte, I2C_FDATA_FBYTE_FIELD, bytes[i]);
717  mmio_region_write32(i2c->base_addr, I2C_FDATA_REG_OFFSET, reg);
718  spin_while_status_bit(i2c, I2C_STATUS_FMTFULL_BIT, /*set*/ true);
719  }
720 
721  return kDifOk;
722 }
723 
725  dif_i2c_fmt_flags_t flags) {
726  if (i2c == NULL) {
727  return kDifBadArg;
728  }
729 
730  uint32_t fmt_byte = 0;
731  DIF_RETURN_IF_ERROR(parse_flags(flags, &fmt_byte));
732  fmt_byte = bitfield_field32_write(fmt_byte, I2C_FDATA_FBYTE_FIELD, byte);
733  mmio_region_write32(i2c->base_addr, I2C_FDATA_REG_OFFSET, fmt_byte);
734 
735  return kDifOk;
736 }
737 
738 dif_result_t dif_i2c_write_byte(const dif_i2c_t *i2c, uint8_t byte,
739  dif_i2c_fmt_t code, bool suppress_nak_irq) {
740  if (i2c == NULL) {
741  return kDifBadArg;
742  }
743 
744  // Validate that `suppress_nak_irq` has not been mixed with an Rx code.
745  if (suppress_nak_irq) {
746  switch (code) {
747  case kDifI2cFmtRx:
749  case kDifI2cFmtRxStop:
750  return kDifBadArg;
751  default:
752  break;
753  }
754  }
755 
756  // Convert the format code into flags.
757  dif_i2c_fmt_flags_t flags = {.suppress_nak_irq = suppress_nak_irq};
758  switch (code) {
759  case kDifI2cFmtStart:
760  flags.start = true;
761  break;
762  case kDifI2cFmtTx:
763  break;
764  case kDifI2cFmtTxStop:
765  flags.stop = true;
766  break;
767  case kDifI2cFmtRx:
768  flags.read = true;
769  break;
771  flags.read = true;
772  flags.read_cont = true;
773  break;
774  case kDifI2cFmtRxStop:
775  flags.read = true;
776  flags.stop = true;
777  break;
778  default:
779  return kDifBadArg;
780  }
781 
782  return dif_i2c_write_byte_raw(i2c, byte, flags);
783 }
784 
785 dif_result_t dif_i2c_transmit_byte(const dif_i2c_t *i2c, uint8_t byte) {
786  if (i2c == NULL) {
787  return kDifBadArg;
788  }
789 
790  uint32_t tx_byte = 0;
791  tx_byte = bitfield_field32_write(tx_byte, I2C_TXDATA_TXDATA_FIELD, byte);
792  mmio_region_write32(i2c->base_addr, I2C_TXDATA_REG_OFFSET, tx_byte);
793 
794  return kDifOk;
795 }
796 
797 dif_result_t dif_i2c_acquire_byte(const dif_i2c_t *i2c, uint8_t *byte,
798  dif_i2c_signal_t *signal) {
799  if (i2c == NULL) {
800  return kDifBadArg;
801  }
802 
803  uint32_t acq_byte =
804  mmio_region_read32(i2c->base_addr, I2C_ACQDATA_REG_OFFSET);
805  if (byte != NULL) {
806  *byte = (uint8_t)bitfield_field32_read(acq_byte, I2C_ACQDATA_ABYTE_FIELD);
807  }
808  if (signal != NULL) {
809  *signal = bitfield_field32_read(acq_byte, I2C_ACQDATA_SIGNAL_FIELD);
810  }
811  return kDifOk;
812 }
813 
815  dif_i2c_scl_timeout_t timeout_type,
816  uint32_t cycles) {
817  if (i2c == NULL) {
818  return kDifBadArg;
819  }
820 
821  bool timeout_en = false;
822  uint8_t timeout_mode = 0;
823  switch (timeout_type) {
825  timeout_en = false;
826  break;
828  timeout_en = true;
829  timeout_mode = I2C_TIMEOUT_CTRL_MODE_VALUE_STRETCH_TIMEOUT;
830  break;
832  timeout_en = true;
833  timeout_mode = I2C_TIMEOUT_CTRL_MODE_VALUE_BUS_TIMEOUT;
834  break;
835  default:
836  return kDifBadArg;
837  }
838 
839  uint32_t config = 0;
840  config = bitfield_bit32_write(config, I2C_TIMEOUT_CTRL_EN_BIT, timeout_en);
841  config =
842  bitfield_bit32_write(config, I2C_TIMEOUT_CTRL_MODE_BIT, timeout_mode);
843  config = bitfield_field32_write(config, I2C_TIMEOUT_CTRL_VAL_FIELD, cycles);
844  mmio_region_write32(i2c->base_addr, I2C_TIMEOUT_CTRL_REG_OFFSET, config);
845  return kDifOk;
846 }
847 
849  const dif_i2c_id_t *id0,
850  const dif_i2c_id_t *id1) {
851  if (i2c == NULL) {
852  return kDifBadArg;
853  }
854 
855  uint32_t config = 0;
856  if (id0 != NULL) {
857  config = bitfield_field32_write(config, I2C_TARGET_ID_ADDRESS0_FIELD,
858  id0->address);
859  config =
860  bitfield_field32_write(config, I2C_TARGET_ID_MASK0_FIELD, id0->mask);
861  } else {
862  // Don't listen by default
863  config = bitfield_field32_write(config, I2C_TARGET_ID_ADDRESS0_FIELD, 0x7f);
864  }
865 
866  if (id1 != NULL) {
867  config = bitfield_field32_write(config, I2C_TARGET_ID_ADDRESS1_FIELD,
868  id1->address);
869  config =
870  bitfield_field32_write(config, I2C_TARGET_ID_MASK1_FIELD, id1->mask);
871  } else {
872  // Don't listen by default
873  config = bitfield_field32_write(config, I2C_TARGET_ID_ADDRESS1_FIELD, 0x7f);
874  }
875 
876  mmio_region_write32(i2c->base_addr, I2C_TARGET_ID_REG_OFFSET, config);
877  return kDifOk;
878 }
879 
880 dif_result_t dif_i2c_set_host_timeout(const dif_i2c_t *i2c, uint32_t cycles) {
881  if (i2c == NULL) {
882  return kDifBadArg;
883  }
884 
885  mmio_region_write32(i2c->base_addr, I2C_HOST_TIMEOUT_CTRL_REG_OFFSET, cycles);
886  return kDifOk;
887 }