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,
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<'a, 'b, REMAP>(
70        self,
71        _pins: (impl I2cSclPin<REMAP>, impl I2cSdaPin<REMAP>),
72        slave_addr: Address,
73        speed: HertzU32,
74        max_operation: usize,
75        mcu: &'a mut Mcu,
76    ) -> (
77        impl BusDeviceWithAddress<u8> + 'b,
78        I2cBusInterruptHandler<OS, I>,
79        I2cBusErrorInterruptHandler<OS, I>,
80    )
81    where
82        I: 'b,
83        OS: OsInterface,
84        REMAP: RemapMode<I>,
85    {
86        REMAP::remap(&mut mcu.afio);
87        assert!(speed <= kHz(400));
88        let (bus, it, it_err) = I2cBusInterrupt::<OS, I>::new(self.i2c, max_operation);
89        (
90            I2cSoleDevice::new(bus, convert_addr(slave_addr), speed),
91            it,
92            it_err,
93        )
94    }
95}
96
97pub struct I2cDeviceBuilder<OS, BUS>
98where
99    OS: OsInterface,
100    BUS: I2cBusInterface,
101{
102    bus: Arc<Mutex<OS, BUS>>,
103}
104
105impl<OS, BUS> I2cDeviceBuilder<OS, BUS>
106where
107    OS: OsInterface,
108    BUS: I2cBusInterface,
109{
110    fn new(bus: BUS) -> Self {
111        Self {
112            bus: Arc::new(OS::mutex(bus)),
113        }
114    }
115
116    pub fn new_device(&self, slave_addr: Address, speed: HertzU32) -> I2cBusDevice<OS, BUS> {
117        assert!(speed <= kHz(400));
118        I2cBusDevice::new(self.bus.clone(), convert_addr(slave_addr), speed)
119    }
120}
121
122fn convert_addr(addr: Address) -> Address {
123    match addr {
124        Address::Seven(addr) => Address::Seven(addr << 1),
125        Address::Ten(addr) => {
126            let [msb, lsb] = addr.to_be_bytes();
127            let msb = ((msb & 0b11) << 1) | 0b11110000;
128            Address::Ten(u16::from_be_bytes([msb, lsb]))
129        }
130    }
131}
132
133#[derive(Debug, Eq, PartialEq)]
134pub enum DutyCycle {
135    Ratio2to1,
136    Ratio16to9,
137}
138
139#[derive(Debug, PartialEq, Eq)]
140pub enum Mode {
141    Standard {
142        frequency: HertzU32,
143    },
144    Fast {
145        frequency: HertzU32,
146        duty_cycle: DutyCycle,
147    },
148}
149
150impl Mode {
151    pub fn standard(frequency: HertzU32) -> Self {
152        Mode::Standard { frequency }
153    }
154
155    pub fn fast(frequency: HertzU32, duty_cycle: DutyCycle) -> Self {
156        Mode::Fast {
157            frequency,
158            duty_cycle,
159        }
160    }
161
162    pub fn get_frequency(&self) -> HertzU32 {
163        match *self {
164            Mode::Standard { frequency } => frequency,
165            Mode::Fast { frequency, .. } => frequency,
166        }
167    }
168}
169
170impl From<HertzU32> for Mode {
171    fn from(frequency: HertzU32) -> Self {
172        if frequency <= kHz(100) {
173            Self::Standard { frequency }
174        } else {
175            Self::Fast {
176                frequency,
177                duty_cycle: DutyCycle::Ratio2to1,
178            }
179        }
180    }
181}