diff options
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/i2c/config.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/mod.rs | 11 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 4 |
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)] |
| 111 | pub struct Config { | 111 | pub 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 { | |||
| 129 | impl Default for Config { | 133 | impl 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 { | |||
| 142 | impl Config { | 148 | impl 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 | ||
| 45 | impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | 45 | impl<'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 | ||
| 740 | impl Timings { | 740 | impl 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 | ||
| 95 | impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { | 95 | impl<'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); |
