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 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
38pub 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}