stm32g0xx_hal/i2c/
config.rs

1use crate::i2c::SlaveAddressMask;
2use crate::time::Hertz;
3use core::cmp;
4
5pub struct Config {
6    pub speed: Option<Hertz>,
7    pub timing: Option<u32>,
8    pub analog_filter: bool,
9    pub digital_filter: u8,
10    pub slave_address_1: u16,
11    pub address_11bits: bool,
12    pub slave_address_2: u8,
13    pub slave_address_mask: SlaveAddressMask,
14}
15
16impl Config {
17    pub fn new(speed: Hertz) -> Self {
18        Config {
19            speed: Some(speed),
20            timing: None,
21            analog_filter: true,
22            digital_filter: 0,
23            slave_address_1: 0,
24            address_11bits: false,
25            slave_address_2: 0,
26            slave_address_mask: SlaveAddressMask::MaskNone,
27        }
28    }
29
30    pub fn with_timing(timing: u32) -> Self {
31        Config {
32            timing: Some(timing),
33            speed: None,
34            analog_filter: true,
35            digital_filter: 0,
36            slave_address_1: 0,
37            address_11bits: false,
38            slave_address_2: 0,
39            slave_address_mask: SlaveAddressMask::MaskNone,
40        }
41    }
42
43    pub fn disable_analog_filter(mut self) -> Self {
44        self.analog_filter = false;
45        self
46    }
47
48    pub fn enable_digital_filter(mut self, cycles: u8) -> Self {
49        assert!(cycles <= 16);
50        self.digital_filter = cycles;
51        self
52    }
53
54    pub fn timing_bits(&self, i2c_clk: Hertz) -> u32 {
55        if let Some(bits) = self.timing {
56            return bits;
57        }
58        let speed = self.speed.unwrap();
59        let (psc, scll, sclh, sdadel, scldel) = if speed.raw() <= 100_000 {
60            let psc = 3;
61            let scll = cmp::min((((i2c_clk.raw() >> 1) / (psc + 1)) / speed.raw()) - 1, 255);
62            let sclh = scll - 4;
63            let sdadel = 2;
64            let scldel = 4;
65            (psc, scll, sclh, sdadel, scldel)
66        } else {
67            let psc = 1;
68            let scll = cmp::min((((i2c_clk.raw() >> 1) / (psc + 1)) / speed.raw()) - 1, 255);
69            let sclh = scll - 6;
70            let sdadel = 1;
71            let scldel = 3;
72            (psc, scll, sclh, sdadel, scldel)
73        };
74        psc << 28 | scldel << 20 | sdadel << 16 | sclh << 8 | scll
75    }
76
77    /// Slave address 1 as 7 bit address, in range 0 .. 127
78    pub fn slave_address(&mut self, own_address: u8) {
79        self.slave_address_1 = own_address as u16;
80        self.address_11bits = false;
81    }
82
83    /// Slave address 1 as 11 bit address in range 0 .. 2047
84    pub fn slave_address_11bits(&mut self, own_address: u16) {
85        self.slave_address_1 = own_address;
86        self.address_11bits = true;
87    }
88
89    /// Slave address 2 as 7 bit address in range 0 .. 127.
90    /// The mask makes all slaves within the mask addressable
91    pub fn slave_address_2(&mut self, own_address: u8, mask: SlaveAddressMask) {
92        self.slave_address_2 = own_address;
93        self.slave_address_mask = mask;
94    }
95}
96
97impl From<Hertz> for Config {
98    fn from(speed: Hertz) -> Self {
99        Config::new(speed)
100    }
101}