mirror of
https://github.com/andreili/klipper.git
synced 2025-08-23 19:34:06 +02:00
stm32: f0 make i2c distinguish I2C NACKs
Some devices can return a read NACK on host retries. When the MCU receives the I2C CMD, reads out data, but fails to deliver a response to the host. The host retries, the device returns NACK, and the MCU goes into the shutdown state. Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
This commit is contained in:
parent
c01e6eee1d
commit
1931b11001
@ -195,6 +195,7 @@ i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write)
|
|||||||
I2C_TypeDef *i2c = config.i2c;
|
I2C_TypeDef *i2c = config.i2c;
|
||||||
uint32_t timeout = timer_read_time() + timer_from_us(5000);
|
uint32_t timeout = timer_read_time() + timer_from_us(5000);
|
||||||
int ret = I2C_BUS_SUCCESS;
|
int ret = I2C_BUS_SUCCESS;
|
||||||
|
uint8_t *write_orig = write;
|
||||||
|
|
||||||
// Send start and address
|
// Send start and address
|
||||||
i2c->CR2 = (I2C_CR2_START | config.addr | (write_len << I2C_CR2_NBYTES_Pos)
|
i2c->CR2 = (I2C_CR2_START | config.addr | (write_len << I2C_CR2_NBYTES_Pos)
|
||||||
@ -207,6 +208,8 @@ i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write)
|
|||||||
}
|
}
|
||||||
return i2c_wait(i2c, I2C_ISR_TXE, timeout);
|
return i2c_wait(i2c, I2C_ISR_TXE, timeout);
|
||||||
abrt:
|
abrt:
|
||||||
|
if (write == write_orig && ret == I2C_BUS_NACK)
|
||||||
|
ret = I2C_BUS_START_NACK;
|
||||||
i2c->CR2 |= I2C_CR2_STOP;
|
i2c->CR2 |= I2C_CR2_STOP;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -218,6 +221,8 @@ i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg
|
|||||||
I2C_TypeDef *i2c = config.i2c;
|
I2C_TypeDef *i2c = config.i2c;
|
||||||
uint32_t timeout = timer_read_time() + timer_from_us(5000);
|
uint32_t timeout = timer_read_time() + timer_from_us(5000);
|
||||||
int ret = I2C_BUS_SUCCESS;
|
int ret = I2C_BUS_SUCCESS;
|
||||||
|
uint8_t *write_orig = reg;
|
||||||
|
uint8_t *read_orig = read;
|
||||||
|
|
||||||
// Send start, address, reg
|
// Send start, address, reg
|
||||||
i2c->CR2 = (I2C_CR2_START | config.addr |
|
i2c->CR2 = (I2C_CR2_START | config.addr |
|
||||||
@ -236,11 +241,16 @@ i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg
|
|||||||
while (read_len--) {
|
while (read_len--) {
|
||||||
ret = i2c_wait(i2c, I2C_ISR_RXNE, timeout);
|
ret = i2c_wait(i2c, I2C_ISR_RXNE, timeout);
|
||||||
if (ret != I2C_BUS_SUCCESS)
|
if (ret != I2C_BUS_SUCCESS)
|
||||||
goto abrt;
|
goto abrt_read;
|
||||||
*read++ = i2c->RXDR;
|
*read++ = i2c->RXDR;
|
||||||
}
|
}
|
||||||
return i2c_wait(i2c, I2C_ISR_STOPF, timeout);
|
return i2c_wait(i2c, I2C_ISR_STOPF, timeout);
|
||||||
|
abrt_read:
|
||||||
|
if (read == read_orig && ret == I2C_BUS_NACK)
|
||||||
|
ret = I2C_BUS_START_READ_NACK;
|
||||||
abrt:
|
abrt:
|
||||||
|
if (reg == write_orig && ret == I2C_BUS_NACK)
|
||||||
|
ret = I2C_BUS_START_NACK;
|
||||||
i2c->CR2 |= I2C_CR2_STOP;
|
i2c->CR2 |= I2C_CR2_STOP;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user