aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-04-29 12:06:08 +0000
committerGitHub <[email protected]>2024-04-29 12:06:08 +0000
commit679160a1c573709ccf2c54755e69ea9e1b5a209e (patch)
tree0eebf1c13267dfda3abb2359f77ec6528f70388d
parent49a90a3b9051a4c55e29ba98e5ccd13591806248 (diff)
parent5ce3a6b61ed7a4aaa48a687615e709d5d5309266 (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.rs26
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| {