Skip to content

Commit 2d9b911

Browse files
committed
Re-initialize I2C in a way that is safe from the ISR
Originally I2C was polled from the main loop, so it didn't matter that we did a full re-initialization of the peripheral on error. That calls into mbed, does lots of busy looping and waiting, and is generally slow. However as of 803a988 I2C is now polled from the ISR. That means we can't do crazy stuff like that any more. Instead, we do the minimum the datasheet requires, which is to disable the I2C peripheral, wait for its enable flag to report as 0, then re-enable it.
1 parent 79414d0 commit 2d9b911

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

fw/stm32_i2c.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,14 @@ class Stm32I2c {
142142
}
143143
if (mode_ == Mode::kError) {
144144
// Re-initialize.
145-
Initialize();
145+
i2c_->CR1 &= ~(I2C_CR1_PE);
146+
147+
if ((i2c_->CR1 & I2C_CR1_PE) == 0) {
148+
// The peripheral is off and ready be re-enabled.
149+
mode_ = Mode::kIdle;
150+
i2c_->CR1 |= I2C_CR1_PE;
151+
}
146152

147-
mode_ = Mode::kIdle;
148153
return ReadStatus::kError;
149154
}
150155
return ReadStatus::kNoStatus;

0 commit comments

Comments
 (0)