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