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 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<'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}