Skip to content

Commit 7a33286

Browse files
stickbreakerme-no-dev
authored andcommitted
I2C ReSTART returns Success (espressif#2141)
* Don't Return I2C_ERROR_CONTINUE on ReSTART ReSTART operations on the ESP32 have to be handled differently than on AVR chips, so ReSTART operations(`Wire.endTransmission(false), Wire.requestFrom(id,size,false);` are queued until a STOP is send (`Wire.endTransmission(TRUE), Wire.endTransmission(), Wire.requestFrom(id,size), Wire.requestFrom(id,size,TRUE)). To indicate the queuing I had used `I2C_ERROR_CONTINUE`, this caused compatibility issues with the existing Arduino I2C Code base. So, back to Lying to the public(for their own good of course) about success! This update just returns `I2C_ERROR_OK` on ReSTART commands. * add comments add comments * Change Return error for ReSTART operation to I2C_ERROR_OK This change restores compatibility with pre-existing Arduino Libraries. The ReSTART queuing operations are hidden behind the scenes. Wire.endTransmission(id,len,FALSE); will know return I2C_ERROR_OK instead of I2C_ERROR_CONTINUE, Wire.lastError() will return the true condition of I2C_ERROR_CONTINUE.
1 parent 8aa6e2e commit 7a33286

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

libraries/Wire/src/Wire.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,15 @@ void TwoWire::beginTransmission(uint16_t address)
154154
uint8_t TwoWire::endTransmission(bool sendStop) // Assumes Wire.beginTransaction(), Wire.write()
155155
{
156156
if(transmitting == 1) {
157+
// txlength is howmany bytes in txbuffer have been use
157158
last_error = writeTransmission(txAddress, &txBuffer[txQueued], txLength - txQueued, sendStop);
158-
rxIndex = 0;
159-
rxLength = rxQueued;
160-
rxQueued = 0;
161-
txQueued = 0; // the SendStop=true will restart all Queueing
162159
if(last_error == I2C_ERROR_CONTINUE){
163-
// txlength is howmany bytes in txbuffer have been use
164160
txQueued = txLength;
161+
} else if( last_error == I2C_ERROR_OK){
162+
rxIndex = 0;
163+
rxLength = rxQueued;
164+
rxQueued = 0;
165+
txQueued = 0; // the SendStop=true will restart all Queueing
165166
}
166167
} else {
167168
last_error = I2C_ERROR_NO_BEGIN;
@@ -170,7 +171,7 @@ uint8_t TwoWire::endTransmission(bool sendStop) // Assumes Wire.beginTransactio
170171
txIndex = 0;
171172
txLength = 0;
172173
transmitting = 0;
173-
return last_error;
174+
return (last_error == I2C_ERROR_CONTINUE)?I2C_ERROR_OK:last_error; // Don't return Continue for compatibility.
174175
}
175176

176177
/* @stickBreaker 11/2017 fix for ReSTART timeout, ISR
@@ -191,12 +192,19 @@ uint8_t TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop)
191192

192193
last_error = readTransmission(address, &rxBuffer[cnt], size, sendStop, &cnt);
193194
rxIndex = 0;
194-
rxLength = rxQueued;
195-
rxQueued = 0;
196-
txQueued = 0; // the SendStop=true will restart all Queueing
197-
if(last_error != I2C_ERROR_OK){
195+
196+
rxLength = cnt;
197+
198+
if( last_error != I2C_ERROR_CONTINUE){ // not a buffered ReSTART operation
199+
// so this operation actually moved data, queuing is done.
200+
rxQueued = 0;
201+
txQueued = 0; // the SendStop=true will restart all Queueing or error condition
202+
}
203+
204+
if(last_error != I2C_ERROR_OK){ // ReSTART on read does not return any data
198205
cnt = 0;
199206
}
207+
200208
return cnt;
201209
}
202210

libraries/Wire/src/Wire.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,13 @@ class TwoWire: public Stream
6767
public:
6868
TwoWire(uint8_t bus_num);
6969
~TwoWire();
70-
bool begin(int sda=-1, int scl=-1, uint32_t frequency=0);
70+
bool begin(int sda=-1, int scl=-1, uint32_t frequency=0); // returns true, if successful init of i2c bus
71+
// calling will attemp to recover hung bus
7172

7273
void setClock(uint32_t frequency); // change bus clock without initing hardware
7374
size_t getClock(); // current bus clock rate in hz
7475

75-
void setTimeOut(uint16_t timeOutMillis);
76+
void setTimeOut(uint16_t timeOutMillis); // default timeout of i2c transactions is 50ms
7677
uint16_t getTimeOut();
7778

7879
uint8_t lastError();
@@ -137,6 +138,7 @@ extern TwoWire Wire1;
137138

138139

139140
/*
141+
V1.0.2 30NOV2018 stop returning I2C_ERROR_CONTINUE on ReSTART operations, regain compatibility with Arduino libs
140142
V1.0.1 02AUG2018 First Fix after release, Correct ReSTART handling, change Debug control, change begin()
141143
to a function, this allow reporting if bus cannot be initialized, Wire.begin() can be used to recover
142144
a hung bus busy condition.

0 commit comments

Comments
 (0)