stm32f303xc/
i2c.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use core::cell::Cell;
6
7use kernel::hil;
8use kernel::hil::i2c::{self, Error, I2CHwMasterClient, I2CMaster};
9use kernel::platform::chip::ClockInterface;
10use kernel::utilities::cells::{OptionalCell, TakeCell};
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, ReadWrite};
13use kernel::utilities::StaticRef;
14
15use crate::rcc;
16
17pub enum I2CSpeed {
18    Speed100k,
19    Speed400k,
20    Speed1M,
21}
22
23/// Inter-Integrated Circuit
24#[repr(C)]
25struct I2CRegisters {
26    /// control register 1
27    cr1: ReadWrite<u32, CR1::Register>,
28    /// control register 2
29    cr2: ReadWrite<u32, CR2::Register>,
30    /// own address register 1
31    oar1: ReadWrite<u32, OAR1::Register>,
32    /// own address register 2
33    oar2: ReadWrite<u32, OAR2::Register>,
34    /// timing register
35    timingr: ReadWrite<u32, TIMINGR::Register>,
36    /// timeout register
37    timeout: ReadWrite<u32, TIMEOUT::Register>,
38    /// interrupt and status register
39    isr: ReadWrite<u32, ISR::Register>,
40    /// interrupt clear register
41    icr: ReadWrite<u32, ICR::Register>,
42    /// PEC register
43    pecr: ReadWrite<u32, PECR::Register>,
44    /// receive data register
45    rxdr: ReadWrite<u32, RXDR::Register>,
46    /// transmit data register
47    txdr: ReadWrite<u32, TXDR::Register>,
48}
49
50register_bitfields![u32,
51    CR1 [
52        /// PEC enable
53        PCEN OFFSET(23) NUMBITS(1) [],
54        /// SMBus alert enable
55        ALERTEN OFFSET(22) NUMBITS(1) [],
56        /// SMBus Device Default address enable
57        SMBDEN OFFSET(21) NUMBITS(1) [],
58        /// SMBus Host address enable
59        SMBHEN OFFSET(20) NUMBITS(1) [],
60        /// General call enable
61        GCEN OFFSET(19) NUMBITS(1) [],
62        /// Wakeup from Stop mode enable
63        WUPEN OFFSET(18) NUMBITS(1) [],
64        /// Clock stretching disable
65        NOSTRETCH OFFSET(17) NUMBITS(1) [],
66        /// Slave byte control
67        SBC OFFSET(16) NUMBITS(1) [],
68        /// DMA reception requests enable
69        RXDMAEN OFFSET(15) NUMBITS(1) [],
70        /// DMA transmission requests enable
71        TXDMAEN OFFSET(14) NUMBITS(1) [],
72        /// Analog noise filter OFF
73        ANOFF OFFSET(12) NUMBITS(1) [],
74        /// Digital noise filter
75        DNF OFFSET(8) NUMBITS(4) [],
76        /// Error interrupts enable
77        ERRIE OFFSET(7) NUMBITS(1) [],
78        /// Transfer Complete interrupt enable
79        TCIE OFFSET(6) NUMBITS(1) [],
80        /// STOP detection Interrupt enable
81        STOPIE OFFSET(5) NUMBITS(1) [],
82        /// Not acknowledge received Interrupt enable
83        NACKIE OFFSET(4) NUMBITS(1) [],
84        /// Address match Interrupt enable (slave only)
85        ADDRIE OFFSET(3) NUMBITS(3) [],
86        /// RX Interrupt enable
87        RXIE OFFSET(2) NUMBITS(1) [],
88        /// TX Interrupt enable
89        TXIE OFFSET(1) NUMBITS(1) [],
90        /// Peripheral enable
91        PE OFFSET(0) NUMBITS(1) []
92    ],
93    CR2 [
94        /// Packet error checking byte
95        PECBYTE OFFSET(26) NUMBITS(1) [],
96        /// Automatic end mode (master mode)
97        AUTOEND OFFSET(25) NUMBITS(1) [],
98        /// NBYTES reload mode
99        RELOAD OFFSET(24) NUMBITS(1) [],
100        /// Number of bytes
101        NBYTES OFFSET(16) NUMBITS(8) [],
102        /// NACK generation (slave mode)
103        NACK OFFSET(15) NUMBITS(1) [],
104        /// Stop generation (master mode)
105        STOP OFFSET(14) NUMBITS(1) [],
106        /// Start generation
107        START OFFSET(13) NUMBITS(1) [],
108        /// 10-bit address header only read direction (master receiver mode)
109        HEAD10R OFFSET(12) NUMBITS(1) [],
110        /// 10-bit addressing mode (master mode)
111        ADD10 OFFSET(11) NUMBITS(1) [],
112        /// Transfer direction (master mode)
113        RD_WRN OFFSET(10) NUMBITS(1) [],
114        /// Slave address bit 9:8 (master mode)
115        SADD8_9 OFFSET(8) NUMBITS(2) [],
116        // Slave address bit 7:1 (master mode)
117        SADD7_1 OFFSET(1) NUMBITS(7) [],
118        /// Slave address bit 0 (master mode)
119        SADD OFFSET(0) NUMBITS(1) []
120    ],
121    OAR1 [
122        /// Own Address 1 enable
123        OA1EN OFFSET(15) NUMBITS(1) [],
124        /// Own Address 1 10-bitmode
125        OA1MODE OFFSET(10) NUMBITS(1) [],
126        /// Interface address
127        OA1 OFFSET(0) NUMBITS(10) []
128    ],
129    OAR2 [
130        /// Own Address 2 enable
131        OA2EN OFFSET(15) NUMBITS(1) [],
132        /// Own Address 2 masks
133        OA2MSK OFFSET(8) NUMBITS(3) [],
134        /// Interface address
135        OA2 OFFSET(1) NUMBITS(7) []
136    ],
137    TIMINGR [
138        /// Timing prescaler
139        PRESC OFFSET(28) NUMBITS(4) [],
140        /// Data setup time
141        SCLDEL OFFSET(20) NUMBITS(4) [],
142        /// Data hold time
143        SDAEL OFFSET(16) NUMBITS(4) [],
144        /// SCL high period (master mode)
145        SCLH OFFSET(8) NUMBITS(8) [],
146        /// SCL low period (master mode)
147        SCLL OFFSET(0) NUMBITS(8) []
148    ],
149    TIMEOUT [
150        /// Extended clock timeout enable
151        TEXTEN OFFSET(31) NUMBITS(1) [],
152        /// Bus timeout B
153        TIMEOUTB OFFSET(16) NUMBITS(12) [],
154        /// Clock timeout enable
155        TIMOUTEN OFFSET(15) NUMBITS(1) [],
156        /// Idle clock timeout detection
157        TIDLE OFFSET(12) NUMBITS(1) [],
158        /// Bus Timeout A
159        TIMEOUTA OFFSET(0) NUMBITS(12) []
160    ],
161    ISR [
162        /// Address match code (slavemode)
163        ADDCODE OFFSET(17) NUMBITS(7) [],
164        /// Transfer direction (slave mode)
165        DIR OFFSET(16) NUMBITS(1) [],
166        /// Bus busy
167        BUSY OFFSET(15) NUMBITS(1) [],
168        /// SMBus alert
169        ALERT OFFSET(13) NUMBITS(1) [],
170        /// Timeout or tLOW detection flag
171        TIMEOUT OFFSET(12) NUMBITS(1) [],
172        /// Bus error
173        PECERR OFFSET(11) NUMBITS(1) [],
174        /// Overrun/Underrun (slave mode)
175        OVR OFFSET(10) NUMBITS(1) [],
176        /// Arbitration lost
177        ARLO OFFSET(9) NUMBITS(1) [],
178        /// Bus error
179        BERR OFFSET(8) NUMBITS(1) [],
180        /// Transfer Complete Reload
181        TCR OFFSET(7) NUMBITS(1) [],
182        /// Transfer Complete (master mode)
183        TC OFFSET(6) NUMBITS(1) [],
184        /// Stop detection flag
185        STOPF OFFSET(5) NUMBITS(1) [],
186        /// Not Acknowledge received flag
187        NACKF OFFSET(4) NUMBITS(1) [],
188        /// Address matched (slave mode)
189        ADDR OFFSET(3) NUMBITS(1) [],
190        /// Receive data register not empty (receivers)
191        RXNE OFFSET(2) NUMBITS(1) [],
192        /// Transmit interrupt status (transmitters)
193        TXIS OFFSET(1) NUMBITS(1) [],
194        /// Transmit data register empty (transmitters)
195        TXE OFFSET(0) NUMBITS(1) []
196    ],
197    ICR [
198        /// Alert flag clear
199        ALERTCF OFFSET(13) NUMBITS(1) [],
200        /// Timeout detection flag clear
201        TIMOUTCF OFFSET(12) NUMBITS(1) [],
202        /// PEC Error flag clear
203        PECCF OFFSET(11) NUMBITS(1) [],
204        /// Overrun/Underrun flag clear
205        OVRCF OFFSET(10) NUMBITS(1) [],
206        /// Arbitration Lost flag clear
207        ARLOCF OFFSET(9) NUMBITS(1) [],
208        /// Bus error flag clear
209        BERRCF OFFSET(8) NUMBITS(1) [],
210        /// Stop detection flag clear
211        STOPCF OFFSET(5) NUMBITS(1) [],
212        /// Not Acknowledge flag clear
213        NACKCF OFFSET(4) NUMBITS(1) [],
214        /// Address matched flag clear
215        ADDRCF OFFSET(3) NUMBITS(1) []
216    ],
217    PECR [
218        /// Packet error checking register
219        PEC OFFSET(0) NUMBITS(8) []
220    ],
221    RXDR [
222        /// 8-bit receive data
223        RXDATA OFFSET(0) NUMBITS(8) []
224    ],
225    TXDR [
226        /// 8-bit transmit data
227        TXDATA OFFSET(0) NUMBITS(8) []
228    ]
229];
230
231const I2C1_BASE: StaticRef<I2CRegisters> =
232    unsafe { StaticRef::new(0x4000_5400 as *const I2CRegisters) };
233
234// const I2C2_BASE: StaticRef<I2CRegisters> =
235//     unsafe { StaticRef::new(0x4000_5800 as *const I2CRegisters) };
236
237pub struct I2C<'a> {
238    registers: StaticRef<I2CRegisters>,
239    clock: I2CClock<'a>,
240
241    // I2C slave support not yet implemented
242    master_client: OptionalCell<&'a dyn hil::i2c::I2CHwMasterClient>,
243
244    buffer: TakeCell<'static, [u8]>,
245    tx_position: Cell<usize>,
246    rx_position: Cell<usize>,
247    tx_len: Cell<usize>,
248    rx_len: Cell<usize>,
249
250    slave_address: Cell<u8>,
251
252    status: Cell<I2CStatus>,
253    // transfers: Cell<u8>
254}
255
256#[derive(Copy, Clone, PartialEq)]
257enum I2CStatus {
258    Idle,
259    Writing,
260    WritingReading,
261    Reading,
262}
263
264impl<'a> I2C<'a> {
265    fn new(base_addr: StaticRef<I2CRegisters>, clock: I2CClock<'a>) -> Self {
266        Self {
267            registers: base_addr,
268            clock,
269
270            master_client: OptionalCell::empty(),
271
272            slave_address: Cell::new(0),
273
274            buffer: TakeCell::empty(),
275            tx_position: Cell::new(0),
276            rx_position: Cell::new(0),
277
278            tx_len: Cell::new(0),
279            rx_len: Cell::new(0),
280
281            status: Cell::new(I2CStatus::Idle),
282        }
283    }
284
285    pub fn new_i2c1(rcc: &'a rcc::Rcc) -> Self {
286        Self::new(
287            I2C1_BASE,
288            I2CClock(rcc::PeripheralClock::new(
289                rcc::PeripheralClockType::APB1(rcc::PCLK1::I2C1),
290                rcc,
291            )),
292        )
293    }
294
295    pub fn set_speed(&self, speed: I2CSpeed, system_clock_in_mhz: usize) {
296        self.disable();
297        match speed {
298            I2CSpeed::Speed100k => {
299                let prescaler = system_clock_in_mhz / 4 - 1;
300                self.registers.timingr.modify(
301                    TIMINGR::PRESC.val(prescaler as u32)
302                        + TIMINGR::SCLL.val(19)
303                        + TIMINGR::SCLH.val(15)
304                        + TIMINGR::SDAEL.val(2)
305                        + TIMINGR::SCLDEL.val(4),
306                );
307            }
308            I2CSpeed::Speed400k => {
309                let prescaler = system_clock_in_mhz / 8 - 1;
310                self.registers.timingr.modify(
311                    TIMINGR::PRESC.val(prescaler as u32)
312                        + TIMINGR::SCLL.val(9)
313                        + TIMINGR::SCLH.val(3)
314                        + TIMINGR::SDAEL.val(3)
315                        + TIMINGR::SCLDEL.val(3),
316                );
317            }
318            I2CSpeed::Speed1M => {
319                panic!("i2c speed 1MHz not implemented");
320            }
321        }
322        self.enable();
323    }
324
325    pub fn is_enabled_clock(&self) -> bool {
326        self.clock.is_enabled()
327    }
328
329    pub fn enable_clock(&self) {
330        self.clock.enable();
331    }
332
333    pub fn disable_clock(&self) {
334        self.clock.disable();
335    }
336
337    pub fn handle_event(&self) {
338        if self.registers.isr.is_set(ISR::TXIS) {
339            // send the next byte
340            if self.buffer.is_some() && self.tx_position.get() < self.tx_len.get() {
341                self.buffer.map(|buf| {
342                    let byte = buf[self.tx_position.get()];
343                    self.registers.txdr.write(TXDR::TXDATA.val(byte as u32));
344                    self.tx_position.set(self.tx_position.get() + 1);
345                });
346            } else {
347                panic!("i2c attempted to read more bytes than the available buffer");
348            }
349        }
350
351        while self.registers.isr.is_set(ISR::RXNE) {
352            // send the next byte
353            let byte = self.registers.rxdr.read(RXDR::RXDATA) as u8;
354            if self.buffer.is_some() && self.rx_position.get() < self.rx_len.get() {
355                self.buffer.map(|buf| {
356                    buf[self.rx_position.get()] = byte;
357                    self.rx_position.set(self.rx_position.get() + 1);
358                });
359            }
360        }
361
362        if self.registers.isr.is_set(ISR::TC) {
363            match self.status.get() {
364                I2CStatus::Writing | I2CStatus::WritingReading => {
365                    if self.tx_position.get() < self.tx_len.get() {
366                        self.registers.cr2.modify(CR2::STOP::SET);
367                        self.stop();
368                        self.master_client.map(|client| {
369                            self.buffer
370                                .take()
371                                .map(|buf| client.command_complete(buf, Err(Error::DataNak)))
372                        });
373                    } else {
374                        if self.status.get() == I2CStatus::Writing {
375                            self.registers.cr2.modify(CR2::STOP::SET);
376                            self.stop();
377                            self.master_client.map(|client| {
378                                self.buffer
379                                    .take()
380                                    .map(|buf| client.command_complete(buf, Ok(())))
381                            });
382                        } else {
383                            self.status.set(I2CStatus::Reading);
384                            self.start_read();
385                        }
386                    }
387                }
388                I2CStatus::Reading => {
389                    let status = if self.rx_position.get() == self.rx_len.get() {
390                        Ok(())
391                    } else {
392                        Err(Error::DataNak)
393                    };
394                    self.registers.cr2.modify(CR2::STOP::SET);
395                    self.stop();
396                    self.master_client.map(|client| {
397                        self.buffer
398                            .take()
399                            .map(|buf| client.command_complete(buf, status))
400                    });
401                }
402                _ => panic!("i2c status error"),
403            }
404        }
405
406        if self.registers.isr.is_set(ISR::NACKF) {
407            // abort transfer due to NACK
408            self.registers.cr2.modify(CR2::STOP::SET);
409            self.stop();
410            self.registers.icr.modify(ICR::NACKCF::SET);
411            self.master_client.map(|client| {
412                self.buffer
413                    .take()
414                    .map(|buf| client.command_complete(buf, Err(Error::AddressNak)))
415            });
416        }
417    }
418
419    pub fn handle_error(&self) {
420        // not sure that this is the best error to send
421        self.master_client.map(|client| {
422            self.buffer
423                .take()
424                .map(|buf| client.command_complete(buf, Err(Error::DataNak)))
425        });
426        self.stop();
427    }
428
429    fn reset(&self) {
430        self.disable();
431        self.enable();
432    }
433
434    fn start_write(&self) {
435        self.tx_position.set(0);
436        self.registers
437            .cr2
438            .modify(CR2::NBYTES.val(self.tx_len.get() as u32));
439        self.registers
440            .cr2
441            .modify(CR2::SADD7_1.val(self.slave_address.get() as u32));
442        self.registers.cr2.modify(CR2::RD_WRN::CLEAR);
443        self.registers
444            .cr1
445            .modify(CR1::TXIE::SET + CR1::ERRIE::SET + CR1::NACKIE::SET + CR1::TCIE::SET);
446        self.registers.cr2.modify(CR2::START::SET);
447    }
448
449    fn stop(&self) {
450        self.registers.cr1.modify(
451            CR1::TXIE::CLEAR
452                + CR1::ERRIE::CLEAR
453                + CR1::NACKIE::CLEAR
454                + CR1::TCIE::CLEAR
455                + CR1::STOPIE::CLEAR
456                + CR1::RXIE::CLEAR,
457        );
458        self.status.set(I2CStatus::Idle);
459    }
460
461    fn start_read(&self) {
462        self.rx_position.set(0);
463        self.registers
464            .cr2
465            .modify(CR2::NBYTES.val(self.rx_len.get() as u32));
466        self.registers
467            .cr2
468            .modify(CR2::SADD7_1.val(self.slave_address.get() as u32));
469        self.registers.cr2.modify(CR2::AUTOEND::CLEAR);
470        self.registers.cr2.modify(CR2::RD_WRN::SET);
471        self.registers
472            .cr1
473            .modify(CR1::ERRIE::SET + CR1::NACKIE::SET + CR1::TCIE::SET + CR1::RXIE::SET);
474        self.registers.cr2.modify(CR2::START::SET);
475    }
476}
477
478impl<'a> i2c::I2CMaster<'a> for I2C<'a> {
479    fn set_master_client(&self, master_client: &'a dyn I2CHwMasterClient) {
480        self.master_client.replace(master_client);
481    }
482    fn enable(&self) {
483        self.registers.cr1.modify(CR1::PE::SET);
484    }
485    fn disable(&self) {
486        self.registers.cr1.modify(CR1::PE::CLEAR);
487    }
488    fn write_read(
489        &self,
490        addr: u8,
491        data: &'static mut [u8],
492        write_len: usize,
493        read_len: usize,
494    ) -> Result<(), (Error, &'static mut [u8])> {
495        if self.status.get() == I2CStatus::Idle {
496            self.reset();
497            self.status.set(I2CStatus::WritingReading);
498            self.slave_address.set(addr);
499            self.buffer.replace(data);
500            self.tx_len.set(write_len);
501            self.rx_len.set(read_len);
502            self.registers.cr2.modify(CR2::AUTOEND::CLEAR);
503            self.start_write();
504            Ok(())
505        } else {
506            Err((Error::Busy, data))
507        }
508    }
509    fn write(
510        &self,
511        addr: u8,
512        data: &'static mut [u8],
513        len: usize,
514    ) -> Result<(), (Error, &'static mut [u8])> {
515        if self.status.get() == I2CStatus::Idle {
516            self.reset();
517            self.status.set(I2CStatus::Writing);
518            self.slave_address.set(addr);
519            self.buffer.replace(data);
520            self.tx_len.set(len);
521            self.registers.cr2.modify(CR2::AUTOEND::CLEAR);
522            self.start_write();
523            Ok(())
524        } else {
525            Err((Error::Busy, data))
526        }
527    }
528    fn read(
529        &self,
530        addr: u8,
531        buffer: &'static mut [u8],
532        len: usize,
533    ) -> Result<(), (Error, &'static mut [u8])> {
534        if self.status.get() == I2CStatus::Idle {
535            self.reset();
536            self.status.set(I2CStatus::Reading);
537            self.slave_address.set(addr);
538            self.buffer.replace(buffer);
539            self.rx_len.set(len);
540            self.registers.cr2.modify(CR2::AUTOEND::CLEAR);
541            self.start_read();
542            Ok(())
543        } else {
544            Err((Error::Busy, buffer))
545        }
546    }
547}
548
549struct I2CClock<'a>(rcc::PeripheralClock<'a>);
550
551impl ClockInterface for I2CClock<'_> {
552    fn is_enabled(&self) -> bool {
553        self.0.is_enabled()
554    }
555
556    fn enable(&self) {
557        self.0.enable();
558    }
559
560    fn disable(&self) {
561        self.0.disable();
562    }
563}