aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/i2c/config.rs149
-rw-r--r--embassy-stm32/src/i2c/mod.rs161
-rw-r--r--embassy-stm32/src/i2c/v2.rs442
3 files changed, 681 insertions, 71 deletions
diff --git a/embassy-stm32/src/i2c/config.rs b/embassy-stm32/src/i2c/config.rs
new file mode 100644
index 000000000..eba14f6e0
--- /dev/null
+++ b/embassy-stm32/src/i2c/config.rs
@@ -0,0 +1,149 @@
1use stm32_metapac::i2c::vals::Oamsk;
2
3use crate::gpio::Pull;
4
5#[repr(u8)]
6#[derive(Copy, Clone)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8pub enum AddrMask {
9 NOMASK,
10 MASK1,
11 MASK2,
12 MASK3,
13 MASK4,
14 MASK5,
15 MASK6,
16 MASK7,
17}
18impl From<AddrMask> for Oamsk {
19 fn from(value: AddrMask) -> Self {
20 match value {
21 AddrMask::NOMASK => Oamsk::NOMASK,
22 AddrMask::MASK1 => Oamsk::MASK1,
23 AddrMask::MASK2 => Oamsk::MASK2,
24 AddrMask::MASK3 => Oamsk::MASK3,
25 AddrMask::MASK4 => Oamsk::MASK4,
26 AddrMask::MASK5 => Oamsk::MASK5,
27 AddrMask::MASK6 => Oamsk::MASK6,
28 AddrMask::MASK7 => Oamsk::MASK7,
29 }
30 }
31}
32
33#[derive(Debug, Copy, Clone, PartialEq, Eq)]
34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
35pub enum Address {
36 SevenBit(u8),
37 TenBit(u16),
38}
39impl From<u8> for Address {
40 fn from(value: u8) -> Self {
41 Address::SevenBit(value)
42 }
43}
44impl From<u16> for Address {
45 fn from(value: u16) -> Self {
46 assert!(value < 0x400, "Ten bit address must be less than 0x400");
47 Address::TenBit(value)
48 }
49}
50impl Address {
51 pub(super) fn add_mode(&self) -> stm32_metapac::i2c::vals::Addmode {
52 match self {
53 Address::SevenBit(_) => stm32_metapac::i2c::vals::Addmode::BIT7,
54 Address::TenBit(_) => stm32_metapac::i2c::vals::Addmode::BIT10,
55 }
56 }
57 pub fn addr(&self) -> u16 {
58 match self {
59 Address::SevenBit(addr) => *addr as u16,
60 Address::TenBit(addr) => *addr,
61 }
62 }
63}
64
65#[derive(Copy, Clone)]
66#[cfg_attr(feature = "defmt", derive(defmt::Format))]
67pub struct OA2 {
68 pub addr: u8,
69 pub mask: AddrMask,
70}
71
72#[derive(Copy, Clone)]
73#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74pub enum OwnAddresses {
75 OA1(Address),
76 OA2(OA2),
77 Both { oa1: Address, oa2: OA2 },
78}
79
80/// Slave Configuration
81#[derive(Copy, Clone)]
82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
83pub struct SlaveAddrConfig {
84 /// Target Address(es)
85 pub addr: OwnAddresses,
86 /// Control if the peripheral should respond to the general call address
87 pub general_call: bool,
88}
89impl SlaveAddrConfig {
90 pub fn new_oa1(addr: Address, general_call: bool) -> Self {
91 Self {
92 addr: OwnAddresses::OA1(addr),
93 general_call,
94 }
95 }
96
97 pub fn basic(addr: Address) -> Self {
98 Self {
99 addr: OwnAddresses::OA1(addr),
100 general_call: false,
101 }
102 }
103}
104
105/// I2C config
106#[non_exhaustive]
107#[derive(Copy, Clone)]
108pub struct Config {
109 /// Enable internal pullup on SDA.
110 ///
111 /// Using external pullup resistors is recommended for I2C. If you do
112 /// have external pullups you should not enable this.
113 pub sda_pullup: bool,
114 /// Enable internal pullup on SCL.
115 ///
116 /// Using external pullup resistors is recommended for I2C. If you do
117 /// have external pullups you should not enable this.
118 pub scl_pullup: bool,
119 /// Timeout.
120 #[cfg(feature = "time")]
121 pub timeout: embassy_time::Duration,
122}
123
124impl Default for Config {
125 fn default() -> Self {
126 Self {
127 sda_pullup: false,
128 scl_pullup: false,
129 #[cfg(feature = "time")]
130 timeout: embassy_time::Duration::from_millis(1000),
131 }
132 }
133}
134
135impl Config {
136 pub(super) fn scl_pull_mode(&self) -> Pull {
137 match self.scl_pullup {
138 true => Pull::Up,
139 false => Pull::Down,
140 }
141 }
142
143 pub(super) fn sda_pull_mode(&self) -> Pull {
144 match self.sda_pullup {
145 true => Pull::Up,
146 false => Pull::Down,
147 }
148 }
149}
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 739e960b9..0457595d2 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -5,14 +5,18 @@
5#[cfg_attr(any(i2c_v2, i2c_v3), path = "v2.rs")] 5#[cfg_attr(any(i2c_v2, i2c_v3), path = "v2.rs")]
6mod _version; 6mod _version;
7 7
8mod config;
9
8use core::future::Future; 10use core::future::Future;
9use core::iter; 11use core::iter;
10use core::marker::PhantomData; 12use core::marker::PhantomData;
11 13
14pub use config::*;
12use embassy_hal_internal::{Peripheral, PeripheralRef}; 15use embassy_hal_internal::{Peripheral, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 16use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 17#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 18use embassy_time::{Duration, Instant};
19use mode::{Master, MasterMode, MultiMaster};
16 20
17use crate::dma::ChannelAndRequest; 21use crate::dma::ChannelAndRequest;
18#[cfg(gpio_v2)] 22#[cfg(gpio_v2)]
@@ -108,8 +112,56 @@ impl Config {
108 } 112 }
109} 113}
110 114
115/// I2C modes
116pub mod mode {
117 trait SealedMode {}
118
119 /// Trait for I2C master operations.
120 #[allow(private_bounds)]
121 pub trait MasterMode: SealedMode {}
122
123 /// Mode allowing for I2C master operations.
124 pub struct Master;
125 /// Mode allowing for I2C master and slave operations.
126 pub struct MultiMaster;
127
128 impl SealedMode for Master {}
129 impl MasterMode for Master {}
130
131 impl SealedMode for MultiMaster {}
132 impl MasterMode for MultiMaster {}
133}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
136#[cfg_attr(feature = "defmt", derive(defmt::Format))]
137/// The command kind to the slave from the master
138pub enum CommandKind {
139 /// Write to the slave
140 SlaveReceive,
141 /// Read from the slave
142 SlaveSend,
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
146#[cfg_attr(feature = "defmt", derive(defmt::Format))]
147/// The command kind to the slave from the master and the address that the slave matched
148pub struct Command {
149 pub kind: CommandKind,
150 pub address: Address,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
154#[cfg_attr(feature = "defmt", derive(defmt::Format))]
155/// The status of the slave send operation
156pub enum SendStatus {
157 /// The slave send operation is done, all bytes have been sent and the master is not requesting more
158 Done,
159 /// The slave send operation is done, but there are leftover bytes that the master did not read
160 LeftoverBytes(usize),
161}
162
111/// I2C driver. 163/// I2C driver.
112pub struct I2c<'d, M: Mode> { 164pub struct I2c<'d, M: Mode, IM: MasterMode> {
113 info: &'static Info, 165 info: &'static Info,
114 state: &'static State, 166 state: &'static State,
115 kernel_clock: Hertz, 167 kernel_clock: Hertz,
@@ -120,9 +172,10 @@ pub struct I2c<'d, M: Mode> {
120 #[cfg(feature = "time")] 172 #[cfg(feature = "time")]
121 timeout: Duration, 173 timeout: Duration,
122 _phantom: PhantomData<M>, 174 _phantom: PhantomData<M>,
175 _phantom2: PhantomData<IM>,
123} 176}
124 177
125impl<'d> I2c<'d, Async> { 178impl<'d> I2c<'d, Async, Master> {
126 /// Create a new I2C driver. 179 /// Create a new I2C driver.
127 pub fn new<T: Instance>( 180 pub fn new<T: Instance>(
128 peri: impl Peripheral<P = T> + 'd, 181 peri: impl Peripheral<P = T> + 'd,
@@ -148,7 +201,7 @@ impl<'d> I2c<'d, Async> {
148 } 201 }
149} 202}
150 203
151impl<'d> I2c<'d, Blocking> { 204impl<'d> I2c<'d, Blocking, Master> {
152 /// Create a new blocking I2C driver. 205 /// Create a new blocking I2C driver.
153 pub fn new_blocking<T: Instance>( 206 pub fn new_blocking<T: Instance>(
154 peri: impl Peripheral<P = T> + 'd, 207 peri: impl Peripheral<P = T> + 'd,
@@ -169,7 +222,7 @@ impl<'d> I2c<'d, Blocking> {
169 } 222 }
170} 223}
171 224
172impl<'d, M: Mode> I2c<'d, M> { 225impl<'d, M: Mode> I2c<'d, M, Master> {
173 /// Create a new I2C driver. 226 /// Create a new I2C driver.
174 fn new_inner<T: Instance>( 227 fn new_inner<T: Instance>(
175 _peri: impl Peripheral<P = T> + 'd, 228 _peri: impl Peripheral<P = T> + 'd,
@@ -194,8 +247,10 @@ impl<'d, M: Mode> I2c<'d, M> {
194 #[cfg(feature = "time")] 247 #[cfg(feature = "time")]
195 timeout: config.timeout, 248 timeout: config.timeout,
196 _phantom: PhantomData, 249 _phantom: PhantomData,
250 _phantom2: PhantomData,
197 }; 251 };
198 this.enable_and_init(freq, config); 252 this.enable_and_init(freq, config);
253
199 this 254 this
200 } 255 }
201 256
@@ -203,7 +258,9 @@ impl<'d, M: Mode> I2c<'d, M> {
203 self.info.rcc.enable_and_reset(); 258 self.info.rcc.enable_and_reset();
204 self.init(freq, config); 259 self.init(freq, config);
205 } 260 }
261}
206 262
263impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
207 fn timeout(&self) -> Timeout { 264 fn timeout(&self) -> Timeout {
208 Timeout { 265 Timeout {
209 #[cfg(feature = "time")] 266 #[cfg(feature = "time")]
@@ -211,8 +268,28 @@ impl<'d, M: Mode> I2c<'d, M> {
211 } 268 }
212 } 269 }
213} 270}
271impl<'d, M: Mode> I2c<'d, M, Master> {
272 /// Configure the I2C driver for slave operations, allowing for the driver to be used as a slave and a master (multimaster)
273 pub fn into_slave_multimaster(mut self, slave_addr_config: SlaveAddrConfig) -> I2c<'d, M, MultiMaster> {
274 let mut slave = I2c {
275 info: self.info,
276 state: self.state,
277 kernel_clock: self.kernel_clock,
278 scl: self.scl.take(),
279 sda: self.sda.take(),
280 tx_dma: self.tx_dma.take(),
281 rx_dma: self.rx_dma.take(),
282 #[cfg(feature = "time")]
283 timeout: self.timeout,
284 _phantom: PhantomData,
285 _phantom2: PhantomData,
286 };
287 slave.init_slave(slave_addr_config);
288 slave
289 }
290}
214 291
215impl<'d, M: Mode> Drop for I2c<'d, M> { 292impl<'d, M: Mode, IM: MasterMode> Drop for I2c<'d, M, IM> {
216 fn drop(&mut self) { 293 fn drop(&mut self) {
217 self.scl.as_ref().map(|x| x.set_as_disconnected()); 294 self.scl.as_ref().map(|x| x.set_as_disconnected());
218 self.sda.as_ref().map(|x| x.set_as_disconnected()); 295 self.sda.as_ref().map(|x| x.set_as_disconnected());
@@ -329,27 +406,39 @@ foreach_peripheral!(
329 }; 406 };
330); 407);
331 408
332impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M> { 409impl<'d, M: Mode, IM: MasterMode, A: embedded_hal_02::blocking::i2c::AddressMode>
410 embedded_hal_02::blocking::i2c::Read<A> for I2c<'d, M, IM>
411where
412 A: Into<Address>,
413{
333 type Error = Error; 414 type Error = Error;
334 415
335 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 416 fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
336 self.blocking_read(address, buffer) 417 self.blocking_read(address.into(), buffer)
337 } 418 }
338} 419}
339 420
340impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M> { 421impl<'d, M: Mode, IM: MasterMode, A: embedded_hal_02::blocking::i2c::AddressMode>
422 embedded_hal_02::blocking::i2c::Write<A> for I2c<'d, M, IM>
423where
424 A: Into<Address>,
425{
341 type Error = Error; 426 type Error = Error;
342 427
343 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { 428 fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
344 self.blocking_write(address, write) 429 self.blocking_write(address.into(), write)
345 } 430 }
346} 431}
347 432
348impl<'d, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M> { 433impl<'d, M: Mode, IM: MasterMode, A: embedded_hal_02::blocking::i2c::AddressMode>
434 embedded_hal_02::blocking::i2c::WriteRead<A> for I2c<'d, M, IM>
435where
436 A: Into<Address>,
437{
349 type Error = Error; 438 type Error = Error;
350 439
351 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { 440 fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
352 self.blocking_write_read(address, write, read) 441 self.blocking_write_read(address.into(), write, read)
353 } 442 }
354} 443}
355 444
@@ -369,51 +458,57 @@ impl embedded_hal_1::i2c::Error for Error {
369 } 458 }
370} 459}
371 460
372impl<'d, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, M> { 461impl<'d, M: Mode, IM: MasterMode> embedded_hal_1::i2c::ErrorType for I2c<'d, M, IM> {
373 type Error = Error; 462 type Error = Error;
374} 463}
375 464
376impl<'d, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, M> { 465impl<'d, M: Mode, IM: MasterMode, A: embedded_hal_1::i2c::AddressMode> embedded_hal_1::i2c::I2c<A> for I2c<'d, M, IM>
377 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 466where
378 self.blocking_read(address, read) 467 Address: From<A>,
468{
469 fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
470 self.blocking_read(address.into(), read)
379 } 471 }
380 472
381 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { 473 fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
382 self.blocking_write(address, write) 474 self.blocking_write(address.into(), write)
383 } 475 }
384 476
385 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { 477 fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
386 self.blocking_write_read(address, write, read) 478 self.blocking_write_read(address.into(), write, read)
387 } 479 }
388 480
389 fn transaction( 481 fn transaction(
390 &mut self, 482 &mut self,
391 address: u8, 483 address: A,
392 operations: &mut [embedded_hal_1::i2c::Operation<'_>], 484 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
393 ) -> Result<(), Self::Error> { 485 ) -> Result<(), Self::Error> {
394 self.blocking_transaction(address, operations) 486 self.blocking_transaction(address.into(), operations)
395 } 487 }
396} 488}
397 489
398impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> { 490impl<'d, IM: MasterMode, A: embedded_hal_async::i2c::AddressMode> embedded_hal_async::i2c::I2c<A> for I2c<'d, Async, IM>
399 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 491where
400 self.read(address, read).await 492 Address: From<A>,
493{
494 async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
495 self.read(address.into(), read).await
401 } 496 }
402 497
403 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { 498 async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
404 self.write(address, write).await 499 self.write(address.into(), write).await
405 } 500 }
406 501
407 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { 502 async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
408 self.write_read(address, write, read).await 503 self.write_read(address.into(), write, read).await
409 } 504 }
410 505
411 async fn transaction( 506 async fn transaction(
412 &mut self, 507 &mut self,
413 address: u8, 508 address: A,
414 operations: &mut [embedded_hal_1::i2c::Operation<'_>], 509 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
415 ) -> Result<(), Self::Error> { 510 ) -> Result<(), Self::Error> {
416 self.transaction(address, operations).await 511 self.transaction(address.into(), operations).await
417 } 512 }
418} 513}
419 514
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 8c8df79dd..c2560d819 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -2,9 +2,12 @@ use core::cmp;
2use core::future::poll_fn; 2use core::future::poll_fn;
3use core::task::Poll; 3use core::task::Poll;
4 4
5use config::{Address, OwnAddresses, OA2};
5use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
6use embassy_hal_internal::drop::OnDrop; 7use embassy_hal_internal::drop::OnDrop;
7use embedded_hal_1::i2c::Operation; 8use embedded_hal_1::i2c::Operation;
9use mode::Master;
10use stm32_metapac::i2c::vals::Addmode;
8 11
9use super::*; 12use super::*;
10use crate::pac::i2c; 13use crate::pac::i2c;
@@ -13,17 +16,21 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
13 let regs = T::info().regs; 16 let regs = T::info().regs;
14 let isr = regs.isr().read(); 17 let isr = regs.isr().read();
15 18
16 if isr.tcr() || isr.tc() { 19 if isr.tcr() || isr.tc() || isr.addr() || isr.stopf() {
17 T::state().waker.wake(); 20 T::state().waker.wake();
18 } 21 }
19 // The flag can only be cleared by writting to nbytes, we won't do that here, so disable 22
20 // the interrupt
21 critical_section::with(|_| { 23 critical_section::with(|_| {
22 regs.cr1().modify(|w| w.set_tcie(false)); 24 regs.cr1().modify(|w| {
25 w.set_addrie(false);
26 // The flag can only be cleared by writting to nbytes, we won't do that here, so disable
27 // the interrupt
28 w.set_tcie(false);
29 });
23 }); 30 });
24} 31}
25 32
26impl<'d, M: Mode> I2c<'d, M> { 33impl<'d, M: Mode, IM: MasterMode> I2c<'d, M, IM> {
27 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 34 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
28 self.info.regs.cr1().modify(|reg| { 35 self.info.regs.cr1().modify(|reg| {
29 reg.set_pe(false); 36 reg.set_pe(false);
@@ -51,7 +58,7 @@ impl<'d, M: Mode> I2c<'d, M> {
51 58
52 fn master_read( 59 fn master_read(
53 info: &'static Info, 60 info: &'static Info,
54 address: u8, 61 address: Address,
55 length: usize, 62 length: usize,
56 stop: Stop, 63 stop: Stop,
57 reload: bool, 64 reload: bool,
@@ -80,8 +87,8 @@ impl<'d, M: Mode> I2c<'d, M> {
80 }; 87 };
81 88
82 info.regs.cr2().modify(|w| { 89 info.regs.cr2().modify(|w| {
83 w.set_sadd((address << 1 | 0) as u16); 90 w.set_sadd(address.addr() << 1);
84 w.set_add10(i2c::vals::Addmode::BIT7); 91 w.set_add10(address.add_mode());
85 w.set_dir(i2c::vals::Dir::READ); 92 w.set_dir(i2c::vals::Dir::READ);
86 w.set_nbytes(length as u8); 93 w.set_nbytes(length as u8);
87 w.set_start(true); 94 w.set_start(true);
@@ -94,7 +101,7 @@ impl<'d, M: Mode> I2c<'d, M> {
94 101
95 fn master_write( 102 fn master_write(
96 info: &'static Info, 103 info: &'static Info,
97 address: u8, 104 address: Address,
98 length: usize, 105 length: usize,
99 stop: Stop, 106 stop: Stop,
100 reload: bool, 107 reload: bool,
@@ -124,8 +131,8 @@ impl<'d, M: Mode> I2c<'d, M> {
124 // START bit can be set even if the bus is BUSY or 131 // START bit can be set even if the bus is BUSY or
125 // I2C is in slave mode. 132 // I2C is in slave mode.
126 info.regs.cr2().modify(|w| { 133 info.regs.cr2().modify(|w| {
127 w.set_sadd((address << 1 | 0) as u16); 134 w.set_sadd(address.addr() << 1);
128 w.set_add10(i2c::vals::Addmode::BIT7); 135 w.set_add10(address.add_mode());
129 w.set_dir(i2c::vals::Dir::WRITE); 136 w.set_dir(i2c::vals::Dir::WRITE);
130 w.set_nbytes(length as u8); 137 w.set_nbytes(length as u8);
131 w.set_start(true); 138 w.set_start(true);
@@ -136,14 +143,14 @@ impl<'d, M: Mode> I2c<'d, M> {
136 Ok(()) 143 Ok(())
137 } 144 }
138 145
139 fn master_continue(info: &'static Info, length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { 146 fn reload(info: &'static Info, length: usize, will_reload: bool, timeout: Timeout) -> Result<(), Error> {
140 assert!(length < 256 && length > 0); 147 assert!(length < 256 && length > 0);
141 148
142 while !info.regs.isr().read().tcr() { 149 while !info.regs.isr().read().tcr() {
143 timeout.check()?; 150 timeout.check()?;
144 } 151 }
145 152
146 let reload = if reload { 153 let will_reload = if will_reload {
147 i2c::vals::Reload::NOTCOMPLETED 154 i2c::vals::Reload::NOTCOMPLETED
148 } else { 155 } else {
149 i2c::vals::Reload::COMPLETED 156 i2c::vals::Reload::COMPLETED
@@ -151,7 +158,7 @@ impl<'d, M: Mode> I2c<'d, M> {
151 158
152 info.regs.cr2().modify(|w| { 159 info.regs.cr2().modify(|w| {
153 w.set_nbytes(length as u8); 160 w.set_nbytes(length as u8);
154 w.set_reload(reload); 161 w.set_reload(will_reload);
155 }); 162 });
156 163
157 Ok(()) 164 Ok(())
@@ -229,7 +236,13 @@ impl<'d, M: Mode> I2c<'d, M> {
229 } 236 }
230 } 237 }
231 238
232 fn read_internal(&mut self, address: u8, read: &mut [u8], restart: bool, timeout: Timeout) -> Result<(), Error> { 239 fn read_internal(
240 &mut self,
241 address: Address,
242 read: &mut [u8],
243 restart: bool,
244 timeout: Timeout,
245 ) -> Result<(), Error> {
233 let completed_chunks = read.len() / 255; 246 let completed_chunks = read.len() / 255;
234 let total_chunks = if completed_chunks * 255 == read.len() { 247 let total_chunks = if completed_chunks * 255 == read.len() {
235 completed_chunks 248 completed_chunks
@@ -250,7 +263,7 @@ impl<'d, M: Mode> I2c<'d, M> {
250 263
251 for (number, chunk) in read.chunks_mut(255).enumerate() { 264 for (number, chunk) in read.chunks_mut(255).enumerate() {
252 if number != 0 { 265 if number != 0 {
253 Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 266 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
254 } 267 }
255 268
256 for byte in chunk { 269 for byte in chunk {
@@ -263,7 +276,13 @@ impl<'d, M: Mode> I2c<'d, M> {
263 Ok(()) 276 Ok(())
264 } 277 }
265 278
266 fn write_internal(&mut self, address: u8, write: &[u8], send_stop: bool, timeout: Timeout) -> Result<(), Error> { 279 fn write_internal(
280 &mut self,
281 address: Address,
282 write: &[u8],
283 send_stop: bool,
284 timeout: Timeout,
285 ) -> Result<(), Error> {
267 let completed_chunks = write.len() / 255; 286 let completed_chunks = write.len() / 255;
268 let total_chunks = if completed_chunks * 255 == write.len() { 287 let total_chunks = if completed_chunks * 255 == write.len() {
269 completed_chunks 288 completed_chunks
@@ -291,7 +310,7 @@ impl<'d, M: Mode> I2c<'d, M> {
291 310
292 for (number, chunk) in write.chunks(255).enumerate() { 311 for (number, chunk) in write.chunks(255).enumerate() {
293 if number != 0 { 312 if number != 0 {
294 Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; 313 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
295 } 314 }
296 315
297 for byte in chunk { 316 for byte in chunk {
@@ -320,18 +339,18 @@ impl<'d, M: Mode> I2c<'d, M> {
320 // Blocking public API 339 // Blocking public API
321 340
322 /// Blocking read. 341 /// Blocking read.
323 pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { 342 pub fn blocking_read(&mut self, address: Address, read: &mut [u8]) -> Result<(), Error> {
324 self.read_internal(address, read, false, self.timeout()) 343 self.read_internal(address, read, false, self.timeout())
325 // Automatic Stop 344 // Automatic Stop
326 } 345 }
327 346
328 /// Blocking write. 347 /// Blocking write.
329 pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { 348 pub fn blocking_write(&mut self, address: Address, write: &[u8]) -> Result<(), Error> {
330 self.write_internal(address, write, true, self.timeout()) 349 self.write_internal(address, write, true, self.timeout())
331 } 350 }
332 351
333 /// Blocking write, restart, read. 352 /// Blocking write, restart, read.
334 pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { 353 pub fn blocking_write_read(&mut self, address: Address, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
335 let timeout = self.timeout(); 354 let timeout = self.timeout();
336 self.write_internal(address, write, false, timeout)?; 355 self.write_internal(address, write, false, timeout)?;
337 self.read_internal(address, read, true, timeout) 356 self.read_internal(address, read, true, timeout)
@@ -343,7 +362,7 @@ impl<'d, M: Mode> I2c<'d, M> {
343 /// Consecutive operations of same type are merged. See [transaction contract] for details. 362 /// Consecutive operations of same type are merged. See [transaction contract] for details.
344 /// 363 ///
345 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 364 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
346 pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 365 pub fn blocking_transaction(&mut self, addr: Address, operations: &mut [Operation<'_>]) -> Result<(), Error> {
347 let _ = addr; 366 let _ = addr;
348 let _ = operations; 367 let _ = operations;
349 todo!() 368 todo!()
@@ -352,7 +371,7 @@ impl<'d, M: Mode> I2c<'d, M> {
352 /// Blocking write multiple buffers. 371 /// Blocking write multiple buffers.
353 /// 372 ///
354 /// The buffers are concatenated in a single write transaction. 373 /// The buffers are concatenated in a single write transaction.
355 pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { 374 pub fn blocking_write_vectored(&mut self, address: Address, write: &[&[u8]]) -> Result<(), Error> {
356 if write.is_empty() { 375 if write.is_empty() {
357 return Err(Error::ZeroLengthTransfer); 376 return Err(Error::ZeroLengthTransfer);
358 } 377 }
@@ -385,7 +404,7 @@ impl<'d, M: Mode> I2c<'d, M> {
385 let last_chunk_idx = total_chunks.saturating_sub(1); 404 let last_chunk_idx = total_chunks.saturating_sub(1);
386 405
387 if idx != 0 { 406 if idx != 0 {
388 if let Err(err) = Self::master_continue( 407 if let Err(err) = Self::reload(
389 self.info, 408 self.info,
390 slice_len.min(255), 409 slice_len.min(255),
391 (idx != last_slice_index) || (slice_len > 255), 410 (idx != last_slice_index) || (slice_len > 255),
@@ -398,7 +417,7 @@ impl<'d, M: Mode> I2c<'d, M> {
398 417
399 for (number, chunk) in slice.chunks(255).enumerate() { 418 for (number, chunk) in slice.chunks(255).enumerate() {
400 if number != 0 { 419 if number != 0 {
401 if let Err(err) = Self::master_continue( 420 if let Err(err) = Self::reload(
402 self.info, 421 self.info,
403 chunk.len(), 422 chunk.len(),
404 (number != last_chunk_idx) || (idx != last_slice_index), 423 (number != last_chunk_idx) || (idx != last_slice_index),
@@ -431,10 +450,10 @@ impl<'d, M: Mode> I2c<'d, M> {
431 } 450 }
432} 451}
433 452
434impl<'d> I2c<'d, Async> { 453impl<'d, IM: MasterMode> I2c<'d, Async, IM> {
435 async fn write_dma_internal( 454 async fn write_dma_internal(
436 &mut self, 455 &mut self,
437 address: u8, 456 address: Address,
438 write: &[u8], 457 write: &[u8],
439 first_slice: bool, 458 first_slice: bool,
440 last_slice: bool, 459 last_slice: bool,
@@ -482,7 +501,7 @@ impl<'d> I2c<'d, Async> {
482 timeout, 501 timeout,
483 )?; 502 )?;
484 } else { 503 } else {
485 Self::master_continue(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?; 504 Self::reload(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?;
486 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 505 self.info.regs.cr1().modify(|w| w.set_tcie(true));
487 } 506 }
488 } else if !(isr.tcr() || isr.tc()) { 507 } else if !(isr.tcr() || isr.tc()) {
@@ -493,7 +512,7 @@ impl<'d> I2c<'d, Async> {
493 } else { 512 } else {
494 let last_piece = (remaining_len <= 255) && last_slice; 513 let last_piece = (remaining_len <= 255) && last_slice;
495 514
496 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { 515 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) {
497 return Poll::Ready(Err(e)); 516 return Poll::Ready(Err(e));
498 } 517 }
499 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 518 self.info.regs.cr1().modify(|w| w.set_tcie(true));
@@ -519,7 +538,7 @@ impl<'d> I2c<'d, Async> {
519 538
520 async fn read_dma_internal( 539 async fn read_dma_internal(
521 &mut self, 540 &mut self,
522 address: u8, 541 address: Address,
523 buffer: &mut [u8], 542 buffer: &mut [u8],
524 restart: bool, 543 restart: bool,
525 timeout: Timeout, 544 timeout: Timeout,
@@ -569,7 +588,7 @@ impl<'d> I2c<'d, Async> {
569 } else { 588 } else {
570 let last_piece = remaining_len <= 255; 589 let last_piece = remaining_len <= 255;
571 590
572 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { 591 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !last_piece, timeout) {
573 return Poll::Ready(Err(e)); 592 return Poll::Ready(Err(e));
574 } 593 }
575 self.info.regs.cr1().modify(|w| w.set_tcie(true)); 594 self.info.regs.cr1().modify(|w| w.set_tcie(true));
@@ -590,12 +609,11 @@ impl<'d> I2c<'d, Async> {
590 609
591 Ok(()) 610 Ok(())
592 } 611 }
593
594 // ========================= 612 // =========================
595 // Async public API 613 // Async public API
596 614
597 /// Write. 615 /// Write.
598 pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { 616 pub async fn write(&mut self, address: Address, write: &[u8]) -> Result<(), Error> {
599 let timeout = self.timeout(); 617 let timeout = self.timeout();
600 if write.is_empty() { 618 if write.is_empty() {
601 self.write_internal(address, write, true, timeout) 619 self.write_internal(address, write, true, timeout)
@@ -609,7 +627,7 @@ impl<'d> I2c<'d, Async> {
609 /// Write multiple buffers. 627 /// Write multiple buffers.
610 /// 628 ///
611 /// The buffers are concatenated in a single write transaction. 629 /// The buffers are concatenated in a single write transaction.
612 pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> { 630 pub async fn write_vectored(&mut self, address: Address, write: &[&[u8]]) -> Result<(), Error> {
613 let timeout = self.timeout(); 631 let timeout = self.timeout();
614 632
615 if write.is_empty() { 633 if write.is_empty() {
@@ -632,7 +650,7 @@ impl<'d> I2c<'d, Async> {
632 } 650 }
633 651
634 /// Read. 652 /// Read.
635 pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { 653 pub async fn read(&mut self, address: Address, buffer: &mut [u8]) -> Result<(), Error> {
636 let timeout = self.timeout(); 654 let timeout = self.timeout();
637 655
638 if buffer.is_empty() { 656 if buffer.is_empty() {
@@ -644,7 +662,7 @@ impl<'d> I2c<'d, Async> {
644 } 662 }
645 663
646 /// Write, restart, read. 664 /// Write, restart, read.
647 pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { 665 pub async fn write_read(&mut self, address: Address, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
648 let timeout = self.timeout(); 666 let timeout = self.timeout();
649 667
650 if write.is_empty() { 668 if write.is_empty() {
@@ -669,13 +687,343 @@ impl<'d> I2c<'d, Async> {
669 /// Consecutive operations of same type are merged. See [transaction contract] for details. 687 /// Consecutive operations of same type are merged. See [transaction contract] for details.
670 /// 688 ///
671 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction 689 /// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
672 pub async fn transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> { 690 pub async fn transaction(&mut self, addr: Address, operations: &mut [Operation<'_>]) -> Result<(), Error> {
673 let _ = addr; 691 let _ = addr;
674 let _ = operations; 692 let _ = operations;
675 todo!() 693 todo!()
676 } 694 }
677} 695}
678 696
697impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
698 pub(crate) fn init_slave(&mut self, config: SlaveAddrConfig) {
699 self.info.regs.cr1().modify(|reg| {
700 reg.set_pe(false);
701 });
702
703 self.info.regs.cr1().modify(|reg| {
704 reg.set_nostretch(false);
705 reg.set_gcen(config.general_call);
706 reg.set_sbc(true);
707 reg.set_pe(true);
708 });
709
710 self.reconfigure_addresses(config.addr);
711 }
712
713 /// Configure the slave address.
714 pub fn reconfigure_addresses(&mut self, addresses: OwnAddresses) {
715 match addresses {
716 OwnAddresses::OA1(oa1) => self.configure_oa1(oa1),
717 OwnAddresses::OA2(oa2) => self.configure_oa2(oa2),
718 OwnAddresses::Both { oa1, oa2 } => {
719 self.configure_oa1(oa1);
720 self.configure_oa2(oa2);
721 }
722 }
723 }
724
725 fn configure_oa1(&mut self, oa1: Address) {
726 match oa1 {
727 Address::SevenBit(addr) => self.info.regs.oar1().write(|reg| {
728 reg.set_oa1en(false);
729 reg.set_oa1((addr << 1) as u16);
730 reg.set_oa1mode(Addmode::BIT7);
731 reg.set_oa1en(true);
732 }),
733 Address::TenBit(addr) => self.info.regs.oar1().write(|reg| {
734 reg.set_oa1en(false);
735 reg.set_oa1(addr);
736 reg.set_oa1mode(Addmode::BIT10);
737 reg.set_oa1en(true);
738 }),
739 }
740 }
741
742 fn configure_oa2(&mut self, oa2: OA2) {
743 self.info.regs.oar2().write(|reg| {
744 reg.set_oa2en(false);
745 reg.set_oa2msk(oa2.mask.into());
746 reg.set_oa2(oa2.addr << 1);
747 reg.set_oa2en(true);
748 });
749 }
750
751 fn determine_matched_address(&self) -> Result<Address, Error> {
752 let matched = self.info.regs.isr().read().addcode();
753
754 if matched >> 3 == 0b11110 {
755 // is 10-bit address and we need to get the other 8 bits from the rxdr
756 // we do this by doing a blocking read of 1 byte
757 let mut buffer = [0];
758 self.slave_read_internal(&mut buffer, self.timeout())?;
759 Ok(Address::TenBit((matched as u16) << 6 | buffer[0] as u16))
760 } else {
761 Ok(Address::SevenBit(matched))
762 }
763 }
764}
765
766impl<'d, M: Mode> I2c<'d, M, MultiMaster> {
767 /// # Safety
768 /// This function will clear the address flag which will stop the clock stretching.
769 /// This should only be done after the dma transfer has been set up.
770 fn slave_start(info: &'static Info, length: usize, reload: bool) {
771 assert!(length < 256);
772
773 let reload = if reload {
774 i2c::vals::Reload::NOTCOMPLETED
775 } else {
776 i2c::vals::Reload::COMPLETED
777 };
778
779 info.regs.cr2().modify(|w| {
780 w.set_nbytes(length as u8);
781 w.set_reload(reload);
782 });
783
784 // clear the address flag, will stop the clock stretching.
785 // this should only be done after the dma transfer has been set up.
786 info.regs.icr().modify(|reg| reg.set_addrcf(true));
787 }
788
789 // A blocking read operation
790 fn slave_read_internal(&self, read: &mut [u8], timeout: Timeout) -> Result<(), Error> {
791 let completed_chunks = read.len() / 255;
792 let total_chunks = if completed_chunks * 255 == read.len() {
793 completed_chunks
794 } else {
795 completed_chunks + 1
796 };
797 let last_chunk_idx = total_chunks.saturating_sub(1);
798 for (number, chunk) in read.chunks_mut(255).enumerate() {
799 if number != 0 {
800 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
801 }
802
803 for byte in chunk {
804 // Wait until we have received something
805 self.wait_rxne(timeout)?;
806
807 *byte = self.info.regs.rxdr().read().rxdata();
808 }
809 }
810
811 Ok(())
812 }
813
814 // A blocking write operation
815 fn slave_write_internal(&mut self, write: &[u8], timeout: Timeout) -> Result<(), Error> {
816 let completed_chunks = write.len() / 255;
817 let total_chunks = if completed_chunks * 255 == write.len() {
818 completed_chunks
819 } else {
820 completed_chunks + 1
821 };
822 let last_chunk_idx = total_chunks.saturating_sub(1);
823
824 for (number, chunk) in write.chunks(255).enumerate() {
825 if number != 0 {
826 Self::reload(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
827 }
828
829 for byte in chunk {
830 // Wait until we are allowed to send data
831 // (START has been ACKed or last byte when
832 // through)
833 self.wait_txe(timeout)?;
834
835 self.info.regs.txdr().write(|w| w.set_txdata(*byte));
836 }
837 }
838 Ok(())
839 }
840
841 /// Listen for incoming I2C messages.
842 ///
843 /// The listen method is an asynchronous method but it does not require DMA to be asynchronous.
844 pub async fn listen(&mut self) -> Result<Command, Error> {
845 let state = self.state;
846 self.info.regs.cr1().modify(|reg| {
847 reg.set_addrie(true);
848 });
849
850 poll_fn(|cx| {
851 state.waker.register(cx.waker());
852 let isr = self.info.regs.isr().read();
853 if !isr.addr() {
854 Poll::Pending
855 } else {
856 // we do not clear the address flag here as it will be cleared by the dma read/write
857 // if we clear it here the clock stretching will stop and the master will read in data before the slave is ready to send it
858 match isr.dir() {
859 i2c::vals::Dir::WRITE => Poll::Ready(Ok(Command {
860 kind: CommandKind::SlaveReceive,
861 address: self.determine_matched_address()?,
862 })),
863 i2c::vals::Dir::READ => Poll::Ready(Ok(Command {
864 kind: CommandKind::SlaveSend,
865 address: self.determine_matched_address()?,
866 })),
867 }
868 }
869 })
870 .await
871 }
872
873 /// Respond to a receive command.
874 pub fn blocking_respond_to_receive(&self, read: &mut [u8]) -> Result<(), Error> {
875 let timeout = self.timeout();
876 self.slave_read_internal(read, timeout)
877 }
878
879 /// Respond to a send command.
880 pub fn blocking_respond_to_send(&mut self, write: &[u8]) -> Result<(), Error> {
881 let timeout = self.timeout();
882 self.slave_write_internal(write, timeout)
883 }
884}
885
886impl<'d> I2c<'d, Async, MultiMaster> {
887 /// Respond to a receive command.
888 pub async fn respond_to_receive(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
889 let timeout = self.timeout();
890 timeout.with(self.read_dma_internal_slave(buffer, timeout)).await
891 }
892
893 /// Respond to a send request from an I2C master.
894 pub async fn respond_to_send(&mut self, write: &[u8]) -> Result<SendStatus, Error> {
895 let timeout = self.timeout();
896 timeout.with(self.write_dma_internal_slave(write, timeout)).await
897 }
898
899 // for data reception in slave mode
900 async fn read_dma_internal_slave(&mut self, buffer: &mut [u8], timeout: Timeout) -> Result<usize, Error> {
901 let total_len = buffer.len();
902 let mut remaining_len = total_len;
903
904 let regs = self.info.regs;
905
906 let dma_transfer = unsafe {
907 regs.cr1().modify(|w| {
908 w.set_rxdmaen(true);
909 w.set_stopie(true);
910 w.set_tcie(true);
911 });
912 let src = regs.rxdr().as_ptr() as *mut u8;
913
914 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
915 };
916
917 let state = self.state;
918
919 let on_drop = OnDrop::new(|| {
920 regs.cr1().modify(|w| {
921 w.set_rxdmaen(false);
922 w.set_stopie(false);
923 w.set_tcie(false);
924 })
925 });
926
927 let total_received = poll_fn(|cx| {
928 state.waker.register(cx.waker());
929
930 let isr = regs.isr().read();
931
932 if remaining_len == total_len {
933 Self::slave_start(self.info, total_len.min(255), total_len > 255);
934 remaining_len = remaining_len.saturating_sub(255);
935 Poll::Pending
936 } else if isr.tcr() {
937 let is_last_slice = remaining_len <= 255;
938 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) {
939 return Poll::Ready(Err(e));
940 }
941 remaining_len = remaining_len.saturating_sub(255);
942 regs.cr1().modify(|w| w.set_tcie(true));
943 Poll::Pending
944 } else if isr.stopf() {
945 regs.icr().write(|reg| reg.set_stopcf(true));
946 let poll = Poll::Ready(Ok(remaining_len));
947 poll
948 } else {
949 Poll::Pending
950 }
951 })
952 .await?;
953
954 dma_transfer.await;
955
956 drop(on_drop);
957
958 Ok(total_received)
959 }
960
961 async fn write_dma_internal_slave(&mut self, buffer: &[u8], timeout: Timeout) -> Result<SendStatus, Error> {
962 let total_len = buffer.len();
963 let mut remaining_len = total_len;
964
965 let mut dma_transfer = unsafe {
966 let regs = self.info.regs;
967 regs.cr1().modify(|w| {
968 w.set_txdmaen(true);
969 w.set_stopie(true);
970 w.set_tcie(true);
971 });
972 let dst = regs.txdr().as_ptr() as *mut u8;
973
974 self.tx_dma.as_mut().unwrap().write(buffer, dst, Default::default())
975 };
976
977 let on_drop = OnDrop::new(|| {
978 let regs = self.info.regs;
979 regs.cr1().modify(|w| {
980 w.set_txdmaen(false);
981 w.set_stopie(false);
982 w.set_tcie(false);
983 })
984 });
985
986 let state = self.state;
987
988 let size = poll_fn(|cx| {
989 state.waker.register(cx.waker());
990
991 let isr = self.info.regs.isr().read();
992
993 if remaining_len == total_len {
994 Self::slave_start(self.info, total_len.min(255), total_len > 255);
995 remaining_len = remaining_len.saturating_sub(255);
996 Poll::Pending
997 } else if isr.tcr() {
998 let is_last_slice = remaining_len <= 255;
999 if let Err(e) = Self::reload(self.info, remaining_len.min(255), !is_last_slice, timeout) {
1000 return Poll::Ready(Err(e));
1001 }
1002 remaining_len = remaining_len.saturating_sub(255);
1003 self.info.regs.cr1().modify(|w| w.set_tcie(true));
1004 Poll::Pending
1005 } else if isr.stopf() {
1006 self.info.regs.icr().write(|reg| reg.set_stopcf(true));
1007 if remaining_len > 0 {
1008 dma_transfer.request_stop();
1009 Poll::Ready(Ok(SendStatus::LeftoverBytes(remaining_len as usize)))
1010 } else {
1011 Poll::Ready(Ok(SendStatus::Done))
1012 }
1013 } else {
1014 Poll::Pending
1015 }
1016 })
1017 .await?;
1018
1019 dma_transfer.await;
1020
1021 drop(on_drop);
1022
1023 Ok(size)
1024 }
1025}
1026
679/// I2C Stop Configuration 1027/// I2C Stop Configuration
680/// 1028///
681/// Peripheral options for generating the STOP condition 1029/// Peripheral options for generating the STOP condition
@@ -800,7 +1148,7 @@ impl Timings {
800 } 1148 }
801} 1149}
802 1150
803impl<'d, M: Mode> SetConfig for I2c<'d, M> { 1151impl<'d, M: Mode> SetConfig for I2c<'d, M, Master> {
804 type Config = Hertz; 1152 type Config = Hertz;
805 type ConfigError = (); 1153 type ConfigError = ();
806 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 1154 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
@@ -816,3 +1164,21 @@ impl<'d, M: Mode> SetConfig for I2c<'d, M> {
816 Ok(()) 1164 Ok(())
817 } 1165 }
818} 1166}
1167
1168impl<'d, M: Mode> SetConfig for I2c<'d, M, MultiMaster> {
1169 type Config = (Hertz, SlaveAddrConfig);
1170 type ConfigError = ();
1171 fn set_config(&mut self, (config, addr_config): &Self::Config) -> Result<(), ()> {
1172 let timings = Timings::new(self.kernel_clock, *config);
1173 self.info.regs.timingr().write(|reg| {
1174 reg.set_presc(timings.prescale);
1175 reg.set_scll(timings.scll);
1176 reg.set_sclh(timings.sclh);
1177 reg.set_sdadel(timings.sdadel);
1178 reg.set_scldel(timings.scldel);
1179 });
1180 self.init_slave(*addr_config);
1181
1182 Ok(())
1183 }
1184}