diff options
| author | HybridChild <[email protected]> | 2025-07-27 08:27:09 +0200 |
|---|---|---|
| committer | HybridChild <[email protected]> | 2025-08-23 08:48:32 +0200 |
| commit | bf01151bbb793c36431820bd814db775bf10a870 (patch) | |
| tree | e005fa6dfd010163a6a33a1db715e547cc5d31ea | |
| parent | ef673c6ca310cf0a7e9b1254afb7806bd6879e94 (diff) | |
stm32/i2c_v1: Remove redundant timing config abstractions for DutyCycle and I2C mode
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 79 |
1 files changed, 24 insertions, 55 deletions
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 081eb1191..a1ad9caef 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -14,7 +14,7 @@ use embedded_hal_1::i2c::Operation; | |||
| 14 | use mode::Master; | 14 | use mode::Master; |
| 15 | 15 | ||
| 16 | use super::*; | 16 | use super::*; |
| 17 | use crate::mode::Mode as PeriMode; | 17 | use crate::mode::Mode; |
| 18 | use crate::pac::i2c; | 18 | use crate::pac::i2c; |
| 19 | 19 | ||
| 20 | // /!\ /!\ | 20 | // /!\ /!\ |
| @@ -42,7 +42,7 @@ pub unsafe fn on_interrupt<T: Instance>() { | |||
| 42 | }); | 42 | }); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | 45 | impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> { |
| 46 | pub(crate) fn init(&mut self, 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); |
| @@ -81,8 +81,8 @@ impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { | |||
| 81 | reg.set_freq(timings.freq); | 81 | reg.set_freq(timings.freq); |
| 82 | }); | 82 | }); |
| 83 | self.info.regs.ccr().modify(|reg| { | 83 | self.info.regs.ccr().modify(|reg| { |
| 84 | reg.set_f_s(timings.mode.f_s()); | 84 | reg.set_f_s(timings.f_s); |
| 85 | reg.set_duty(timings.duty.duty()); | 85 | reg.set_duty(timings.duty); |
| 86 | reg.set_ccr(timings.ccr); | 86 | reg.set_ccr(timings.ccr); |
| 87 | }); | 87 | }); |
| 88 | self.info.regs.trise().modify(|reg| { | 88 | self.info.regs.trise().modify(|reg| { |
| @@ -701,40 +701,18 @@ impl<'d, IM: MasterMode> I2c<'d, Async, IM> { | |||
| 701 | } | 701 | } |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | enum Mode { | ||
| 705 | Fast, | ||
| 706 | Standard, | ||
| 707 | } | ||
| 708 | |||
| 709 | impl Mode { | ||
| 710 | fn f_s(&self) -> i2c::vals::FS { | ||
| 711 | match self { | ||
| 712 | Mode::Fast => i2c::vals::FS::FAST, | ||
| 713 | Mode::Standard => i2c::vals::FS::STANDARD, | ||
| 714 | } | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | enum Duty { | ||
| 719 | Duty2_1, | ||
| 720 | Duty16_9, | ||
| 721 | } | ||
| 722 | |||
| 723 | impl Duty { | ||
| 724 | fn duty(&self) -> i2c::vals::Duty { | ||
| 725 | match self { | ||
| 726 | Duty::Duty2_1 => i2c::vals::Duty::DUTY2_1, | ||
| 727 | Duty::Duty16_9 => i2c::vals::Duty::DUTY16_9, | ||
| 728 | } | ||
| 729 | } | ||
| 730 | } | ||
| 731 | 704 | ||
| 705 | /// Timing configuration for I2C v1 hardware | ||
| 706 | /// | ||
| 707 | /// This struct encapsulates the complex timing calculations required for STM32 I2C v1 | ||
| 708 | /// peripherals, which use three separate registers (CR2.FREQ, CCR, TRISE) instead of | ||
| 709 | /// the unified TIMINGR register found in v2 hardware. | ||
| 732 | struct Timings { | 710 | struct Timings { |
| 733 | freq: u8, | 711 | freq: u8, // APB frequency in MHz for CR2.FREQ register |
| 734 | mode: Mode, | 712 | f_s: i2c::vals::FS, // Standard or Fast mode selection |
| 735 | trise: u8, | 713 | trise: u8, // Rise time compensation value |
| 736 | ccr: u16, | 714 | ccr: u16, // Clock control register value |
| 737 | duty: Duty, | 715 | duty: i2c::vals::Duty, // Fast mode duty cycle selection |
| 738 | } | 716 | } |
| 739 | 717 | ||
| 740 | impl Timings { | 718 | impl Timings { |
| @@ -754,12 +732,12 @@ impl Timings { | |||
| 754 | 732 | ||
| 755 | let mut ccr; | 733 | let mut ccr; |
| 756 | let duty; | 734 | let duty; |
| 757 | let mode; | 735 | let f_s; |
| 758 | 736 | ||
| 759 | // I2C clock control calculation | 737 | // I2C clock control calculation |
| 760 | if frequency <= 100_000 { | 738 | if frequency <= 100_000 { |
| 761 | duty = Duty::Duty2_1; | 739 | duty = i2c::vals::Duty::DUTY2_1; |
| 762 | mode = Mode::Standard; | 740 | f_s = i2c::vals::FS::STANDARD; |
| 763 | ccr = { | 741 | ccr = { |
| 764 | let ccr = clock / (frequency * 2); | 742 | let ccr = clock / (frequency * 2); |
| 765 | if ccr < 4 { | 743 | if ccr < 4 { |
| @@ -770,38 +748,29 @@ impl Timings { | |||
| 770 | }; | 748 | }; |
| 771 | } else { | 749 | } else { |
| 772 | const DUTYCYCLE: u8 = 0; | 750 | const DUTYCYCLE: u8 = 0; |
| 773 | mode = Mode::Fast; | 751 | f_s = i2c::vals::FS::FAST; |
| 774 | if DUTYCYCLE == 0 { | 752 | if DUTYCYCLE == 0 { |
| 775 | duty = Duty::Duty2_1; | 753 | duty = i2c::vals::Duty::DUTY2_1; |
| 776 | ccr = clock / (frequency * 3); | 754 | ccr = clock / (frequency * 3); |
| 777 | ccr = if ccr < 1 { 1 } else { ccr }; | 755 | ccr = if ccr < 1 { 1 } else { ccr }; |
| 778 | |||
| 779 | // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle) | ||
| 780 | } else { | 756 | } else { |
| 781 | duty = Duty::Duty16_9; | 757 | duty = i2c::vals::Duty::DUTY16_9; |
| 782 | ccr = clock / (frequency * 25); | 758 | ccr = clock / (frequency * 25); |
| 783 | ccr = if ccr < 1 { 1 } else { ccr }; | 759 | ccr = if ccr < 1 { 1 } else { ccr }; |
| 784 | |||
| 785 | // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle) | ||
| 786 | } | 760 | } |
| 787 | } | 761 | } |
| 788 | 762 | ||
| 789 | Self { | 763 | Self { |
| 790 | freq: freq as u8, | 764 | freq: freq as u8, |
| 765 | f_s, | ||
| 791 | trise: trise as u8, | 766 | trise: trise as u8, |
| 792 | ccr: ccr as u16, | 767 | ccr: ccr as u16, |
| 793 | duty, | 768 | duty, |
| 794 | mode, | ||
| 795 | //prescale: presc_reg, | ||
| 796 | //scll, | ||
| 797 | //sclh, | ||
| 798 | //sdadel, | ||
| 799 | //scldel, | ||
| 800 | } | 769 | } |
| 801 | } | 770 | } |
| 802 | } | 771 | } |
| 803 | 772 | ||
| 804 | impl<'d, M: PeriMode> SetConfig for I2c<'d, M, Master> { | 773 | impl<'d, M: Mode> SetConfig for I2c<'d, M, Master> { |
| 805 | type Config = Hertz; | 774 | type Config = Hertz; |
| 806 | type ConfigError = (); | 775 | type ConfigError = (); |
| 807 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 776 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
| @@ -810,8 +779,8 @@ impl<'d, M: PeriMode> SetConfig for I2c<'d, M, Master> { | |||
| 810 | reg.set_freq(timings.freq); | 779 | reg.set_freq(timings.freq); |
| 811 | }); | 780 | }); |
| 812 | self.info.regs.ccr().modify(|reg| { | 781 | self.info.regs.ccr().modify(|reg| { |
| 813 | reg.set_f_s(timings.mode.f_s()); | 782 | reg.set_f_s(timings.f_s); |
| 814 | reg.set_duty(timings.duty.duty()); | 783 | reg.set_duty(timings.duty); |
| 815 | reg.set_ccr(timings.ccr); | 784 | reg.set_ccr(timings.ccr); |
| 816 | }); | 785 | }); |
| 817 | self.info.regs.trise().modify(|reg| { | 786 | self.info.regs.trise().modify(|reg| { |
