Skip to content

Commit

Permalink
Re-initialize I2C in a way that is safe from the ISR
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jpieper committed Dec 14, 2023
1 parent 79414d0 commit 2d9b911
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions fw/stm32_i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,14 @@ class Stm32I2c {
}
if (mode_ == Mode::kError) {
// Re-initialize.
Initialize();
i2c_->CR1 &= ~(I2C_CR1_PE);

if ((i2c_->CR1 & I2C_CR1_PE) == 0) {
// The peripheral is off and ready be re-enabled.
mode_ = Mode::kIdle;
i2c_->CR1 |= I2C_CR1_PE;
}

mode_ = Mode::kIdle;
return ReadStatus::kError;
}
return ReadStatus::kNoStatus;
Expand Down

0 comments on commit 2d9b911

Please sign in to comment.