Unverified Commit 8ac616e8 authored by ZinnerC's avatar ZinnerC Committed by GitHub

Adding capability to enable timeout for I2C (#1793)

parent 3ce90218
...@@ -262,6 +262,9 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) { ...@@ -262,6 +262,9 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) {
_buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(_timeout)); _buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(_timeout));
if ((_buffLen == PICO_ERROR_GENERIC) || (_buffLen == PICO_ERROR_TIMEOUT)) { if ((_buffLen == PICO_ERROR_GENERIC) || (_buffLen == PICO_ERROR_TIMEOUT)) {
if (_buffLen == PICO_ERROR_TIMEOUT) {
_handleTimeout(_reset_with_timeout);
}
_buffLen = 0; _buffLen = 0;
} }
_buffOff = 0; _buffOff = 0;
...@@ -335,12 +338,32 @@ stop: ...@@ -335,12 +338,32 @@ stop:
return ack; return ack;
} }
void TwoWire::_handleTimeout(bool reset) {
_timeoutFlag = true;
if (reset) {
if (_slave) {
uint8_t prev_addr = _addr;
int prev_clkHz = _clkHz;
end();
setClock(prev_clkHz);
begin(prev_addr);
} else {
int prev_clkHz = _clkHz;
end();
setClock(prev_clkHz);
begin();
}
}
}
// Errors: // Errors:
// 0 : Success // 0 : Success
// 1 : Data too long // 1 : Data too long
// 2 : NACK on transmit of address // 2 : NACK on transmit of address
// 3 : NACK on transmit of data // 3 : NACK on transmit of data
// 4 : Other error // 4 : Other error
// 5 : Timeout
uint8_t TwoWire::endTransmission(bool stopBit) { uint8_t TwoWire::endTransmission(bool stopBit) {
if (!_running || !_txBegun) { if (!_running || !_txBegun) {
return 4; return 4;
...@@ -352,6 +375,10 @@ uint8_t TwoWire::endTransmission(bool stopBit) { ...@@ -352,6 +375,10 @@ uint8_t TwoWire::endTransmission(bool stopBit) {
} else { } else {
auto len = _buffLen; auto len = _buffLen;
auto ret = i2c_write_blocking_until(_i2c, _addr, _buff, _buffLen, !stopBit, make_timeout_time_ms(_timeout)); auto ret = i2c_write_blocking_until(_i2c, _addr, _buff, _buffLen, !stopBit, make_timeout_time_ms(_timeout));
if (ret == PICO_ERROR_TIMEOUT) {
_handleTimeout(_reset_with_timeout);
return 5;
}
_buffLen = 0; _buffLen = 0;
return (ret == len) ? 0 : 4; return (ret == len) ? 0 : 4;
} }
...@@ -422,6 +449,20 @@ void TwoWire::onRequest(void(*function)(void)) { ...@@ -422,6 +449,20 @@ void TwoWire::onRequest(void(*function)(void)) {
_onRequestCallback = function; _onRequestCallback = function;
} }
void TwoWire::setTimeout(uint32_t timeout, bool reset_with_timeout) {
_timeoutFlag = false;
Stream::setTimeout(timeout);
_reset_with_timeout = reset_with_timeout;
}
bool TwoWire::getTimeoutFlag() {
return _timeoutFlag;
}
void TwoWire::clearTimeoutFlag() {
_timeoutFlag = false;
}
#ifndef __WIRE0_DEVICE #ifndef __WIRE0_DEVICE
#define __WIRE0_DEVICE i2c0 #define __WIRE0_DEVICE i2c0
#endif #endif
......
...@@ -82,6 +82,10 @@ public: ...@@ -82,6 +82,10 @@ public:
} }
using Print::write; using Print::write;
void setTimeout(uint32_t timeout = 25, bool reset_with_timeout = false); // sets the maximum number of milliseconds to wait
bool getTimeoutFlag(void);
void clearTimeoutFlag(void);
// IRQ callback // IRQ callback
void onIRQ(); void onIRQ();
...@@ -96,6 +100,10 @@ private: ...@@ -96,6 +100,10 @@ private:
uint8_t _addr; uint8_t _addr;
bool _txBegun; bool _txBegun;
bool _timeoutFlag;
bool _reset_with_timeout;
void _handleTimeout(bool reset);
uint8_t _buff[WIRE_BUFFER_SIZE]; uint8_t _buff[WIRE_BUFFER_SIZE];
int _buffLen; int _buffLen;
int _buffOff; int _buffOff;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment