stm32f1_hal/i2c/
i2c1.rs

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