diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-04-29 12:06:08 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-04-29 12:06:08 +0000 |
| commit | 679160a1c573709ccf2c54755e69ea9e1b5a209e (patch) | |
| tree | 0eebf1c13267dfda3abb2359f77ec6528f70388d | |
| parent | 49a90a3b9051a4c55e29ba98e5ccd13591806248 (diff) | |
| parent | 5ce3a6b61ed7a4aaa48a687615e709d5d5309266 (diff) | |
Merge pull request #2887 from jamesmunns/james/stm32-i2cv1-errata
stm32: Add workaround for STM32 i2cv1 errata
| -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| { |
