Skip to content

Commit 0938055

Browse files
committed
Add Wire timeout
Enable Wire timeout py adding -DWIRE_TIMEOUT as a compiler flag, or by incommening a line in Wire_timeout.h
1 parent 525170b commit 0938055

File tree

7 files changed

+272
-62
lines changed

7 files changed

+272
-62
lines changed

avr/libraries/Wire/keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ endTransmission KEYWORD2
1717
requestFrom KEYWORD2
1818
onReceive KEYWORD2
1919
onRequest KEYWORD2
20+
setWireTimeout KEYWORD2
21+
getWireTimeoutFlag KEYWORD2
22+
clearWireTimeoutFlag KEYWORD2
2023

2124
#######################################
2225
# Instances (KEYWORD2)

avr/libraries/Wire/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Wire
2-
version=1.0
2+
version=1.1
33
author=Arduino
44
maintainer=MCUdude
55
sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus.

avr/libraries/Wire/src/Wire.cpp

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
TwoWire.cpp - TWI/I2C library for Wiring & Arduino
2+
Wire.cpp - TWI/I2C library for Wiring & Arduino
33
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
44
55
This library is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@
1919
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
2020
Modified 2017 by Chuck Todd (ctodd@cableone.net) to correct Unconfigured Slave Mode reboot
2121
Modified 2020 by Asuki Kono (asukiaaa@gmail.com) to use TwoWire class for Wire1
22+
Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts
2223
*/
2324

2425
extern "C" {
@@ -122,6 +123,54 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
122123
return read;
123124
}
124125

126+
#if defined(WIRE_TIMEOUT)
127+
/**
128+
* Sets the TWI timeout.
129+
*
130+
* This limits the maximum time to wait for the TWI hardware. If more time passes, the bus is assumed
131+
* to have locked up (e.g. due to noise-induced glitches or faulty slaves) and the transaction is aborted.
132+
* Optionally, the TWI hardware is also reset, which can be required to allow subsequent transactions to
133+
* succeed in some cases (in particular when noise has made the TWI hardware think there is a second
134+
* master that has claimed the bus).
135+
*
136+
* When a timeout is triggered, a flag is set that can be queried with `getWireTimeoutFlag()` and is cleared
137+
* when `clearWireTimeoutFlag()` or `setWireTimeoutUs()` is called.
138+
*
139+
* Note that this timeout can also trigger while waiting for clock stretching or waiting for a second master
140+
* to complete its transaction. So make sure to adapt the timeout to accomodate for those cases if needed.
141+
* A typical timeout would be 25ms (which is the maximum clock stretching allowed by the SMBus protocol),
142+
* but (much) shorter values will usually also work.
143+
*
144+
* In the future, a timeout will be enabled by default, so if you require the timeout to be disabled, it is
145+
* recommended you disable it by default using `setWireTimeoutUs(0)`, even though that is currently
146+
* the default.
147+
*
148+
* @param timeout a timeout value in microseconds, if zero then timeout checking is disabled
149+
* @param reset_with_timeout if true then TWI interface will be automatically reset on timeout
150+
* if false then TWI interface will not be reset on timeout
151+
152+
*/
153+
void TwoWire::setWireTimeout(uint32_t timeout, bool reset_with_timeout){
154+
twi_setTimeoutInMicros(timeout, reset_with_timeout);
155+
}
156+
157+
/**
158+
* Returns the TWI timeout flag.
159+
*
160+
* @return true if timeout has occured since the flag was last cleared.
161+
*/
162+
bool TwoWire::getWireTimeoutFlag(void){
163+
return(twi_manageTimeoutFlag(false));
164+
}
165+
166+
/**
167+
* Clears the TWI timeout flag.
168+
*/
169+
void TwoWire::clearWireTimeoutFlag(void){
170+
twi_manageTimeoutFlag(true);
171+
}
172+
#endif // WIRE_TIMEOUT
173+
125174
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
126175
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop);
127176
}
@@ -161,8 +210,8 @@ void TwoWire::beginTransmission(int address)
161210
// Originally, 'endTransmission' was an f(void) function.
162211
// It has been modified to take one parameter indicating
163212
// whether or not a STOP should be performed on the bus.
164-
// Calling endTransmission(false) allows a sketch to
165-
// perform a repeated start.
213+
// Calling endTransmission(false) allows a sketch to
214+
// perform a repeated start.
166215
//
167216
// WARNING: Nothing in the library keeps track of whether
168217
// the bus tenure has been properly ended with a STOP. It

avr/libraries/Wire/src/Wire.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <Arduino.h>
2727
#include <inttypes.h>
2828
#include "Stream.h"
29+
#include "Wire_timeout.h"
2930

3031

3132
// WIRE_HAS_END means Wire has end()
@@ -57,6 +58,11 @@ class TwoWire : public Stream
5758
void begin(int);
5859
void end();
5960
void setClock(uint32_t);
61+
#if defined(WIRE_TIMEOUT)
62+
void setWireTimeout(uint32_t timeout = 25000, bool reset_with_timeout = false);
63+
bool getWireTimeoutFlag(void);
64+
void clearWireTimeoutFlag(void);
65+
#endif
6066
void beginTransmission(uint8_t);
6167
void beginTransmission(int);
6268
uint8_t endTransmission(void);

avr/libraries/Wire/src/Wire_timeout.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Enable Wire timeout by uncommenting the line below
2+
#ifndef WIRE_TIMEOUT
3+
#define WIRE_TIMEOUT
4+
#endif

0 commit comments

Comments
 (0)