stm32f1_hal/i2c/
mod.rs

1mod i2c1;
2mod i2c2;
3
4pub use crate::common::i2c::*;
5
6use crate::{
7    Mcu, Steal,
8    afio::{RemapMode, i2c_remap::*},
9    os_trait::{Mutex, utils::FrequencyHolder},
10    prelude::*,
11    rcc::{Enable, GetClock, Reset},
12    time::*,
13};
14use core::marker::PhantomData;
15
16pub trait I2cInit<T> {
17    fn init<OS: OsInterface>(self, mcu: &mut Mcu) -> I2c<OS, T>;
18}
19
20pub trait I2cPeriphConfig: I2cPeriph + GetClock + Enable + Reset + Steal {
21    fn config(&mut self, mode: Mode);
22    fn set_ack(&mut self, en: bool);
23    /// Continue after the address has been sent.
24    fn continue_after_addr(&mut self);
25    fn write_data(&mut self, addr: u8);
26    fn read_data(&self) -> u8;
27    fn set_interrupt(&mut self, it: Interrupt, en: bool);
28    fn it_clean_needless_flag(&self);
29}
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
32pub enum Interrupt {
33    Error,
34    Event,
35    Buffer,
36}
37
38// wrapper
39pub struct I2c<OS: OsInterface, I> {
40    i2c: I,
41    _os: PhantomData<OS>,
42}
43
44#[allow(clippy::type_complexity)]
45impl<OS, I> I2c<OS, I>
46where
47    OS: OsInterface,
48    I: I2cPeriphConfig,
49{
50    pub fn into_interrupt_bus<REMAP>(
51        self,
52        _pins: (impl I2cSclPin<REMAP>, impl I2cSdaPin<REMAP>),
53        max_operation: usize,
54        mcu: &mut Mcu,
55    ) -> (
56        I2cDeviceBuilder<OS, I2cBusInterrupt<OS, I>>,
57        I2cBusInterruptHandler<OS, I>,
58        I2cBusErrorInterruptHandler<OS, I>,
59    )
60    where
61        OS: OsInterface,
62        REMAP: RemapMode<I>,
63    {
64        REMAP::remap(&mut mcu.afio);
65        let (bus, it, it_err) = I2cBusInterrupt::<OS, I>::new(self.i2c, max_operation);
66        (I2cDeviceBuilder::new(bus), it, it_err)
67    }
68
69    pub fn into_interrupt_sole<REMAP>(
70        self,
71        _pins: (impl I2cSclPin<REMAP>, impl I2cSdaPin<REMAP>),
72        slave_addr: Address,
73        speed: HertzU32,
74        max_operation: usize,
75        mcu: &mut Mcu,
76    ) -> (
77        impl BusDeviceWithAddress<u8>,
78        I2cBusInterruptHandler<OS, I>,
79        I2cBusErrorInterruptHandler<OS, I>,
80    )
81    where
82        OS: OsInterface,
83        REMAP: RemapMode<I>,
84    {
85        REMAP::remap(&mut mcu.afio);
86        assert!(speed <= kHz(400));
87        let (bus, it, it_err) = I2cBusInterrupt::<OS, I>::new(self.i2c, max_operation);
88        (
89            I2cSoleDevice::new(bus, convert_addr(slave_addr), speed),
90            it,
91            it_err,
92        )
93    }
94}
95
96pub struct I2cDeviceBuilder<OS, BUS>
97where
98    OS: OsInterface,
99    BUS: I2cBusInterface,
100{
101    bus: Arc<Mutex<OS, BUS>>,
102}
103
104impl<OS, BUS> I2cDeviceBuilder<OS, BUS>
105where
106    OS: OsInterface,
107    BUS: I2cBusInterface,
108{
109    fn new(bus: BUS) -> Self {
110        Self {
111            bus: Arc::new(OS::mutex(bus)),
112        }
113    }
114
115    pub fn new_device(&self, slave_addr: Address, speed: HertzU32) -> I2cBusDevice<OS, BUS> {
116        assert!(speed <= kHz(400));
117        I2cBusDevice::new(self.bus.clone(), convert_addr(slave_addr), speed)
118    }
119}
120
121fn convert_addr(addr: Address) -> Address {
122    match addr {
123        Address::Seven(addr) => Address::Seven(addr << 1),
124        Address::Ten(addr) => {
125            let [msb, lsb] = addr.to_be_bytes();
126            let msb = ((msb & 0b11) << 1) | 0b11110000;
127            Address::Ten(u16::from_be_bytes([msb, lsb]))
128        }
129    }
130}
131
132#[derive(Debug, Eq, PartialEq)]
133pub enum DutyCycle {
134    Ratio2to1,
135    Ratio16to9,
136}
137
138#[derive(Debug, PartialEq, Eq)]
139pub enum Mode {
140    Standard {
141        frequency: HertzU32,
142    },
143    Fast {
144        frequency: HertzU32,
145        duty_cycle: DutyCycle,
146    },
147}
148
149impl Mode {
150    pub fn standard(frequency: HertzU32) -> Self {
151        Mode::Standard { frequency }
152    }
153
154    pub fn fast(frequency: HertzU32, duty_cycle: DutyCycle) -> Self {
155        Mode::Fast {
156            frequency,
157            duty_cycle,
158        }
159    }
160
161    pub fn get_frequency(&self) -> HertzU32 {
162        match *self {
163            Mode::Standard { frequency } => frequency,
164            Mode::Fast { frequency, .. } => frequency,
165        }
166    }
167}
168
169impl From<HertzU32> for Mode {
170    fn from(frequency: HertzU32) -> Self {
171        if frequency <= kHz(100) {
172            Self::Standard { frequency }
173        } else {
174            Self::Fast {
175                frequency,
176                duty_cycle: DutyCycle::Ratio2to1,
177            }
178        }
179    }
180}