Skip to content

Commit f1fe5e8

Browse files
matthijskooijmanfacchinm
authored andcommitted
Wire: improve comments on timeout
1 parent 38ff552 commit f1fe5e8

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

Diff for: libraries/Wire/src/Wire.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,28 @@ void TwoWire::setClock(uint32_t clock)
9090
/***
9191
* Sets the TWI timeout.
9292
*
93+
* This limits the maximum time to wait for the TWI hardware. If more time passes, the bus is assumed
94+
* to have locked up (e.g. due to noise-induced glitches or faulty slaves) and the transaction is aborted.
95+
* Optionally, the TWI hardware is also reset, which can be required to allow subsequent transactions to
96+
* succeed in some cases (in particular when noise has made the TWI hardware think there is a second
97+
* master that has claimed the bus).
98+
*
99+
* When a timeout is triggered, a flag is set that can be queried with `getWireTimeoutFlag()` and is cleared
100+
* when `clearWireTimeoutFlag()` or `setWireTimeoutUs()` is called.
101+
*
102+
* Note that this timeout can also trigger while waiting for clock stretching or waiting for a second master
103+
* to complete its transaction. So make sure to adapt the timeout to accomodate for those cases if needed.
104+
* A typical timeout would be 25ms (which is the maximum clock stretching allowed by the SMBus protocol),
105+
* but (much) shorter values will usually also work.
106+
*
107+
* In the future, a timeout will be enabled by default, so if you require the timeout to be disabled, it is
108+
* recommended you disable it by default using `setWireTimeoutUs(0)`, even though that is currently
109+
* the default.
110+
*
93111
* @param timeout a timeout value in microseconds, if zero then timeout checking is disabled
94112
* @param reset_with_timeout if true then TWI interface will be automatically reset on timeout
95113
* if false then TWI interface will not be reset on timeout
114+
96115
*/
97116
void TwoWire::setWireTimeout(uint32_t timeout, bool reset_with_timeout){
98117
twi_setTimeoutInMicros(timeout, reset_with_timeout);
@@ -101,7 +120,7 @@ void TwoWire::setWireTimeout(uint32_t timeout, bool reset_with_timeout){
101120
/***
102121
* Returns the TWI timeout flag.
103122
*
104-
* @return true if timeout has occured
123+
* @return true if timeout has occured since the flag was last cleared.
105124
*/
106125
bool TwoWire::getWireTimeoutFlag(void){
107126
return(twi_manageTimeoutFlag(false));

Diff for: libraries/Wire/src/utility/twi.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,9 @@ void twi_stop(void)
413413

414414
// wait for stop condition to be exectued on bus
415415
// TWINT is not set after a stop condition!
416-
volatile uint32_t counter = twi_timeout_us/10ul; // approximate the timeout
416+
// We cannot use micros() from an ISR, so approximate the timeout with cycle-counted delays
417+
const uint8_t us_per_loop = 8;
418+
uint32_t counter = (twi_timeout_us + us_per_loop - 1)/us_per_loop; // Round up
417419
while(TWCR & _BV(TWSTO)){
418420
if(twi_timeout_us > 0ul){
419421
if (counter > 0ul){

0 commit comments

Comments
 (0)