I2C fix READ of zero bytes hardware hang (#2301)
The i2c peripheral will hang if a READ request is issued with a zero data length. The peripheral drops into a continuous timeout interrupt response. The STOP command can not be set out to the I2C bus. The SLAVE device correctly ACK'd the address byte, with READ bit set, it has control of the SDA pin. The ESP32 send out the next SCL HIGH pulse but, since the SLAVE is in READ Mode, and the First bit it is sending happened to be a ZERO, the ESP32 cannot send the STOP. When it releases SDA during the SCL HIGH, the pin does not change state. The pin stays low because the SLAVE is outputing a LOW! The ESP32 drops into a perminent WAIT state waiting for SDA to go HIGH (the STOP). **esp32-hal-i2c.c** * add databuff length checks to `i2cRead()` and `i2cWrite()`
This commit is contained in:
parent
566b69eda3
commit
9a7946e685
@ -1609,6 +1609,9 @@ i2c_err_t i2cFlush(i2c_t * i2c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis){
|
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis){
|
||||||
|
if((i2c==NULL)||((size>0)&&(buff==NULL))) { // need to have location to store requested data
|
||||||
|
return I2C_ERROR_DEV;
|
||||||
|
}
|
||||||
i2c_err_t last_error = i2cAddQueueWrite(i2c, address, buff, size, sendStop, NULL);
|
i2c_err_t last_error = i2cAddQueueWrite(i2c, address, buff, size, sendStop, NULL);
|
||||||
|
|
||||||
if(last_error == I2C_ERROR_OK) { //queued
|
if(last_error == I2C_ERROR_OK) { //queued
|
||||||
@ -1628,6 +1631,9 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis, uint32_t *readCount){
|
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis, uint32_t *readCount){
|
||||||
|
if((size == 0)||(i2c == NULL)||(buff==NULL)){ // hardware will hang if no data requested on READ
|
||||||
|
return I2C_ERROR_DEV;
|
||||||
|
}
|
||||||
i2c_err_t last_error=i2cAddQueueRead(i2c, address, buff, size, sendStop, NULL);
|
i2c_err_t last_error=i2cAddQueueRead(i2c, address, buff, size, sendStop, NULL);
|
||||||
|
|
||||||
if(last_error == I2C_ERROR_OK) { //queued
|
if(last_error == I2C_ERROR_OK) { //queued
|
||||||
|
Loading…
Reference in New Issue
Block a user