stm32f1_hal/i2c/
i2c1.rs

1type I2cX = pac::I2C1;
2
3// $sync begin
4
5use super::*;
6use crate::{Mcu, pac};
7
8static CLOCK: FrequencyHolder = FrequencyHolder::new(KilohertzU32::from_raw(0));
9
10// Initialization -------------------------------------------------------------
11
12impl I2cInit<I2cX> for I2cX {
13    fn init<OS: OsInterface>(self, mcu: &mut Mcu) -> I2c<OS, I2cX> {
14        mcu.rcc.enable(&self);
15        mcu.rcc.reset(&self);
16        CLOCK.set(self.get_clock(&mcu.rcc).convert());
17
18        I2c {
19            i2c: self,
20            _os: PhantomData,
21        }
22    }
23}
24
25impl I2cPeriphConfig for I2cX {
26    fn config(&mut self, mode: Mode) {
27        let clock = CLOCK.get().to_Hz();
28        let clc_mhz = clock / 1_000_000;
29
30        // Configure bus frequency into I2C peripheral
31        self.cr2()
32            .write(|w| unsafe { w.freq().bits(clc_mhz as u8) });
33
34        let trise = match mode {
35            Mode::Standard { .. } => clc_mhz + 1,
36            Mode::Fast { .. } => clc_mhz * 300 / 1000 + 1,
37        };
38
39        // Configure correct rise times
40        self.trise().write(|w| w.trise().set(trise as u8));
41
42        match mode {
43            // I2C clock control calculation
44            Mode::Standard { frequency } => {
45                let ccr = (clock / (frequency.raw() * 2)).max(4);
46
47                // Set clock to standard mode with appropriate parameters for selected speed
48                self.ccr().write(|w| unsafe {
49                    w.f_s().clear_bit();
50                    w.duty().clear_bit();
51                    w.ccr().bits(ccr as u16)
52                });
53            }
54            Mode::Fast {
55                frequency,
56                duty_cycle,
57            } => match duty_cycle {
58                DutyCycle::Ratio2to1 => {
59                    let ccr = (clock / (frequency.raw() * 3)).max(1);
60
61                    // Set clock to fast mode with appropriate parameters for selected speed (2:1 duty cycle)
62                    self.ccr().write(|w| unsafe {
63                        w.f_s().set_bit().duty().clear_bit().ccr().bits(ccr as u16)
64                    });
65                }
66                DutyCycle::Ratio16to9 => {
67                    let ccr = (clock / (frequency.raw() * 25)).max(1);
68
69                    // Set clock to fast mode with appropriate parameters for selected speed (16:9 duty cycle)
70                    self.ccr().write(|w| unsafe {
71                        w.f_s().set_bit().duty().set_bit().ccr().bits(ccr as u16)
72                    });
73                }
74            },
75        }
76
77        // Enable the I2C processing
78        // Disable acknowledge at next position
79        self.cr1().modify(|_, w| w.pe().set_bit().pos().clear_bit());
80    }
81
82    #[inline]
83    fn set_ack(&mut self, en: bool) {
84        self.cr1().modify(|_, w| w.ack().bit(en));
85    }
86
87    #[inline]
88    fn continue_after_addr(&mut self) {
89        let _ = self.sr1().read();
90        let _ = self.sr2().read();
91    }
92
93    #[inline]
94    fn write_data(&mut self, data: u8) {
95        self.dr().write(|w| unsafe { w.dr().bits(data) });
96    }
97
98    #[inline]
99    fn read_data(&self) -> u8 {
100        self.dr().read().bits() as u8
101    }
102
103    #[inline]
104    fn set_interrupt(&mut self, event: Interrupt, en: bool) {
105        match event {
106            Interrupt::Buffer => self.cr2().modify(|_, w| w.itbufen().bit(en)),
107            Interrupt::Error => self.cr2().modify(|_, w| w.iterren().bit(en)),
108            Interrupt::Event => self.cr2().modify(|_, w| w.itevten().bit(en)),
109        };
110    }
111
112    fn it_clean_needless_flag(&self) {
113        if self.sr1().read().btf().bit_is_set() {
114            let _ = self.read_data();
115        }
116    }
117}
118
119// Implement Peripheral -------------------------------------------------------
120
121impl I2cPeriph for I2cX {
122    #[inline]
123    fn disable_all_interrupt(&mut self) {
124        self.cr2().modify(|_, w| {
125            w.itbufen()
126                .clear_bit()
127                .iterren()
128                .clear_bit()
129                .itevten()
130                .clear_bit()
131        });
132    }
133
134    fn disable_data_interrupt(&mut self) {
135        self.set_interrupt(Interrupt::Buffer, false);
136    }
137
138    #[inline]
139    fn it_send_start(&mut self) {
140        self.set_interrupt(Interrupt::Event, true);
141        // Clear all pending error bits
142        // NOTE(unsafe): Writing 0 clears the r/w bits and has no effect on the r bits
143        self.sr1().write(|w| unsafe { w.bits(0) });
144        self.cr1().modify(|_, w| w.start().set_bit());
145        self.set_interrupt(Interrupt::Error, true);
146    }
147
148    fn it_prepare_write(&mut self, addr: Address, step: &mut u8) -> Result<(), bool> {
149        match *step {
150            0 => {
151                if !self.get_flag(Flag::Started) {
152                    return Err(false);
153                }
154                match addr {
155                    Address::Seven(addr) => {
156                        self.write_data(addr);
157                        *step = 2;
158                    }
159                    Address::Ten(addr) => {
160                        let [msb, _] = addr.to_be_bytes();
161                        self.write_data(msb);
162                        next(step);
163                    }
164                }
165            }
166            1 => {
167                if !self.get_flag(Flag::Address10Sent) {
168                    return Err(false);
169                }
170                if let Address::Ten(addr) = addr {
171                    let [_, lsb] = addr.to_be_bytes();
172                    self.write_data(lsb);
173                    next(step);
174                } else {
175                    panic!();
176                }
177            }
178            2 => {
179                if !self.get_flag(Flag::AddressSent) {
180                    return Err(false);
181                }
182                self.continue_after_addr();
183                self.set_interrupt(Interrupt::Buffer, true);
184                next(step);
185                return Ok(());
186            }
187            _ => return Ok(()),
188        }
189        Err(true)
190    }
191
192    fn it_prepare_read(
193        &mut self,
194        addr: Address,
195        total_len: usize,
196        last_operation: bool,
197        step: &mut u8,
198    ) -> Result<(), bool> {
199        self.it_clean_needless_flag();
200        match *step {
201            0 => {
202                if !self.get_flag(Flag::Started) {
203                    return Err(false);
204                }
205                self.set_ack(false);
206                match addr {
207                    Address::Seven(addr) => {
208                        self.write_data(addr | 1);
209                        *step = 4;
210                    }
211                    Address::Ten(addr) => {
212                        let [msb, _] = addr.to_be_bytes();
213                        self.write_data(msb);
214                        next(step);
215                    }
216                }
217            }
218            1 => {
219                if !self.get_flag(Flag::Address10Sent) {
220                    return Err(false);
221                }
222                if let Address::Ten(addr) = addr {
223                    let [_, lsb] = addr.to_be_bytes();
224                    self.write_data(lsb);
225                    next(step);
226                } else {
227                    panic!();
228                }
229            }
230            2 => {
231                if !self.get_flag(Flag::AddressSent) {
232                    return Err(false);
233                }
234                self.it_send_start();
235                next(step);
236            }
237            3 => {
238                if !self.get_flag(Flag::Started) {
239                    return Err(false);
240                }
241                if let Address::Ten(addr) = addr {
242                    let [msb, _] = addr.to_be_bytes();
243                    self.write_data(msb | 1);
244                    next(step);
245                } else {
246                    panic!();
247                }
248            }
249            4 => {
250                if !self.get_flag(Flag::AddressSent) {
251                    return Err(false);
252                }
253                self.set_ack(total_len > 1);
254                self.continue_after_addr();
255                if total_len <= 1 {
256                    if last_operation {
257                        self.send_stop();
258                    } else {
259                        self.it_send_start();
260                    }
261                }
262                self.set_interrupt(Interrupt::Buffer, true);
263                next(step);
264                return Ok(());
265            }
266            _ => return Ok(()),
267        }
268        Err(true)
269    }
270
271    #[inline]
272    fn it_read(&mut self, left_len: usize, last_operation: bool) -> Option<u8> {
273        if self.sr1().read().rx_ne().bit_is_set() {
274            if left_len == 2 {
275                if last_operation {
276                    // stop
277                    self.cr1()
278                        .modify(|_, w| w.stop().set_bit().ack().clear_bit());
279                } else {
280                    // restart
281                    self.cr1()
282                        .modify(|_, w| w.start().set_bit().ack().clear_bit());
283                }
284            }
285            let data = self.read_data();
286            Some(data)
287        } else {
288            None
289        }
290    }
291
292    #[inline]
293    fn it_write_with(&mut self, mut f: impl FnMut() -> Option<u8>) -> Result<(), bool> {
294        let mut rst = false;
295        while self.get_flag(Flag::TxEmpty) {
296            if let Some(data) = f() {
297                self.write_data(data);
298                rst = true;
299            } else {
300                return Ok(());
301            }
302        }
303        Err(rst)
304    }
305
306    #[inline]
307    fn send_stop(&mut self) {
308        self.cr1()
309            .modify(|_, w| w.stop().set_bit().ack().clear_bit());
310        // Clear all pending error bits
311        self.sr1().write(|w| unsafe { w.bits(0) });
312    }
313
314    #[inline]
315    fn is_stopped(&mut self) -> bool {
316        self.cr1().read().stop().bit_is_clear() && !self.get_flag(Flag::Busy)
317    }
318
319    #[inline]
320    fn is_slave_stopped(&mut self) -> bool {
321        self.sr1().read().stopf().bit_is_set()
322    }
323
324    #[inline]
325    fn get_flag(&mut self, flag: Flag) -> bool {
326        match flag {
327            Flag::Started => self.sr1().read().sb().bit_is_set(),
328            Flag::AddressSent => self.sr1().read().addr().bit_is_set(),
329            Flag::Address10Sent => self.sr1().read().add10().bit_is_set(),
330            Flag::TxEmpty => self.sr1().read().tx_e().bit_is_set(),
331            Flag::RxNotEmpty => self.sr1().read().rx_ne().bit_is_set(),
332            Flag::ByteTransferFinished => self.sr1().read().btf().bit_is_set(),
333            Flag::MasterSlave => self.sr2().read().msl().bit_is_set(),
334            Flag::Busy => self.sr2().read().busy().bit_is_set(),
335            _ => false,
336        }
337    }
338
339    fn get_and_clean_error(&mut self) -> Option<Error> {
340        let sr1 = self.sr1().read();
341        if sr1.arlo().bit_is_set() {
342            self.sr1().write(|w| w.arlo().clear_bit());
343            Some(Error::ArbitrationLoss)
344        } else if sr1.af().bit_is_set() {
345            self.sr1().write(|w| w.af().clear_bit());
346            Some(Error::NoAcknowledge(NoAcknowledgeSource::Unknown))
347        } else if sr1.ovr().bit_is_set() {
348            self.sr1().write(|w| w.ovr().clear_bit());
349            Some(Error::Overrun)
350        } else if sr1.timeout().bit_is_set() {
351            self.sr1().write(|w| w.timeout().clear_bit());
352            Some(Error::SMBusTimeout)
353        } else if sr1.smbalert().bit_is_set() {
354            self.sr1().write(|w| w.smbalert().clear_bit());
355            Some(Error::SMBusAlert)
356        } else if sr1.pecerr().bit_is_set() {
357            self.sr1().write(|w| w.pecerr().clear_bit());
358            Some(Error::Pec)
359        } else {
360            // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and
361            // clearing the BERR bit instead.
362            if sr1.berr().bit_is_set() {
363                self.sr1().write(|w| w.berr().clear_bit());
364            }
365            None
366        }
367    }
368
369    fn handle_error(&mut self, _err: Error) {
370        if self.sr2().read().busy().bit_is_set() {
371            // TODO recover from busy
372            self.soft_reset();
373        } else {
374            self.soft_reset();
375        }
376    }
377
378    fn set_speed(&mut self, speed: HertzU32) {
379        self.cr1().modify(|_, w| w.pe().clear_bit());
380        self.config(Mode::from(speed));
381    }
382
383    fn soft_reset(&mut self) {
384        // backup
385        let cr2 = self.cr2().read().bits();
386        let t_rise = self.trise().read().bits();
387        let ccr = self.ccr().read().bits();
388        // software reset
389        self.cr1().write(|w| w.pe().set_bit().swrst().set_bit());
390        self.cr1().reset();
391        // restore
392        self.cr2().write(|w| unsafe { w.bits(cr2) });
393        self.trise().write(|w| unsafe { w.bits(t_rise) });
394        self.ccr().write(|w| unsafe { w.bits(ccr) });
395        // enable
396        self.cr1().modify(|_, w| w.pe().set_bit().pos().clear_bit());
397    }
398
399    // fn read_sr(&mut self) -> u32 {
400    //     self.sr1().read().bits() as u32
401    // }
402}
403
404fn next(step: &mut u8) {
405    *step += 1;
406}
407
408// $sync end