aboutsummaryrefslogtreecommitdiff
path: root/libraries/Wire/src/Wire.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/Wire/src/Wire.cpp')
-rw-r--r--libraries/Wire/src/Wire.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp
index 58916ce..c407776 100644
--- a/libraries/Wire/src/Wire.cpp
+++ b/libraries/Wire/src/Wire.cpp
@@ -18,6 +18,7 @@
Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
Modified 2017 by Chuck Todd (ctodd@cableone.net) to correct Unconfigured Slave Mode reboot
+ Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts
*/
extern "C" {
@@ -86,6 +87,52 @@ void TwoWire::setClock(uint32_t clock)
twi_setFrequency(clock);
}
+/***
+ * Sets the TWI timeout.
+ *
+ * This limits the maximum time to wait for the TWI hardware. If more time passes, the bus is assumed
+ * to have locked up (e.g. due to noise-induced glitches or faulty slaves) and the transaction is aborted.
+ * Optionally, the TWI hardware is also reset, which can be required to allow subsequent transactions to
+ * succeed in some cases (in particular when noise has made the TWI hardware think there is a second
+ * master that has claimed the bus).
+ *
+ * When a timeout is triggered, a flag is set that can be queried with `getWireTimeoutFlag()` and is cleared
+ * when `clearWireTimeoutFlag()` or `setWireTimeoutUs()` is called.
+ *
+ * Note that this timeout can also trigger while waiting for clock stretching or waiting for a second master
+ * to complete its transaction. So make sure to adapt the timeout to accomodate for those cases if needed.
+ * A typical timeout would be 25ms (which is the maximum clock stretching allowed by the SMBus protocol),
+ * but (much) shorter values will usually also work.
+ *
+ * In the future, a timeout will be enabled by default, so if you require the timeout to be disabled, it is
+ * recommended you disable it by default using `setWireTimeoutUs(0)`, even though that is currently
+ * the default.
+ *
+ * @param timeout a timeout value in microseconds, if zero then timeout checking is disabled
+ * @param reset_with_timeout if true then TWI interface will be automatically reset on timeout
+ * if false then TWI interface will not be reset on timeout
+
+ */
+void TwoWire::setWireTimeout(uint32_t timeout, bool reset_with_timeout){
+ twi_setTimeoutInMicros(timeout, reset_with_timeout);
+}
+
+/***
+ * Returns the TWI timeout flag.
+ *
+ * @return true if timeout has occured since the flag was last cleared.
+ */
+bool TwoWire::getWireTimeoutFlag(void){
+ return(twi_manageTimeoutFlag(false));
+}
+
+/***
+ * Clears the TWI timeout flag.
+ */
+void TwoWire::clearWireTimeoutFlag(void){
+ twi_manageTimeoutFlag(true);
+}
+
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop)
{
if (isize > 0) {