I2C ReSTART returns Success (#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.
This commit is contained in:
		
							parent
							
								
									8aa6e2e143
								
							
						
					
					
						commit
						7a332864ab
					
				| @ -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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user