Skip to content

Commit 64aa5ad

Browse files
authored
Fixed timeout bug
The new logic for the timeout loop in read_from() and write_to() had a bug. It is now fixed.
1 parent ded4ed9 commit 64aa5ad

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

libraries/Wire/src/Wire.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern "C" {
3030
#include <inttypes.h>
3131
}
3232

33+
#include "Arduino.h"
3334
#include "Wire.h"
3435

3536
TwoWire *TwoWire::g_SCIWires[TWOWIRE_MAX_SCI_CHANNELS] = {nullptr};
@@ -211,6 +212,8 @@ TwoWire::TwoWire(int scl, int sda, WireAddressMode_t am /*= ADDRESS_MODE_7_BITS*
211212
s_i2c_cfg.txi_irq = FSP_INVALID_VECTOR;
212213
s_i2c_cfg.tei_irq = FSP_INVALID_VECTOR;
213214
s_i2c_cfg.tei_irq = FSP_INVALID_VECTOR;
215+
216+
214217
}
215218

216219
/* -------------------------------------------------------------------------- */
@@ -485,12 +488,13 @@ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, uint3
485488
}
486489
}
487490

488-
while( bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) {
489-
uint32_t const start = micros();
490-
if((timeout_us > 0ul) && ((micros() - start) > timeout_us)) {
491-
handleTimeout(do_reset_on_timeout);
492-
return 0;
493-
}
491+
uint32_t const start = micros();
492+
while (((timeout_us == 0ul) || ((millis() - start) < timeout_us)) &&
493+
bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) {
494+
}
495+
if ((err == FSP_SUCCESS) && (bus_status == WIRE_STATUS_UNSET)) {
496+
handleTimeout(do_reset_on_timeout);
497+
return 0;
494498
}
495499
}
496500

@@ -502,7 +506,7 @@ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, uint3
502506
}
503507

504508
/* -------------------------------------------------------------------------- */
505-
uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, uint32_t timeout_us /* micros */, bool sendStop) {
509+
uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, uint32_t timeout_us , bool sendStop) {
506510
/* -------------------------------------------------------------------------- */
507511
uint8_t rv = END_TX_OK;
508512
fsp_err_t err = FSP_ERR_ASSERTION;
@@ -517,12 +521,9 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, uint32
517521
}
518522
}
519523

520-
while( bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) {
521-
uint32_t const start = micros();
522-
if((timeout_us > 0ul) && ((micros() - start) > timeout_us)) {
523-
handleTimeout(do_reset_on_timeout);
524-
return END_TX_TIMEOUT;
525-
}
524+
uint32_t const start = micros();
525+
while (((timeout_us == 0ul) || ((millis() - start) < timeout_us)) &&
526+
bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) {
526527
}
527528

528529
if(err != FSP_SUCCESS) {
@@ -531,6 +532,10 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, uint32
531532
else if(data_too_long) {
532533
rv = END_TX_DATA_TOO_LONG;
533534
}
535+
else if(bus_status == WIRE_STATUS_UNSET) {
536+
rv = END_TX_TIMEOUT;
537+
handleTimeout(do_reset_on_timeout);
538+
}
534539
/* as far as I know is impossible to distinguish between NACK on ADDRESS and
535540
NACK on DATA */
536541
else if(bus_status == WIRE_STATUS_TRANSACTION_ABORTED) {
@@ -675,7 +680,6 @@ void TwoWire::clearWireTimeoutFlag(void){
675680
void TwoWire::handleTimeout(bool reset){
676681
/* -------------------------------------------------------------------------- */
677682
timed_out_flag = true;
678-
679683
if (reset) { //TBD; What do we do here? like fixHungWire()?
680684
// TBD, Is this the way to go to reset the bus?
681685
// Do we need more to handle devices that hangs the bus?
@@ -684,11 +688,11 @@ void TwoWire::handleTimeout(bool reset){
684688
fsp_err_t err = m_abort(&m_i2c_ctrl);
685689
}
686690
// TDB, Is this the right way to get back after reset?
687-
if(m_open != nullptr) {
688-
if(FSP_SUCCESS == m_open(&m_i2c_ctrl,&m_i2c_cfg)) {
689-
init_ok &= true;
690-
}
691-
}
691+
//if(m_open != nullptr) {
692+
// if(FSP_SUCCESS == m_open(&m_i2c_ctrl,&m_i2c_cfg)) {
693+
// init_ok &= true;
694+
// }
695+
//}
692696
}
693697
}
694698

libraries/Wire/src/Wire.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ using I2C_onTxCallback_f = void (*)(void);
6969
// WIRE_HAS_END means Wire has end()
7070
#define WIRE_HAS_END 1
7171

72+
// WIRE_HAS_TIMEOUT means Wire has setWireTimeout(), getWireTimeoutFlag
73+
// and clearWireTimeoutFlag()
74+
#define WIRE_HAS_TIMEOUT 1
75+
76+
// When not configured, these settings are used for the timeout
77+
#define WIRE_DEFAULT_TIMEOUT 25000
78+
#define WIRE_DEFAULT_RESET_WITH_TIMEOUT 0
79+
7280
#define END_TX_OK 0
7381
#define END_TX_DATA_TOO_LONG 1
7482
#define END_TX_NACK_ON_ADD 2

0 commit comments

Comments
 (0)