kopia lustrzana https://github.com/micropython/micropython
stm32/i2c: Fix generation of restart condition for hw I2C on F0/F7.
Before this patch I2C transactions using a hardware I2C peripheral on F0/F7 MCUs would not correctly generate the I2C restart condition, and instead would generate a stop followed by a start. This is because the CR2 AUTOEND bit was being set before CR2 START when the peripheral already had the I2C bus from a previous transaction that did not generate a stop. As a consequence all combined transactions, eg read-then-write for an I2C memory transfer, generated a stop condition after the first transaction and didn't generate a stop at the very end (but still released the bus). Some I2C devices require a repeated start to function correctly. This patch fixes this by making sure the CR2 AUTOEND bit is set after the start condition and slave address have been fully transferred out.pull/4894/head
rodzic
eb7eed5d92
commit
3eff81288c
|
@ -340,8 +340,7 @@ STATIC int i2c_wait_isr_set(i2c_t *i2c, uint32_t mask) {
|
|||
int i2c_start_addr(i2c_t *i2c, int rd_wrn, uint16_t addr, size_t len, bool stop) {
|
||||
// Enable the peripheral and send the START condition with slave address
|
||||
i2c->CR1 |= I2C_CR1_PE;
|
||||
i2c->CR2 = stop << I2C_CR2_AUTOEND_Pos
|
||||
| (len > 1) << I2C_CR2_RELOAD_Pos
|
||||
i2c->CR2 = (len > 1) << I2C_CR2_RELOAD_Pos
|
||||
| (len > 0) << I2C_CR2_NBYTES_Pos
|
||||
| rd_wrn << I2C_CR2_RD_WRN_Pos
|
||||
| (addr & 0x7f) << 1;
|
||||
|
@ -361,6 +360,11 @@ int i2c_start_addr(i2c_t *i2c, int rd_wrn, uint16_t addr, size_t len, bool stop)
|
|||
return -MP_ENODEV;
|
||||
}
|
||||
|
||||
// Configure automatic STOP if needed
|
||||
if (stop) {
|
||||
i2c->CR2 |= I2C_CR2_AUTOEND;
|
||||
}
|
||||
|
||||
// Repurpose OAR1 to indicate that we loaded CR2
|
||||
i2c->OAR1 = 1;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue