diff options
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 13a473344..ac4fa1b9e 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -48,6 +48,32 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 48 | //reg.set_anfoff(false); | 48 | //reg.set_anfoff(false); |
| 49 | }); | 49 | }); |
| 50 | 50 | ||
| 51 | // Errata: "Start cannot be generated after a misplaced Stop" | ||
| 52 | // | ||
| 53 | // > If a master generates a misplaced Stop on the bus (bus error) | ||
| 54 | // > while the microcontroller I2C peripheral attempts to switch to | ||
| 55 | // > Master mode by setting the START bit, the Start condition is | ||
| 56 | // > not properly generated. | ||
| 57 | // | ||
| 58 | // This also can occur with falsely detected STOP events, for example | ||
| 59 | // if the SDA line is shorted to low. | ||
| 60 | // | ||
| 61 | // The workaround for this is to trigger the SWRST line AFTER power is | ||
| 62 | // enabled, AFTER PE is disabled and BEFORE making any other configuration. | ||
| 63 | // | ||
| 64 | // It COULD be possible to apply this workaround at runtime, instead of | ||
| 65 | // only on initialization, however this would require detecting the timeout | ||
| 66 | // or BUSY lockup condition, and re-configuring the peripheral after reset. | ||
| 67 | // | ||
| 68 | // This presents as an ~infinite hang on read or write, as the START condition | ||
| 69 | // is never generated, meaning the start event is never generated. | ||
| 70 | T::regs().cr1().modify(|reg| { | ||
| 71 | reg.set_swrst(true); | ||
| 72 | }); | ||
| 73 | T::regs().cr1().modify(|reg| { | ||
| 74 | reg.set_swrst(false); | ||
| 75 | }); | ||
| 76 | |||
| 51 | let timings = Timings::new(T::frequency(), freq); | 77 | let timings = Timings::new(T::frequency(), freq); |
| 52 | 78 | ||
| 53 | T::regs().cr2().modify(|reg| { | 79 | T::regs().cr2().modify(|reg| { |
