diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 87ed627b..bc580147 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -154,14 +154,15 @@ void TwoWire::beginTransmission(uint16_t address) uint8_t TwoWire::endTransmission(bool sendStop) // Assumes Wire.beginTransaction(), Wire.write() { if(transmitting == 1) { - last_error = writeTransmission(txAddress, &txBuffer[txQueued], txLength - txQueued, sendStop); - rxIndex = 0; - rxLength = rxQueued; - rxQueued = 0; - txQueued = 0; // the SendStop=true will restart all Queueing - if(last_error == I2C_ERROR_CONTINUE){ // txlength is howmany bytes in txbuffer have been use + last_error = writeTransmission(txAddress, &txBuffer[txQueued], txLength - txQueued, sendStop); + if(last_error == I2C_ERROR_CONTINUE){ txQueued = txLength; + } else if( last_error == I2C_ERROR_OK){ + rxIndex = 0; + rxLength = rxQueued; + rxQueued = 0; + txQueued = 0; // the SendStop=true will restart all Queueing } } else { last_error = I2C_ERROR_NO_BEGIN; @@ -170,7 +171,7 @@ uint8_t TwoWire::endTransmission(bool sendStop) // Assumes Wire.beginTransactio txIndex = 0; txLength = 0; transmitting = 0; - return last_error; + return (last_error == I2C_ERROR_CONTINUE)?I2C_ERROR_OK:last_error; // Don't return Continue for compatibility. } /* @stickBreaker 11/2017 fix for ReSTART timeout, ISR @@ -191,12 +192,19 @@ uint8_t TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop) last_error = readTransmission(address, &rxBuffer[cnt], size, sendStop, &cnt); rxIndex = 0; - rxLength = rxQueued; - rxQueued = 0; - txQueued = 0; // the SendStop=true will restart all Queueing - if(last_error != I2C_ERROR_OK){ + + rxLength = cnt; + + if( last_error != I2C_ERROR_CONTINUE){ // not a buffered ReSTART operation + // so this operation actually moved data, queuing is done. + rxQueued = 0; + txQueued = 0; // the SendStop=true will restart all Queueing or error condition + } + + if(last_error != I2C_ERROR_OK){ // ReSTART on read does not return any data cnt = 0; } + return cnt; } diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 34bdd60a..031ea3e5 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -67,12 +67,13 @@ protected: public: TwoWire(uint8_t bus_num); ~TwoWire(); - bool begin(int sda=-1, int scl=-1, uint32_t frequency=0); + bool begin(int sda=-1, int scl=-1, uint32_t frequency=0); // returns true, if successful init of i2c bus + // calling will attemp to recover hung bus void setClock(uint32_t frequency); // change bus clock without initing hardware size_t getClock(); // current bus clock rate in hz - void setTimeOut(uint16_t timeOutMillis); + void setTimeOut(uint16_t timeOutMillis); // default timeout of i2c transactions is 50ms uint16_t getTimeOut(); uint8_t lastError(); @@ -137,6 +138,7 @@ extern TwoWire Wire1; /* +V1.0.2 30NOV2018 stop returning I2C_ERROR_CONTINUE on ReSTART operations, regain compatibility with Arduino libs V1.0.1 02AUG2018 First Fix after release, Correct ReSTART handling, change Debug control, change begin() to a function, this allow reporting if bus cannot be initialized, Wire.begin() can be used to recover a hung bus busy condition.