Skip to content

Commit 60f5901

Browse files
committed
Add i2c_result_t
1 parent aa786a1 commit 60f5901

File tree

2 files changed

+91
-42
lines changed
  • src/rp2_common/hardware_i2c

2 files changed

+91
-42
lines changed

src/rp2_common/hardware_i2c/i2c.c

+78-41
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr) {
130130
i2c->hw->enable = 1;
131131
}
132132

133-
static int i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
133+
static i2c_result_t i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
134134
check_timeout_fn timeout_check, struct timeout_state *ts) {
135135
invalid_params_if(HARDWARE_I2C, addr >= 0x80); // 7-bit addresses
136136
invalid_params_if(HARDWARE_I2C, i2c_reserved_addr(addr));
@@ -146,7 +146,7 @@ static int i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint
146146
bool abort = false;
147147
bool timeout = false;
148148

149-
uint32_t abort_reason = 0;
149+
i2c_result_t result = { 0, 0 };
150150
int byte_ctr;
151151

152152
int ilen = (int)len;
@@ -177,8 +177,8 @@ static int i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint
177177

178178
// If there was a timeout, don't attempt to do anything else.
179179
if (!timeout) {
180-
abort_reason = i2c->hw->tx_abrt_source;
181-
if (abort_reason) {
180+
result.abort_reason = i2c->hw->tx_abrt_source;
181+
if (result.abort_reason) {
182182
// Note clearing the abort flag also clears the reason, and
183183
// this instance of flag is clear-on-read! Note also the
184184
// IC_CLR_TX_ABRT register always reads as 0.
@@ -215,58 +215,77 @@ static int i2c_write_blocking_internal(i2c_inst_t *i2c, uint8_t addr, const uint
215215
break;
216216
}
217217

218-
int rval;
219-
220218
// A lot of things could have just happened due to the ingenious and
221219
// creative design of I2C. Try to figure things out.
222220
if (abort) {
223221
if (timeout)
224-
rval = PICO_ERROR_TIMEOUT;
225-
else if (!abort_reason || abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
222+
result.rval = PICO_ERROR_TIMEOUT;
223+
else if (!result.abort_reason || result.abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
226224
// No reported errors - seems to happen if there is nothing connected to the bus.
227225
// Address byte not acknowledged
228-
rval = PICO_ERROR_GENERIC;
229-
} else if (abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS) {
226+
result.rval = PICO_ERROR_GENERIC;
227+
} else if (result.abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS) {
230228
// Address acknowledged, some data not acknowledged
231-
rval = byte_ctr;
229+
result.rval = byte_ctr;
232230
} else {
233-
//panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, abort_reason);
234-
rval = PICO_ERROR_GENERIC;
231+
//panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, result.abort_reason);
232+
result.rval = PICO_ERROR_GENERIC;
235233
}
236234
} else {
237-
rval = byte_ctr;
235+
result.rval = byte_ctr;
238236
}
239237

240238
// nostop means we are now at the end of a *message* but not the end of a *transfer*
241239
i2c->restart_on_next = nostop;
242-
i2c->last_abort_reason = abort_reason;
243-
return rval;
240+
return result;
244241
}
245242

246-
int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop) {
243+
i2c_result_t i2c_write_result_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop) {
247244
return i2c_write_blocking_internal(i2c, addr, src, len, nostop, NULL, NULL);
248245
}
249246

250-
int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
247+
int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop) {
248+
i2c_result_t r = i2c_write_result_blocking(i2c, addr, src, len, nostop);
249+
return r.rval;
250+
}
251+
252+
i2c_result_t i2c_write_result_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
251253
absolute_time_t until) {
252254
timeout_state_t ts;
253255
return i2c_write_blocking_internal(i2c, addr, src, len, nostop, init_single_timeout_until(&ts, until), &ts);
254256
}
255257

256-
int i2c_write_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
258+
int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
259+
absolute_time_t until) {
260+
i2c_result_t r = i2c_write_result_blocking_until(i2c, addr, src, len, nostop, until);
261+
return r.rval;
262+
}
263+
264+
i2c_result_t i2c_write_result_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
257265
uint timeout_per_char_us) {
258266
timeout_state_t ts;
259267
return i2c_write_blocking_internal(i2c, addr, src, len, nostop,
260268
init_per_iteration_timeout_us(&ts, timeout_per_char_us), &ts);
261269
}
262270

263-
int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len) {
264-
int rc = i2c_write_blocking_internal(i2c, addr, src, len, true, NULL, NULL);
271+
int i2c_write_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop,
272+
uint timeout_per_char_us) {
273+
i2c_result_t r = i2c_write_result_timeout_per_char_us(i2c, addr, src, len, nostop, timeout_per_char_us);
274+
return r.rval;
275+
}
276+
277+
i2c_result_t i2c_write_result_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len) {
278+
i2c_result_t r = i2c_write_blocking_internal(i2c, addr, src, len, true, NULL, NULL);
265279
i2c->restart_on_next = false;
266-
return rc;
280+
return r;
281+
}
282+
283+
int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len) {
284+
i2c_result_t r = i2c_write_result_burst_blocking(i2c, addr, src, len);
285+
return r.rval;
267286
}
268287

269-
static int i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
288+
static i2c_result_t i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
270289
check_timeout_fn timeout_check, timeout_state_t *ts) {
271290
invalid_params_if(HARDWARE_I2C, addr >= 0x80); // 7-bit addresses
272291
invalid_params_if(HARDWARE_I2C, i2c_reserved_addr(addr));
@@ -279,7 +298,7 @@ static int i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *ds
279298

280299
bool abort = false;
281300
bool timeout = false;
282-
uint32_t abort_reason = 0;
301+
i2c_result_t result = { 0, 0 };
283302
int byte_ctr;
284303
int ilen = (int)len;
285304
for (byte_ctr = 0; byte_ctr < ilen; ++byte_ctr) {
@@ -298,7 +317,7 @@ static int i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *ds
298317
I2C_IC_DATA_CMD_CMD_BITS; // -> 1 for read
299318

300319
do {
301-
abort_reason = i2c->hw->tx_abrt_source;
320+
result.abort_reason = i2c->hw->tx_abrt_source;
302321
abort = (bool) i2c->hw->clr_tx_abrt;
303322
if (timeout_check) {
304323
timeout = timeout_check(ts, false);
@@ -312,46 +331,64 @@ static int i2c_read_blocking_internal(i2c_inst_t *i2c, uint8_t addr, uint8_t *ds
312331
*dst++ = (uint8_t) i2c->hw->data_cmd;
313332
}
314333

315-
int rval;
316-
317334
if (abort) {
318335
if (timeout)
319-
rval = PICO_ERROR_TIMEOUT;
320-
else if (!abort_reason || abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
336+
result.rval = PICO_ERROR_TIMEOUT;
337+
else if (!result.abort_reason || result.abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS) {
321338
// No reported errors - seems to happen if there is nothing connected to the bus.
322339
// Address byte not acknowledged
323-
rval = PICO_ERROR_GENERIC;
340+
result.rval = PICO_ERROR_GENERIC;
324341
} else {
325-
// panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, abort_reason);
326-
rval = PICO_ERROR_GENERIC;
342+
// panic("Unknown abort from I2C instance @%08x: %08x\n", (uint32_t) i2c->hw, result.abort_reason);
343+
result.rval = PICO_ERROR_GENERIC;
327344
}
328345
} else {
329-
rval = byte_ctr;
346+
result.rval = byte_ctr;
330347
}
331348

332349
i2c->restart_on_next = nostop;
333-
i2c->last_abort_reason = abort_reason;
334-
return rval;
350+
return result;
335351
}
336352

337-
int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop) {
353+
i2c_result_t i2c_read_result_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop) {
338354
return i2c_read_blocking_internal(i2c, addr, dst, len, nostop, NULL, NULL);
339355
}
340356

341-
int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until) {
357+
int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop) {
358+
i2c_result_t r = i2c_read_result_blocking(i2c, addr, dst, len, nostop);
359+
return r.rval;
360+
}
361+
362+
i2c_result_t i2c_read_result_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until) {
342363
timeout_state_t ts;
343364
return i2c_read_blocking_internal(i2c, addr, dst, len, nostop, init_single_timeout_until(&ts, until), &ts);
344365
}
345366

346-
int i2c_read_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
367+
int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until) {
368+
i2c_result_t r = i2c_read_result_blocking_until(i2c, addr, dst, len, nostop, until);
369+
return r.rval;
370+
}
371+
372+
i2c_result_t i2c_read_result_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
347373
uint timeout_per_char_us) {
348374
timeout_state_t ts;
349375
return i2c_read_blocking_internal(i2c, addr, dst, len, nostop,
350376
init_per_iteration_timeout_us(&ts, timeout_per_char_us), &ts);
351377
}
352378

353-
int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len) {
354-
int rc = i2c_read_blocking_internal(i2c, addr, dst, len, true, NULL, NULL);
379+
int i2c_read_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop,
380+
uint timeout_per_char_us) {
381+
i2c_result_t r = i2c_read_result_timeout_per_char_us(i2c, addr, dst, len, nostop, timeout_per_char_us);
382+
return r.rval;
383+
}
384+
385+
i2c_result_t i2c_read_result_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len) {
386+
i2c_result_t r = i2c_read_blocking_internal(i2c, addr, dst, len, true, NULL, NULL);
355387
i2c->restart_on_next = false;
356-
return rc;
388+
return r;
389+
}
390+
391+
int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len) {
392+
i2c_result_t r = i2c_read_result_burst_blocking(i2c, addr, dst, len);
393+
return r.rval;
357394
}

src/rp2_common/hardware_i2c/include/hardware/i2c.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,13 @@ void i2c_set_slave_mode(i2c_inst_t *i2c, bool slave, uint8_t addr);
151151
struct i2c_inst {
152152
i2c_hw_t *hw;
153153
bool restart_on_next;
154-
uint32_t last_abort_reason;
155154
};
156155

156+
typedef struct i2c_result {
157+
int32_t rval;
158+
uint32_t abort_reason;
159+
} i2c_result_t;
160+
157161
/**
158162
* \def I2C_NUM(i2c)
159163
* \ingroup hardware_i2c
@@ -247,6 +251,7 @@ static inline i2c_inst_t *i2c_get_instance(uint num) {
247251
*
248252
* \return Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.
249253
*/
254+
i2c_result_t i2c_write_result_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until);
250255
int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop, absolute_time_t until);
251256

252257
/*! \brief Attempt to read specified number of bytes from address, blocking until the specified absolute time is reached.
@@ -261,6 +266,7 @@ int i2c_write_blocking_until(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src,
261266
* \param until The absolute time that the block will wait until the entire transaction is complete.
262267
* \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged, no device present, or PICO_ERROR_TIMEOUT if a timeout occurred.
263268
*/
269+
i2c_result_t i2c_read_result_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
264270
int i2c_read_blocking_until(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, absolute_time_t until);
265271

266272
/*! \brief Attempt to write specified number of bytes to address, with timeout
@@ -283,6 +289,7 @@ static inline int i2c_write_timeout_us(i2c_inst_t *i2c, uint8_t addr, const uint
283289
return i2c_write_blocking_until(i2c, addr, src, len, nostop, t);
284290
}
285291

292+
i2c_result_t i2c_write_result_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);
286293
int 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);
287294

288295
/*! \brief Attempt to read specified number of bytes from address, with timeout
@@ -302,6 +309,7 @@ static inline int i2c_read_timeout_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *ds
302309
return i2c_read_blocking_until(i2c, addr, dst, len, nostop, t);
303310
}
304311

312+
i2c_result_t i2c_read_result_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop, uint timeout_per_char_us);
305313
int 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);
306314

307315
/*! \brief Attempt to write specified number of bytes to address, blocking
@@ -315,6 +323,7 @@ int i2c_read_timeout_per_char_us(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, si
315323
* and the next transfer will begin with a Restart rather than a Start.
316324
* \return Number of bytes written, or PICO_ERROR_GENERIC if address not acknowledged, no device present.
317325
*/
326+
i2c_result_t i2c_write_result_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
318327
int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len, bool nostop);
319328

320329
/*! \brief Attempt to write specified number of bytes to address, blocking in burst mode
@@ -330,6 +339,7 @@ int i2c_write_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t
330339
* \param len Length of data in bytes to receive
331340
* \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.
332341
*/
342+
i2c_result_t i2c_write_result_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len);
333343
int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src, size_t len);
334344

335345
/*! \brief Attempt to read specified number of bytes from address, blocking
@@ -343,6 +353,7 @@ int i2c_write_burst_blocking(i2c_inst_t *i2c, uint8_t addr, const uint8_t *src,
343353
* and the next transfer will begin with a Restart rather than a Start.
344354
* \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.
345355
*/
356+
i2c_result_t i2c_read_result_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
346357
int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, bool nostop);
347358

348359
/*! \brief Attempt to read specified number of bytes from address, blocking in burst mode
@@ -358,6 +369,7 @@ int i2c_read_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len, b
358369
* \param len Length of data in bytes to receive
359370
* \return Number of bytes read, or PICO_ERROR_GENERIC if address not acknowledged or no device present.
360371
*/
372+
i2c_result_t i2c_read_result_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len);
361373
int i2c_read_burst_blocking(i2c_inst_t *i2c, uint8_t addr, uint8_t *dst, size_t len);
362374

363375
/*! \brief Determine non-blocking write space available

0 commit comments

Comments
 (0)