cpu/esp32: fix errno for I2C addr ack error
fixup! cpu/esp32: fix errno for I2C addr ack error
This commit is contained in:
parent
8c8306e1ca
commit
cb8b1b12c1
@ -288,23 +288,68 @@ int i2c_release(i2c_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _i2c_return_on_error(dev) \
|
||||
/*
|
||||
* This macro checks the result of a read transfer. In case of an error,
|
||||
* the hardware is reset and returned with a corresponding error code.
|
||||
*
|
||||
* @note:
|
||||
* In a read transfer, an ACK is only expected for the address field. Thus,
|
||||
* an ACK error can only happen for the address field. Therefore, we always
|
||||
* return -ENXIO in case of an ACK error.
|
||||
*/
|
||||
#define _i2c_return_on_error_read(dev) \
|
||||
if (_i2c_bus[dev].results & I2C_ARBITRATION_LOST_INT_ENA) { \
|
||||
LOG_TAG_ERROR("i2c", "arbitration lost dev=%u\n", dev); \
|
||||
LOG_TAG_DEBUG("i2c", "arbitration lost dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -EAGAIN; \
|
||||
} \
|
||||
else if (_i2c_bus[dev].results & I2C_ACK_ERR_INT_ENA) { \
|
||||
LOG_TAG_ERROR("i2c", "ack error dev=%u\n", dev); \
|
||||
LOG_TAG_DEBUG("i2c", "ack error dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -EIO; \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -ENXIO; \
|
||||
} \
|
||||
else if (_i2c_bus[dev].results & I2C_TIME_OUT_INT_ENA) { \
|
||||
LOG_TAG_ERROR("i2c", "bus timeout dev=%u\n", dev); \
|
||||
LOG_TAG_DEBUG("i2c", "bus timeout dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -ETIMEDOUT; \
|
||||
}
|
||||
|
||||
/*
|
||||
* This macro checks the result of a write transfer. In case of an error,
|
||||
* the hardware is reset and returned with a corresponding error code.
|
||||
*
|
||||
* @note:
|
||||
* In a write transfer, an ACK error can happen for the address field
|
||||
* as well as for data. If the FIFO still contains all data bytes,
|
||||
* (i.e. _i2c_hw[dev].regs->status_reg.tx_fifo_cnt >= len), the ACK error
|
||||
* happened in address field and we have to returen -ENXIO. Otherwise, the
|
||||
* ACK error happened in data field and we have to return -EIO.
|
||||
*/
|
||||
#define _i2c_return_on_error_write(dev) \
|
||||
if (_i2c_bus[dev].results & I2C_ARBITRATION_LOST_INT_ENA) { \
|
||||
LOG_TAG_DEBUG("i2c", "arbitration lost dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -EAGAIN; \
|
||||
} \
|
||||
else if (_i2c_bus[dev].results & I2C_ACK_ERR_INT_ENA) { \
|
||||
LOG_TAG_DEBUG("i2c", "ack error dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
if (_i2c_hw[dev].regs->status_reg.tx_fifo_cnt >= len) { \
|
||||
return -ENXIO; \
|
||||
} \
|
||||
else { \
|
||||
return -EIO; \
|
||||
} \
|
||||
} \
|
||||
else if (_i2c_bus[dev].results & I2C_TIME_OUT_INT_ENA) { \
|
||||
LOG_TAG_DEBUG("i2c", "bus timeout dev=%u\n", dev); \
|
||||
_i2c_reset_hw (dev); \
|
||||
__asm__ volatile ("isync"); \
|
||||
return -ETIMEDOUT; \
|
||||
}
|
||||
|
||||
@ -350,7 +395,7 @@ int i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len, uint8_t fla
|
||||
_i2c_read_cmd (dev, data, I2C_MAX_DATA, false);
|
||||
_i2c_end_cmd (dev);
|
||||
_i2c_transfer (dev);
|
||||
_i2c_return_on_error (dev);
|
||||
_i2c_return_on_error_read (dev);
|
||||
|
||||
/* if transfer was successful, fetch the data from I2C RAM */
|
||||
for (unsigned i = 0; i < I2C_MAX_DATA; i++) {
|
||||
@ -380,7 +425,7 @@ int i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len, uint8_t fla
|
||||
|
||||
/* finish operation by executing the command pipeline */
|
||||
_i2c_transfer (dev);
|
||||
_i2c_return_on_error (dev);
|
||||
_i2c_return_on_error_read (dev);
|
||||
|
||||
/* if transfer was successful, fetch data from I2C RAM */
|
||||
for (unsigned i = 0; i < len; i++) {
|
||||
@ -437,7 +482,7 @@ int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_t len, uint
|
||||
_i2c_write_cmd (dev, ((uint8_t*)data) + off, I2C_MAX_DATA);
|
||||
_i2c_end_cmd (dev);
|
||||
_i2c_transfer (dev);
|
||||
_i2c_return_on_error (dev);
|
||||
_i2c_return_on_error_write (dev);
|
||||
|
||||
len -= I2C_MAX_DATA;
|
||||
off += I2C_MAX_DATA;
|
||||
@ -458,7 +503,7 @@ int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_t len, uint
|
||||
|
||||
/* finish operation by executing the command pipeline */
|
||||
_i2c_transfer (dev);
|
||||
_i2c_return_on_error (dev);
|
||||
_i2c_return_on_error_write (dev);
|
||||
|
||||
/* return 0 on success */
|
||||
return 0;
|
||||
|
||||
@ -225,7 +225,7 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
|
||||
(res = _i2c_write_byte (bus, addr2)) != 0) {
|
||||
/* abort transfer */
|
||||
_i2c_abort (bus, __func__);
|
||||
return res;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -233,7 +233,7 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
|
||||
if ((res = _i2c_write_byte (bus, (addr << 1 | I2C_READ))) != 0) {
|
||||
/* abort transfer */
|
||||
_i2c_abort (bus, __func__);
|
||||
return res;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,7 +286,7 @@ int /* IRAM */ i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_
|
||||
(res = _i2c_write_byte (bus, addr2)) != 0) {
|
||||
/* abort transfer */
|
||||
_i2c_abort (bus, __func__);
|
||||
return res;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -294,7 +294,7 @@ int /* IRAM */ i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_
|
||||
if ((res = _i2c_write_byte (bus, addr << 1)) != 0) {
|
||||
/* abort transfer */
|
||||
_i2c_abort (bus, __func__);
|
||||
return res;
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user