1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "hardware/i2c.h"
8 #include "hardware/resets.h"
9 #include "hardware/clocks.h"
10 #include "pico/timeout_helper.h"
11 
12 check_hw_layout(i2c_hw_t, enable, I2C_IC_ENABLE_OFFSET);
13 check_hw_layout(i2c_hw_t, clr_restart_det, I2C_IC_CLR_RESTART_DET_OFFSET);
14 
15 i2c_inst_t i2c0_inst = {i2c0_hw, false};
16 i2c_inst_t i2c1_inst = {i2c1_hw, false};
17 
i2c_reset(i2c_inst_t * i2c)18 static inline void i2c_reset(i2c_inst_t *i2c) {
19     invalid_params_if(HARDWARE_I2C, i2c != i2c0 && i2c != i2c1);
20     reset_block_num(i2c == i2c0 ? RESET_I2C0 : RESET_I2C1);
21 }
22 
i2c_unreset(i2c_inst_t * i2c)23 static inline void i2c_unreset(i2c_inst_t *i2c) {
24     invalid_params_if(HARDWARE_I2C, i2c != i2c0 && i2c != i2c1);
25     unreset_block_num_wait_blocking(i2c == i2c0 ? RESET_I2C0 : RESET_I2C1);
26 }
27 
28 // Addresses of the form 000 0xxx or 111 1xxx are reserved. No slave should
29 // have these addresses.
30 #define i2c_reserved_addr(addr) (((addr) & 0x78) == 0 || ((addr) & 0x78) == 0x78)
31 
i2c_init(i2c_inst_t * i2c,uint baudrate)32 uint i2c_init(i2c_inst_t *i2c, uint baudrate) {
33     i2c_reset(i2c);
34     i2c_unreset(i2c);
35     i2c->restart_on_next = false;
36 
37     i2c->hw->enable = 0;
38 
39     // Configure as a fast-mode master with RepStart support, 7-bit addresses
40     i2c->hw->con =
41             I2C_IC_CON_SPEED_VALUE_FAST << I2C_IC_CON_SPEED_LSB |
42             I2C_IC_CON_MASTER_MODE_BITS |
43             I2C_IC_CON_IC_SLAVE_DISABLE_BITS |
44             I2C_IC_CON_IC_RESTART_EN_BITS |
45             I2C_IC_CON_TX_EMPTY_CTRL_BITS;
46 
47     // Set FIFO watermarks to 1 to make things simpler. This is encoded by a register value of 0.
48     i2c->hw->tx_tl = 0;
49     i2c->hw->rx_tl = 0;
50 
51     // Always enable the DREQ signalling -- harmless if DMA isn't listening
52     i2c->hw->dma_cr = I2C_IC_DMA_CR_TDMAE_BITS | I2C_IC_DMA_CR_RDMAE_BITS;
53 
54     // Re-sets i2c->hw->enable upon returning:
55     return i2c_set_baudrate(i2c, baudrate);
56 }
57 
i2c_deinit(i2c_inst_t * i2c)58 void i2c_deinit(i2c_inst_t *i2c) {
59     i2c_reset(i2c);
60 }
61 
i2c_set_baudrate(i2c_inst_t * i2c,uint baudrate)62 uint i2c_set_baudrate(i2c_inst_t *i2c, uint baudrate) {
63     invalid_params_if(HARDWARE_I2C, baudrate == 0);
64     // I2C is synchronous design that runs from clk_sys
65     uint freq_in = clock_get_hz(clk_sys);
66 
67     // TODO there are some subtleties to I2C timing which we are completely ignoring here
68     uint period = (freq_in + baudrate / 2) / baudrate;
69     uint lcnt = period * 3 / 5; // oof this one hurts
70     uint hcnt = period - lcnt;
71     // Check for out-of-range divisors:
72     invalid_params_if(HARDWARE_I2C, hcnt > I2C_IC_FS_SCL_HCNT_IC_FS_SCL_HCNT_BITS);
73     invalid_params_if(HARDWARE_I2C, lcnt > I2C_IC_FS_SCL_LCNT_IC_FS_SCL_LCNT_BITS);
74     invalid_params_if(HARDWARE_I2C, hcnt < 8);
75     invalid_params_if(HARDWARE_I2C, lcnt < 8);
76 
77     // Per I2C-bus specification a device in standard or fast mode must
78     // internally provide a hold time of at least 300ns for the SDA signal to
79     // bridge the undefined region of the falling edge of SCL. A smaller hold
80     // time of 120ns is used for fast mode plus.
81     uint sda_tx_hold_count;
82     if (baudrate < 1000000) {
83         // sda_tx_hold_count = freq_in [cycles/s] * 300ns * (1s / 1e9ns)
84         // Reduce 300/1e9 to 3/1e7 to avoid numbers that don't fit in uint.
85         // Add 1 to avoid division truncation.
86         sda_tx_hold_count = ((freq_in * 3) / 10000000) + 1;
87     } else {
88         // sda_tx_hold_count = freq_in [cycles/s] * 120ns * (1s / 1e9ns)
89         // Reduce 120/1e9 to 3/25e6 to avoid numbers that don't fit in uint.
90         // Add 1 to avoid division truncation.
91         sda_tx_hold_count = ((freq_in * 3) / 25000000) + 1;
92     }
93     assert(sda_tx_hold_count <= lcnt - 2);
94 
95     i2c->hw->enable = 0;
96     // Always use "fast" mode (<= 400 kHz, works fine for standard mode too)
97     hw_write_masked(&i2c->hw->con,
98                    I2C_IC_CON_SPEED_VALUE_FAST << I2C_IC_CON_SPEED_LSB,
99                    I2C_IC_CON_SPEED_BITS
100     );
101     i2c->hw->fs_scl_hcnt = hcnt;
102     i2c->hw->fs_scl_lcnt = lcnt;
103     i2c->hw->fs_spklen = lcnt < 16 ? 1 : lcnt / 16;
104     hw_write_masked(&i2c->hw->sda_hold,
105                     sda_tx_hold_count << I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD_LSB,
106                     I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD_BITS);
107 
108     i2c->hw->enable = 1;
109     return freq_in / period;
110 }
111 
i2c_set_slave_mode(i2c_inst_t * i2c,bool slave,uint8_t addr)112 void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr) {
113     invalid_params_if(HARDWARE_I2C, addr >= 0x80); // 7-bit addresses
114     invalid_params_if(HARDWARE_I2C, i2c_reserved_addr(addr));
115     i2c->hw->enable = 0;
116     uint32_t ctrl_set_if_master = I2C_IC_CON_MASTER_MODE_BITS | I2C_IC_CON_IC_SLAVE_DISABLE_BITS;
117     uint32_t ctrl_set_if_slave = I2C_IC_CON_RX_FIFO_FULL_HLD_CTRL_BITS;
118     if (slave) {
119         hw_write_masked(&i2c->hw->con,
120             ctrl_set_if_slave,
121             ctrl_set_if_master | ctrl_set_if_slave
122         );
123         i2c->hw->sar = addr;
124     } else {
125         hw_write_masked(&i2c->hw->con,
126             ctrl_set_if_master,
127             ctrl_set_if_master | ctrl_set_if_slave
128         );
129     }
130     i2c->hw->enable = 1;
131 }
132 
i2c_write_blocking_internal(i2c_inst_t * i2c,uint8_t addr,const uint8_t * src,size_t len,bool nostop,check_timeout_fn timeout_check,struct timeout_state * ts)133 static int i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
134                                        check_timeout_fn timeout_check, struct timeout_state *ts) {
135     invalid_params_if(HARDWARE_I2C, addr >= 0x80); // 7-bit addresses
136     invalid_params_if(HARDWARE_I2C, i2c_reserved_addr(addr));
137     // Synopsys hw accepts start/stop flags alongside data items in the same
138     // FIFO word, so no 0 byte transfers.
139     invalid_params_if(HARDWARE_I2C, len == 0);
140     invalid_params_if(HARDWARE_I2C, ((int)len) < 0);
141 
142     i2c->hw->enable = 0;
143     i2c->hw->tar = addr;
144     i2c->hw->enable = 1;
145 
146     bool abort = false;
147     bool timeout = false;
148 
149     uint32_t abort_reason = 0;
150     int byte_ctr;
151 
152     int ilen = (int)len;
153     for (byte_ctr = 0; byte_ctr < ilen; ++byte_ctr) {
154         bool first = byte_ctr == 0;
155         bool last = byte_ctr == ilen - 1;
156 
157         if (timeout_check) {
158             timeout_check(ts, true); // for per iteration checks, this will reset the timeout
159         }
160 
161         i2c->hw->data_cmd =
162                 bool_to_bit(first && i2c->restart_on_next) << I2C_IC_DATA_CMD_RESTART_LSB |
163                 bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB |
164                 *src++;
165 
166         // Wait until the transmission of the address/data from the internal
167         // shift register has completed. For this to function correctly, the
168         // TX_EMPTY_CTRL flag in IC_CON must be set. The TX_EMPTY_CTRL flag
169         // was set in i2c_init.
170         do {
171             if (timeout_check) {
172                 timeout = timeout_check(ts, false);
173                 abort |= timeout;
174             }
175             tight_loop_contents();
176         } while (!timeout && !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_EMPTY_BITS));
177 
178         // If there was a timeout, don't attempt to do anything else.
179         if (!timeout) {
180             abort_reason = i2c->hw->tx_abrt_source;
181             if (abort_reason) {
182                 // Note clearing the abort flag also clears the reason, and
183                 // this instance of flag is clear-on-read! Note also the
184                 // IC_CLR_TX_ABRT register always reads as 0.
185                 i2c->hw->clr_tx_abrt;
186                 abort = true;
187             }
188 
189             if (abort || (last && !nostop)) {
190                 // If the transaction was aborted or if it completed
191                 // successfully wait until the STOP condition has occurred.
192 
193                 // TODO Could there be an abort while waiting for the STOP
194                 // condition here? If so, additional code would be needed here
195                 // to take care of the abort.
196                 do {
197                     if (timeout_check) {
198                         timeout = timeout_check(ts, false);
199                         abort |= timeout;
200                     }
201                     tight_loop_contents();
202                 } while (!timeout && !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS));
203 
204                 // If there was a timeout, don't attempt to do anything else.
205                 if (!timeout) {
206                     i2c->hw->clr_stop_det;
207                 }
208             }
209         }
210 
211         // Note the hardware issues a STOP automatically on an abort condition.
212         // Note also the hardware clears RX FIFO as well as TX on abort,
213         // because we set hwparam IC_AVOID_RX_FIFO_FLUSH_ON_TX_ABRT to 0.
214         if (abort)
215             break;
216     }
217 
218     int rval;
219 
220     // A lot of things could have just happened due to the ingenious and
221     // creative design of I2C. Try to figure things out.
222     if (abort) {
223         if (timeout)
224             rval = PICO_ERROR_TIMEOUT;
225         else if (!abort_reason || abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
226             // No reported errors - seems to happen if there is nothing connected to the bus.
227             // Address byte not acknowledged
228             rval = PICO_ERROR_GENERIC;
229         } else if (abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS) {
230             // Address acknowledged, some data not acknowledged
231             rval = byte_ctr;
232         } else {
233             //panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, abort_reason);
234             rval = PICO_ERROR_GENERIC;
235         }
236     } else {
237         rval = byte_ctr;
238     }
239 
240     // nostop means we are now at the end of a *message* but not the end of a *transfer*
241     i2c->restart_on_next = nostop;
242     return rval;
243 }
244 
i2c_write_blocking(i2c_inst_t * i2c,uint8_t addr,const uint8_t * src,size_t len,bool nostop)245 int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop) {
246     return i2c_write_blocking_internal(i2c, addr, src, len, nostop, NULL, NULL);
247 }
248 
i2c_write_blocking_until(i2c_inst_t * i2c,uint8_t addr,const uint8_t * src,size_t len,bool nostop,absolute_time_t until)249 int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
250                              absolute_time_t until) {
251     timeout_state_t ts;
252     return i2c_write_blocking_internal(i2c, addr, src, len, nostop, init_single_timeout_until(&ts, until), &ts);
253 }
254 
i2c_write_timeout_per_char_us(i2c_inst_t * i2c,uint8_t addr,const uint8_t * src,size_t len,bool nostop,uint timeout_per_char_us)255 int i2c_write_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
256                                   uint timeout_per_char_us) {
257     timeout_state_t ts;
258     return i2c_write_blocking_internal(i2c, addr, src, len, nostop,
259                                        init_per_iteration_timeout_us(&ts, timeout_per_char_us), &ts);
260 }
261 
i2c_write_burst_blocking(i2c_inst_t * i2c,uint8_t addr,const uint8_t * src,size_t len)262 int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len) {
263     int rc = i2c_write_blocking_internal(i2c, addr, src, len, true, NULL, NULL);
264     i2c->restart_on_next = false;
265     return rc;
266 }
267 
i2c_read_blocking_internal(i2c_inst_t * i2c,uint8_t addr,uint8_t * dst,size_t len,bool nostop,check_timeout_fn timeout_check,timeout_state_t * ts)268 static int i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
269                                check_timeout_fn timeout_check, timeout_state_t *ts) {
270     invalid_params_if(HARDWARE_I2C, addr >= 0x80); // 7-bit addresses
271     invalid_params_if(HARDWARE_I2C, i2c_reserved_addr(addr));
272     invalid_params_if(HARDWARE_I2C, len == 0);
273     invalid_params_if(HARDWARE_I2C, ((int)len) < 0);
274 
275     i2c->hw->enable = 0;
276     i2c->hw->tar = addr;
277     i2c->hw->enable = 1;
278 
279     bool abort = false;
280     bool timeout = false;
281     uint32_t abort_reason;
282     int byte_ctr;
283     int ilen = (int)len;
284     for (byte_ctr = 0; byte_ctr < ilen; ++byte_ctr) {
285         bool first = byte_ctr == 0;
286         bool last = byte_ctr == ilen - 1;
287         if (timeout_check) {
288             timeout_check(ts, true); // for per iteration checks, this will reset the timeout
289         }
290 
291         while (!i2c_get_write_available(i2c))
292             tight_loop_contents();
293 
294         i2c->hw->data_cmd =
295                 bool_to_bit(first && i2c->restart_on_next) << I2C_IC_DATA_CMD_RESTART_LSB |
296                 bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB |
297                 I2C_IC_DATA_CMD_CMD_BITS; // -> 1 for read
298 
299         do {
300             abort_reason = i2c->hw->tx_abrt_source;
301             if (i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS) {
302                 abort = true;
303                 i2c->hw->clr_tx_abrt;
304             }
305             if (timeout_check) {
306                 timeout = timeout_check(ts, false);
307                 abort |= timeout;
308             }
309         } while (!abort && !i2c_get_read_available(i2c));
310 
311         if (abort)
312             break;
313 
314         *dst++ = (uint8_t) i2c->hw->data_cmd;
315     }
316 
317     int rval;
318 
319     if (abort) {
320         if (timeout)
321             rval = PICO_ERROR_TIMEOUT;
322         else if (!abort_reason || abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
323             // No reported errors - seems to happen if there is nothing connected to the bus.
324             // Address byte not acknowledged
325             rval = PICO_ERROR_GENERIC;
326         } else {
327 //            panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, abort_reason);
328             rval = PICO_ERROR_GENERIC;
329         }
330     } else {
331         rval = byte_ctr;
332     }
333 
334     i2c->restart_on_next = nostop;
335     return rval;
336 }
337 
i2c_read_blocking(i2c_inst_t * i2c,uint8_t addr,uint8_t * dst,size_t len,bool nostop)338 int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop) {
339     return i2c_read_blocking_internal(i2c, addr, dst, len, nostop, NULL, NULL);
340 }
341 
i2c_read_blocking_until(i2c_inst_t * i2c,uint8_t addr,uint8_t * dst,size_t len,bool nostop,absolute_time_t until)342 int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until) {
343     timeout_state_t ts;
344     return i2c_read_blocking_internal(i2c, addr, dst, len, nostop, init_single_timeout_until(&ts, until), &ts);
345 }
346 
i2c_read_timeout_per_char_us(i2c_inst_t * i2c,uint8_t addr,uint8_t * dst,size_t len,bool nostop,uint timeout_per_char_us)347 int i2c_read_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
348                                  uint timeout_per_char_us) {
349     timeout_state_t ts;
350     return i2c_read_blocking_internal(i2c, addr, dst, len, nostop,
351                                       init_per_iteration_timeout_us(&ts, timeout_per_char_us), &ts);
352 }
353 
i2c_read_burst_blocking(i2c_inst_t * i2c,uint8_t addr,uint8_t * dst,size_t len)354 int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len) {
355     int rc = i2c_read_blocking_internal(i2c, addr, dst, len, true, NULL, NULL);
356     i2c->restart_on_next = false;
357     return rc;
358 }
359