aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridChild <[email protected]>2025-07-27 08:27:09 +0200
committerHybridChild <[email protected]>2025-08-23 08:48:32 +0200
commitbf01151bbb793c36431820bd814db775bf10a870 (patch)
treee005fa6dfd010163a6a33a1db715e547cc5d31ea
parentef673c6ca310cf0a7e9b1254afb7806bd6879e94 (diff)
stm32/i2c_v1: Remove redundant timing config abstractions for DutyCycle and I2C mode
-rw-r--r--embassy-stm32/src/i2c/v1.rs79
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;
14use mode::Master; 14use mode::Master;
15 15
16use super::*; 16use super::*;
17use crate::mode::Mode as PeriMode; 17use crate::mode::Mode;
18use crate::pac::i2c; 18use crate::pac::i2c;
19 19
20// /!\ /!\ 20// /!\ /!\
@@ -42,7 +42,7 @@ pub unsafe fn on_interrupt<T: Instance>() {
42 }); 42 });
43} 43}
44 44
45impl<'d, M: PeriMode, IM: MasterMode> I2c<'d, M, IM> { 45impl<'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
704enum Mode {
705 Fast,
706 Standard,
707}
708
709impl 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
718enum Duty {
719 Duty2_1,
720 Duty16_9,
721}
722
723impl 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.
732struct Timings { 710struct 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
740impl Timings { 718impl 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
804impl<'d, M: PeriMode> SetConfig for I2c<'d, M, Master> { 773impl<'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| {