aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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| {