aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/i2c/config.rs14
-rw-r--r--embassy-stm32/src/i2c/mod.rs11
-rw-r--r--embassy-stm32/src/i2c/v1.rs18
-rw-r--r--embassy-stm32/src/i2c/v2.rs4
4 files changed, 24 insertions, 23 deletions
diff --git a/embassy-stm32/src/i2c/config.rs b/embassy-stm32/src/i2c/config.rs
index daae43bcd..0b4e091b8 100644
--- a/embassy-stm32/src/i2c/config.rs
+++ b/embassy-stm32/src/i2c/config.rs
@@ -109,6 +109,10 @@ impl SlaveAddrConfig {
109#[non_exhaustive] 109#[non_exhaustive]
110#[derive(Copy, Clone)] 110#[derive(Copy, Clone)]
111pub struct Config { 111pub struct Config {
112 /// Frequency
113 pub frequency: Hertz,
114 /// GPIO Speed
115 pub gpio_speed: Speed,
112 /// Enable internal pullup on SDA. 116 /// Enable internal pullup on SDA.
113 /// 117 ///
114 /// Using external pullup resistors is recommended for I2C. If you do 118 /// Using external pullup resistors is recommended for I2C. If you do
@@ -129,6 +133,8 @@ pub struct Config {
129impl Default for Config { 133impl Default for Config {
130 fn default() -> Self { 134 fn default() -> Self {
131 Self { 135 Self {
136 frequency: Hertz::khz(100),
137 gpio_speed: Speed::Medium,
132 #[cfg(gpio_v2)] 138 #[cfg(gpio_v2)]
133 sda_pullup: false, 139 sda_pullup: false,
134 #[cfg(gpio_v2)] 140 #[cfg(gpio_v2)]
@@ -142,11 +148,11 @@ impl Default for Config {
142impl Config { 148impl Config {
143 pub(super) fn scl_af(&self) -> AfType { 149 pub(super) fn scl_af(&self) -> AfType {
144 #[cfg(gpio_v1)] 150 #[cfg(gpio_v1)]
145 return AfType::output(OutputType::OpenDrain, Speed::Medium); 151 return AfType::output(OutputType::OpenDrain, self.gpio_speed);
146 #[cfg(gpio_v2)] 152 #[cfg(gpio_v2)]
147 return AfType::output_pull( 153 return AfType::output_pull(
148 OutputType::OpenDrain, 154 OutputType::OpenDrain,
149 Speed::Medium, 155 self.gpio_speed,
150 match self.scl_pullup { 156 match self.scl_pullup {
151 true => Pull::Up, 157 true => Pull::Up,
152 false => Pull::Down, 158 false => Pull::Down,
@@ -156,11 +162,11 @@ impl Config {
156 162
157 pub(super) fn sda_af(&self) -> AfType { 163 pub(super) fn sda_af(&self) -> AfType {
158 #[cfg(gpio_v1)] 164 #[cfg(gpio_v1)]
159 return AfType::output(OutputType::OpenDrain, Speed::Medium); 165 return AfType::output(OutputType::OpenDrain, self.gpio_speed);
160 #[cfg(gpio_v2)] 166 #[cfg(gpio_v2)]
161 return AfType::output_pull( 167 return AfType::output_pull(
162 OutputType::OpenDrain, 168 OutputType::OpenDrain,
163 Speed::Medium, 169 self.gpio_speed,
164 match self.sda_pullup { 170 match self.sda_pullup {
165 true => Pull::Up, 171 true => Pull::Up,
166 false => Pull::Down, 172 false => Pull::Down,
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 825dd240c..5fb49f943 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -158,7 +158,6 @@ impl<'d> I2c<'d, Async, Master> {
158 + 'd, 158 + 'd,
159 tx_dma: Peri<'d, impl TxDma<T>>, 159 tx_dma: Peri<'d, impl TxDma<T>>,
160 rx_dma: Peri<'d, impl RxDma<T>>, 160 rx_dma: Peri<'d, impl RxDma<T>>,
161 freq: Hertz,
162 config: Config, 161 config: Config,
163 ) -> Self { 162 ) -> Self {
164 Self::new_inner( 163 Self::new_inner(
@@ -167,7 +166,6 @@ impl<'d> I2c<'d, Async, Master> {
167 new_pin!(sda, config.sda_af()), 166 new_pin!(sda, config.sda_af()),
168 new_dma!(tx_dma), 167 new_dma!(tx_dma),
169 new_dma!(rx_dma), 168 new_dma!(rx_dma),
170 freq,
171 config, 169 config,
172 ) 170 )
173 } 171 }
@@ -179,7 +177,6 @@ impl<'d> I2c<'d, Blocking, Master> {
179 peri: Peri<'d, T>, 177 peri: Peri<'d, T>,
180 scl: Peri<'d, impl SclPin<T>>, 178 scl: Peri<'d, impl SclPin<T>>,
181 sda: Peri<'d, impl SdaPin<T>>, 179 sda: Peri<'d, impl SdaPin<T>>,
182 freq: Hertz,
183 config: Config, 180 config: Config,
184 ) -> Self { 181 ) -> Self {
185 Self::new_inner( 182 Self::new_inner(
@@ -188,7 +185,6 @@ impl<'d> I2c<'d, Blocking, Master> {
188 new_pin!(sda, config.sda_af()), 185 new_pin!(sda, config.sda_af()),
189 None, 186 None,
190 None, 187 None,
191 freq,
192 config, 188 config,
193 ) 189 )
194 } 190 }
@@ -202,7 +198,6 @@ impl<'d, M: Mode> I2c<'d, M, Master> {
202 sda: Option<Peri<'d, AnyPin>>, 198 sda: Option<Peri<'d, AnyPin>>,
203 tx_dma: Option<ChannelAndRequest<'d>>, 199 tx_dma: Option<ChannelAndRequest<'d>>,
204 rx_dma: Option<ChannelAndRequest<'d>>, 200 rx_dma: Option<ChannelAndRequest<'d>>,
205 freq: Hertz,
206 config: Config, 201 config: Config,
207 ) -> Self { 202 ) -> Self {
208 unsafe { T::EventInterrupt::enable() }; 203 unsafe { T::EventInterrupt::enable() };
@@ -224,14 +219,14 @@ impl<'d, M: Mode> I2c<'d, M, Master> {
224 sda, 219 sda,
225 }, 220 },
226 }; 221 };
227 this.enable_and_init(freq, config); 222 this.enable_and_init(config);
228 223
229 this 224 this
230 } 225 }
231 226
232 fn enable_and_init(&mut self, freq: Hertz, config: Config) { 227 fn enable_and_init(&mut self, config: Config) {
233 self.info.rcc.enable_and_reset(); 228 self.info.rcc.enable_and_reset();
234 self.init(freq, config); 229 self.init(config);
235 } 230 }
236} 231}
237 232
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 35f13ab46..081eb1191 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -43,7 +43,7 @@ pub unsafe fn on_interrupt<T: Instance>() {
43} 43}
44 44
45impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { 45impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
46 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 46 pub(crate) fn init(&mut self, config: Config) {
47 self.info.regs.cr1().modify(|reg| { 47 self.info.regs.cr1().modify(|reg| {
48 reg.set_pe(false); 48 reg.set_pe(false);
49 //reg.set_anfoff(false); 49 //reg.set_anfoff(false);
@@ -75,7 +75,7 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> {
75 reg.set_swrst(false); 75 reg.set_swrst(false);
76 }); 76 });
77 77
78 let timings = Timings::new(self.kernel_clock, freq); 78 let timings = Timings::new(self.kernel_clock, config.frequency);
79 79
80 self.info.regs.cr2().modify(|reg| { 80 self.info.regs.cr2().modify(|reg| {
81 reg.set_freq(timings.freq); 81 reg.set_freq(timings.freq);
@@ -738,15 +738,15 @@ struct Timings {
738} 738}
739 739
740impl Timings { 740impl Timings {
741 fn new(i2cclk: Hertz, speed: Hertz) -> Self { 741 fn new(i2cclk: Hertz, frequency: Hertz) -> Self {
742 // Calculate settings for I2C speed modes 742 // Calculate settings for I2C speed modes
743 let speed = speed.0; 743 let frequency = frequency.0;
744 let clock = i2cclk.0; 744 let clock = i2cclk.0;
745 let freq = clock / 1_000_000; 745 let freq = clock / 1_000_000;
746 assert!((2..=50).contains(&freq)); 746 assert!((2..=50).contains(&freq));
747 747
748 // Configure bus frequency into I2C peripheral 748 // Configure bus frequency into I2C peripheral
749 let trise = if speed <= 100_000 { 749 let trise = if frequency <= 100_000 {
750 freq + 1 750 freq + 1
751 } else { 751 } else {
752 (freq * 300) / 1000 + 1 752 (freq * 300) / 1000 + 1
@@ -757,11 +757,11 @@ impl Timings {
757 let mode; 757 let mode;
758 758
759 // I2C clock control calculation 759 // I2C clock control calculation
760 if speed <= 100_000 { 760 if frequency <= 100_000 {
761 duty = Duty::Duty2_1; 761 duty = Duty::Duty2_1;
762 mode = Mode::Standard; 762 mode = Mode::Standard;
763 ccr = { 763 ccr = {
764 let ccr = clock / (speed * 2); 764 let ccr = clock / (frequency * 2);
765 if ccr < 4 { 765 if ccr < 4 {
766 4 766 4
767 } else { 767 } else {
@@ -773,13 +773,13 @@ impl Timings {
773 mode = Mode::Fast; 773 mode = Mode::Fast;
774 if DUTYCYCLE == 0 { 774 if DUTYCYCLE == 0 {
775 duty = Duty::Duty2_1; 775 duty = Duty::Duty2_1;
776 ccr = clock / (speed * 3); 776 ccr = clock / (frequency * 3);
777 ccr = if ccr < 1 { 1 } else { ccr }; 777 ccr = if ccr < 1 { 1 } else { ccr };
778 778
779 // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle) 779 // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle)
780 } else { 780 } else {
781 duty = Duty::Duty16_9; 781 duty = Duty::Duty16_9;
782 ccr = clock / (speed * 25); 782 ccr = clock / (frequency * 25);
783 ccr = if ccr < 1 { 1 } else { ccr }; 783 ccr = if ccr < 1 { 1 } else { ccr };
784 784
785 // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle) 785 // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle)
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index e24cce5c6..76f0d25dc 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -93,13 +93,13 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
93} 93}
94 94
95impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { 95impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
96 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 96 pub(crate) fn init(&mut self, config: Config) {
97 self.info.regs.cr1().modify(|reg| { 97 self.info.regs.cr1().modify(|reg| {
98 reg.set_pe(false); 98 reg.set_pe(false);
99 reg.set_anfoff(false); 99 reg.set_anfoff(false);
100 }); 100 });
101 101
102 let timings = Timings::new(self.kernel_clock, freq.into()); 102 let timings = Timings::new(self.kernel_clock, config.frequency.into());
103 103
104 self.info.regs.timingr().write(|reg| { 104 self.info.regs.timingr().write(|reg| {
105 reg.set_presc(timings.prescale); 105 reg.set_presc(timings.prescale);