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,21 +288,66 @@ int i2c_release(i2c_t dev)
|
|||||||
return 0;
|
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) { \
|
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); \
|
_i2c_reset_hw (dev); \
|
||||||
__asm__ volatile ("isync"); \
|
__asm__ volatile ("isync"); \
|
||||||
return -EAGAIN; \
|
return -EAGAIN; \
|
||||||
} \
|
} \
|
||||||
else if (_i2c_bus[dev].results & I2C_ACK_ERR_INT_ENA) { \
|
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); \
|
_i2c_reset_hw (dev); \
|
||||||
__asm__ volatile ("isync"); \
|
__asm__ volatile ("isync"); \
|
||||||
return -EIO; \
|
return -ENXIO; \
|
||||||
} \
|
} \
|
||||||
else if (_i2c_bus[dev].results & I2C_TIME_OUT_INT_ENA) { \
|
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"); \
|
||||||
|
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); \
|
_i2c_reset_hw (dev); \
|
||||||
__asm__ volatile ("isync"); \
|
__asm__ volatile ("isync"); \
|
||||||
return -ETIMEDOUT; \
|
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_read_cmd (dev, data, I2C_MAX_DATA, false);
|
||||||
_i2c_end_cmd (dev);
|
_i2c_end_cmd (dev);
|
||||||
_i2c_transfer (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 */
|
/* if transfer was successful, fetch the data from I2C RAM */
|
||||||
for (unsigned i = 0; i < I2C_MAX_DATA; i++) {
|
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 */
|
/* finish operation by executing the command pipeline */
|
||||||
_i2c_transfer (dev);
|
_i2c_transfer (dev);
|
||||||
_i2c_return_on_error (dev);
|
_i2c_return_on_error_read (dev);
|
||||||
|
|
||||||
/* if transfer was successful, fetch data from I2C RAM */
|
/* if transfer was successful, fetch data from I2C RAM */
|
||||||
for (unsigned i = 0; i < len; i++) {
|
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_write_cmd (dev, ((uint8_t*)data) + off, I2C_MAX_DATA);
|
||||||
_i2c_end_cmd (dev);
|
_i2c_end_cmd (dev);
|
||||||
_i2c_transfer (dev);
|
_i2c_transfer (dev);
|
||||||
_i2c_return_on_error (dev);
|
_i2c_return_on_error_write (dev);
|
||||||
|
|
||||||
len -= I2C_MAX_DATA;
|
len -= I2C_MAX_DATA;
|
||||||
off += 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 */
|
/* finish operation by executing the command pipeline */
|
||||||
_i2c_transfer (dev);
|
_i2c_transfer (dev);
|
||||||
_i2c_return_on_error (dev);
|
_i2c_return_on_error_write (dev);
|
||||||
|
|
||||||
/* return 0 on success */
|
/* return 0 on success */
|
||||||
return 0;
|
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) {
|
(res = _i2c_write_byte (bus, addr2)) != 0) {
|
||||||
/* abort transfer */
|
/* abort transfer */
|
||||||
_i2c_abort (bus, __func__);
|
_i2c_abort (bus, __func__);
|
||||||
return res;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if ((res = _i2c_write_byte (bus, (addr << 1 | I2C_READ))) != 0) {
|
||||||
/* abort transfer */
|
/* abort transfer */
|
||||||
_i2c_abort (bus, __func__);
|
_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) {
|
(res = _i2c_write_byte (bus, addr2)) != 0) {
|
||||||
/* abort transfer */
|
/* abort transfer */
|
||||||
_i2c_abort (bus, __func__);
|
_i2c_abort (bus, __func__);
|
||||||
return res;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if ((res = _i2c_write_byte (bus, addr << 1)) != 0) {
|
||||||
/* abort transfer */
|
/* abort transfer */
|
||||||
_i2c_abort (bus, __func__);
|
_i2c_abort (bus, __func__);
|
||||||
return res;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user