aboutsummaryrefslogtreecommitdiff
path: root/embassy-mspm0/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mspm0/src')
-rw-r--r--embassy-mspm0/src/i2c.rs1156
-rw-r--r--embassy-mspm0/src/lib.rs5
2 files changed, 1161 insertions, 0 deletions
diff --git a/embassy-mspm0/src/i2c.rs b/embassy-mspm0/src/i2c.rs
new file mode 100644
index 000000000..168cfccda
--- /dev/null
+++ b/embassy-mspm0/src/i2c.rs
@@ -0,0 +1,1156 @@
1#![macro_use]
2
3use core::future;
4use core::marker::PhantomData;
5use core::sync::atomic::{AtomicU32, Ordering};
6use core::task::Poll;
7
8use embassy_embedded_hal::SetConfig;
9use embassy_hal_internal::PeripheralType;
10use embassy_sync::waitqueue::AtomicWaker;
11use mspm0_metapac::i2c;
12
13use crate::gpio::{AnyPin, PfType, Pull, SealedPin};
14use crate::interrupt::typelevel::Binding;
15use crate::interrupt::{Interrupt, InterruptExt};
16use crate::mode::{Async, Blocking, Mode};
17use crate::pac::i2c::{vals, I2c as Regs};
18use crate::pac::{self};
19use crate::Peri;
20
21/// The clock source for the I2C.
22#[derive(Clone, Copy, PartialEq, Eq, Debug)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24pub enum ClockSel {
25 /// Use the bus clock.
26 ///
27 /// By default the BusClk runs at 32 MHz.
28 BusClk,
29
30 /// Use the middle frequency clock.
31 ///
32 /// The MCLK runs at 4 MHz.
33 MfClk,
34 // BusClk,
35 // BusClk depends on the timer's power domain.
36 // This will be implemented later.
37}
38
39/// The clock divider for the I2C.
40#[derive(Clone, Copy, PartialEq, Eq, Debug)]
41#[cfg_attr(feature = "defmt", derive(defmt::Format))]
42pub enum ClockDiv {
43 // "Do not divide clock source.
44 DivBy1,
45 // "Divide clock source by 2.
46 DivBy2,
47 // "Divide clock source by 3.
48 DivBy3,
49 // "Divide clock source by 4.
50 DivBy4,
51 // "Divide clock source by 5.
52 DivBy5,
53 // "Divide clock source by 6.
54 DivBy6,
55 // "Divide clock source by 7.
56 DivBy7,
57 // "Divide clock source by 8.
58 DivBy8,
59}
60
61impl Into<vals::Ratio> for ClockDiv {
62 fn into(self) -> vals::Ratio {
63 match self {
64 Self::DivBy1 => vals::Ratio::DIV_BY_1,
65 Self::DivBy2 => vals::Ratio::DIV_BY_2,
66 Self::DivBy3 => vals::Ratio::DIV_BY_3,
67 Self::DivBy4 => vals::Ratio::DIV_BY_4,
68 Self::DivBy5 => vals::Ratio::DIV_BY_5,
69 Self::DivBy6 => vals::Ratio::DIV_BY_6,
70 Self::DivBy7 => vals::Ratio::DIV_BY_7,
71 Self::DivBy8 => vals::Ratio::DIV_BY_8,
72 }
73 }
74}
75
76impl ClockDiv {
77 fn divider(self) -> u32 {
78 match self {
79 Self::DivBy1 => 1,
80 Self::DivBy2 => 2,
81 Self::DivBy3 => 3,
82 Self::DivBy4 => 4,
83 Self::DivBy5 => 5,
84 Self::DivBy6 => 6,
85 Self::DivBy7 => 7,
86 Self::DivBy8 => 8,
87 }
88 }
89}
90
91/// The I2C mode.
92#[derive(Clone, Copy, PartialEq, Eq, Debug)]
93#[cfg_attr(feature = "defmt", derive(defmt::Format))]
94pub enum BusSpeed {
95 /// Standard mode.
96 ///
97 /// The Standard mode runs at 100 kHz.
98 Standard,
99
100 /// Fast mode.
101 ///
102 /// The fast mode runs at 400 kHz.
103 FastMode,
104
105 /// Fast mode plus.
106 ///
107 /// The fast mode plus runs at 1 MHz.
108 FastModePlus,
109
110 /// Custom mode.
111 ///
112 /// The custom mode frequency (in Hz) can be set manually.
113 Custom(u32),
114}
115
116impl BusSpeed {
117 fn hertz(self) -> u32 {
118 match self {
119 Self::Standard => 100_000,
120 Self::FastMode => 400_000,
121 Self::FastModePlus => 1_000_000,
122 Self::Custom(s) => s,
123 }
124 }
125}
126
127#[non_exhaustive]
128#[derive(Clone, Copy, PartialEq, Eq, Debug)]
129#[cfg_attr(feature = "defmt", derive(defmt::Format))]
130/// Config Error
131pub enum ConfigError {
132 /// The clock rate could not be configured with the given conifguratoin.
133 InvalidClockRate,
134}
135
136#[non_exhaustive]
137#[derive(Clone, Copy, PartialEq, Eq, Debug)]
138/// Config
139pub struct Config {
140 /// I2C clock source.
141 pub clock_source: ClockSel,
142
143 /// I2C clock divider.
144 pub clock_div: ClockDiv,
145
146 /// If true: invert SDA pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle).
147 pub invert_sda: bool,
148
149 /// If true: invert SCL pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle).
150 pub invert_scl: bool,
151
152 /// Set the pull configuration for the SDA pin.
153 pub sda_pull: Pull,
154
155 /// Set the pull configuration for the SCL pin.
156 pub scl_pull: Pull,
157
158 /// Set the pull configuration for the SCL pin.
159 pub bus_speed: BusSpeed,
160}
161
162impl Default for Config {
163 fn default() -> Self {
164 Self {
165 clock_source: ClockSel::BusClk,
166 clock_div: ClockDiv::DivBy1,
167 invert_sda: false,
168 invert_scl: false,
169 sda_pull: Pull::None,
170 scl_pull: Pull::None,
171 bus_speed: BusSpeed::FastMode,
172 }
173 }
174}
175
176impl Config {
177 pub fn sda_pf(&self) -> PfType {
178 PfType::input(self.sda_pull, self.invert_sda)
179 }
180 pub fn scl_pf(&self) -> PfType {
181 PfType::input(self.scl_pull, self.invert_scl)
182 }
183 fn timer_period(&self, clock_speed: u32) -> u8 {
184 // Sets the timer period to bring the clock frequency to the selected I2C speed
185 // From the documentation: SCL_PERIOD = (1 + TPR ) * (SCL_LP + SCL_HP ) * INT_CLK_PRD where:
186 // - SCL_PRD is the SCL line period (I2C clock)
187 // - TPR is the Timer Period register value (range of 1 to 127)
188 // - SCL_LP is the SCL Low period (fixed at 6)
189 // - SCL_HP is the SCL High period (fixed at 4)
190 // - CLK_PRD is the functional clock period in ns
191 let scl_period = (1.0 / self.bus_speed.hertz() as f64) * 1_000_000_000.0;
192 let clock = (clock_speed as f64) / self.clock_div.divider() as f64;
193 let clk_period = (1.0 / clock) * 1_000_000_000.0;
194 let tpr = scl_period / (10.0 * clk_period) - 1.0;
195 tpr.clamp(0.0, 255.0) as u8
196 }
197
198 #[cfg(any(mspm0c110x))]
199 pub fn calculate_clock_rate(&self) -> u32 {
200 // Assume that BusClk has default value.
201 // TODO: calculate BusClk more precisely.
202 match self.clock_source {
203 ClockSel::MfClk => 4_000_000,
204 ClockSel::BusClk => 24_000_000,
205 }
206 }
207
208 #[cfg(any(
209 mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x, mspm0l110x, mspm0l122x, mspm0l130x,
210 mspm0l134x, mspm0l222x
211 ))]
212 pub fn calculate_clock_rate(&self) -> u32 {
213 // Assume that BusClk has default value.
214 // TODO: calculate BusClk more precisely.
215 match self.clock_source {
216 ClockSel::MfClk => 4_000_000,
217 ClockSel::BusClk => 32_000_000,
218 }
219 }
220
221 pub fn check_clock_rate(&self) -> bool {
222 // make sure source clock is ~20 faster than i2c clock
223 let clk_ratio = 20;
224
225 let i2c_clk = self.bus_speed.hertz() / self.clock_div.divider();
226 let src_clk = self.calculate_clock_rate();
227
228 // check clock rate
229 return src_clk >= clk_ratio * i2c_clk;
230 }
231}
232
233/// Serial error
234#[derive(Debug, Eq, PartialEq, Copy, Clone)]
235#[cfg_attr(feature = "defmt", derive(defmt::Format))]
236#[non_exhaustive]
237pub enum Error {
238 /// Bus error
239 Bus,
240
241 /// Arbitration lost
242 Arbitration,
243
244 /// ACK not received (either to the address or to a data byte)
245 Nack,
246
247 /// Timeout
248 Timeout,
249
250 /// CRC error
251 Crc,
252
253 /// Overrun error
254 Overrun,
255
256 /// Zero-length transfers are not allowed.
257 ZeroLengthTransfer,
258}
259
260impl core::fmt::Display for Error {
261 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
262 let message = match self {
263 Self::Bus => "Bus Error",
264 Self::Arbitration => "Arbitration Lost",
265 Self::Nack => "ACK Not Received",
266 Self::Timeout => "Request Timed Out",
267 Self::Crc => "CRC Mismatch",
268 Self::Overrun => "Buffer Overrun",
269 Self::ZeroLengthTransfer => "Zero-Length Transfers are not allowed",
270 };
271
272 write!(f, "{}", message)
273 }
274}
275
276impl core::error::Error for Error {}
277
278/// mspm0g, mspm0c, mspm0l, msps00 have 8-bytes FIFO
279pub const FIFO_SIZE: usize = 8;
280
281/// I2C Driver.
282pub struct I2c<'d, M: Mode> {
283 info: &'static Info,
284 state: &'static State,
285 scl: Option<Peri<'d, AnyPin>>,
286 sda: Option<Peri<'d, AnyPin>>,
287 _phantom: PhantomData<M>,
288}
289
290impl<'d, M: Mode> SetConfig for I2c<'d, M> {
291 type Config = Config;
292 type ConfigError = ConfigError;
293
294 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
295 self.set_config(config)
296 }
297}
298
299impl<'d> I2c<'d, Blocking> {
300 pub fn new_blocking<T: Instance>(
301 peri: Peri<'d, T>,
302 scl: Peri<'d, impl SclPin<T>>,
303 sda: Peri<'d, impl SdaPin<T>>,
304 config: Config,
305 ) -> Result<Self, ConfigError> {
306 if !config.check_clock_rate() {
307 return Err(ConfigError::InvalidClockRate);
308 }
309
310 Self::new_inner(peri, scl, sda, config)
311 }
312}
313
314impl<'d> I2c<'d, Async> {
315 pub fn new_async<T: Instance>(
316 peri: Peri<'d, T>,
317 scl: Peri<'d, impl SclPin<T>>,
318 sda: Peri<'d, impl SdaPin<T>>,
319 _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
320 config: Config,
321 ) -> Result<Self, ConfigError> {
322 if !config.check_clock_rate() {
323 return Err(ConfigError::InvalidClockRate);
324 }
325
326 let i2c = Self::new_inner(peri, scl, sda, config);
327
328 T::info().interrupt.unpend();
329 unsafe { T::info().interrupt.enable() };
330
331 i2c
332 }
333}
334
335impl<'d, M: Mode> I2c<'d, M> {
336 /// Reconfigure the driver
337 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
338 if !config.check_clock_rate() {
339 return Err(ConfigError::InvalidClockRate);
340 }
341
342 self.info.interrupt.disable();
343
344 if let Some(ref sda) = self.sda {
345 sda.update_pf(config.sda_pf());
346 }
347
348 if let Some(ref scl) = self.scl {
349 scl.update_pf(config.scl_pf());
350 }
351
352 self.init(config)
353 }
354
355 fn init(&mut self, config: &Config) -> Result<(), ConfigError> {
356 // Init I2C
357 self.info.regs.clksel().write(|w| match config.clock_source {
358 ClockSel::BusClk => {
359 w.set_mfclk_sel(false);
360 w.set_busclk_sel(true);
361 }
362 ClockSel::MfClk => {
363 w.set_mfclk_sel(true);
364 w.set_busclk_sel(false);
365 }
366 });
367 self.info.regs.clkdiv().write(|w| w.set_ratio(config.clock_div.into()));
368
369 // set up glitch filter
370 self.info.regs.gfctl().modify(|w| {
371 w.set_agfen(false);
372 w.set_agfsel(vals::Agfsel::AGLIT_50);
373 w.set_chain(true);
374 });
375
376 // Reset controller transfer, follow TI example
377 self.info
378 .regs
379 .controller(0)
380 .cctr()
381 .write_value(i2c::regs::Cctr::default());
382
383 let clock = config.calculate_clock_rate();
384
385 self.state.clock.store(clock, Ordering::Relaxed);
386
387 self.info
388 .regs
389 .controller(0)
390 .ctpr()
391 .write(|w| w.set_tpr(config.timer_period(clock)));
392
393 // Set Tx Fifo threshold, follow TI example
394 self.info
395 .regs
396 .controller(0)
397 .cfifoctl()
398 .write(|w| w.set_txtrig(vals::CfifoctlTxtrig::EMPTY));
399 // Set Rx Fifo threshold, follow TI example
400 self.info
401 .regs
402 .controller(0)
403 .cfifoctl()
404 .write(|w| w.set_rxtrig(vals::CfifoctlRxtrig::LEVEL_1));
405 // Enable controller clock stretching, follow TI example
406
407 self.info.regs.controller(0).ccr().modify(|w| {
408 w.set_clkstretch(true);
409 w.set_active(true);
410 });
411
412 Ok(())
413 }
414
415 fn master_stop(&mut self) {
416 // not the first transaction, delay 1000 cycles
417 cortex_m::asm::delay(1000);
418
419 // Stop transaction
420 self.info.regs.controller(0).cctr().modify(|w| {
421 w.set_cblen(0);
422 w.set_stop(true);
423 w.set_start(false);
424 });
425 }
426
427 fn master_continue(&mut self, length: usize, send_ack_nack: bool, send_stop: bool) -> Result<(), Error> {
428 assert!(length <= FIFO_SIZE && length > 0);
429
430 // delay between ongoing transactions, 1000 cycles
431 cortex_m::asm::delay(1000);
432
433 // Update transaction to length amount of bytes
434 self.info.regs.controller(0).cctr().modify(|w| {
435 w.set_cblen(length as u16);
436 w.set_start(false);
437 w.set_ack(send_ack_nack);
438 if send_stop {
439 w.set_stop(true);
440 }
441 });
442
443 Ok(())
444 }
445
446 fn master_read(
447 &mut self,
448 address: u8,
449 length: usize,
450 restart: bool,
451 send_ack_nack: bool,
452 send_stop: bool,
453 ) -> Result<(), Error> {
454 if restart {
455 // not the first transaction, delay 1000 cycles
456 cortex_m::asm::delay(1000);
457 }
458
459 // Set START and prepare to receive bytes into
460 // `buffer`. The START bit can be set even if the bus
461 // is BUSY or I2C is in slave mode.
462 self.info.regs.controller(0).csa().modify(|w| {
463 w.set_taddr(address as u16);
464 w.set_cmode(vals::Mode::MODE7);
465 w.set_dir(vals::Dir::RECEIVE);
466 });
467
468 self.info.regs.controller(0).cctr().modify(|w| {
469 w.set_cblen(length as u16);
470 w.set_burstrun(true);
471 w.set_ack(send_ack_nack);
472 w.set_start(true);
473 if send_stop {
474 w.set_stop(true);
475 }
476 });
477
478 Ok(())
479 }
480
481 fn master_write(&mut self, address: u8, length: usize, send_stop: bool) -> Result<(), Error> {
482 assert!(length <= FIFO_SIZE && length > 0);
483
484 // Start transfer of length amount of bytes
485 self.info.regs.controller(0).csa().modify(|w| {
486 w.set_taddr(address as u16);
487 w.set_cmode(vals::Mode::MODE7);
488 w.set_dir(vals::Dir::TRANSMIT);
489 });
490 self.info.regs.controller(0).cctr().modify(|w| {
491 w.set_cblen(length as u16);
492 w.set_burstrun(true);
493 w.set_start(true);
494 if send_stop {
495 w.set_stop(true);
496 }
497 });
498
499 Ok(())
500 }
501
502 fn check_error(&self) -> Result<(), Error> {
503 let csr = self.info.regs.controller(0).csr().read();
504 if csr.err() {
505 return Err(Error::Nack);
506 } else if csr.arblst() {
507 return Err(Error::Arbitration);
508 }
509 Ok(())
510 }
511}
512
513impl<'d> I2c<'d, Blocking> {
514 fn master_blocking_continue(&mut self, length: usize, send_ack_nack: bool, send_stop: bool) -> Result<(), Error> {
515 // Perform transaction
516 self.master_continue(length, send_ack_nack, send_stop)?;
517
518 // Poll until the Controller process all bytes or NACK
519 while self.info.regs.controller(0).csr().read().busy() {}
520
521 Ok(())
522 }
523
524 fn master_blocking_read(
525 &mut self,
526 address: u8,
527 length: usize,
528 restart: bool,
529 send_ack_nack: bool,
530 send_stop: bool,
531 ) -> Result<(), Error> {
532 assert!(length <= FIFO_SIZE && length > 0);
533
534 // unless restart, Wait for the controller to be idle,
535 if !restart {
536 while !self.info.regs.controller(0).csr().read().idle() {}
537 }
538
539 self.master_read(address, length, restart, send_ack_nack, send_stop)?;
540
541 // Poll until the Controller process all bytes or NACK
542 while self.info.regs.controller(0).csr().read().busy() {}
543
544 Ok(())
545 }
546
547 fn master_blocking_write(&mut self, address: u8, length: usize, send_stop: bool) -> Result<(), Error> {
548 // Wait for the controller to be idle
549 while !self.info.regs.controller(0).csr().read().idle() {}
550
551 // Perform writing
552 self.master_write(address, length, send_stop)?;
553
554 // Poll until the Controller writes all bytes or NACK
555 while self.info.regs.controller(0).csr().read().busy() {}
556
557 Ok(())
558 }
559
560 fn read_blocking_internal(
561 &mut self,
562 address: u8,
563 read: &mut [u8],
564 restart: bool,
565 end_w_stop: bool,
566 ) -> Result<(), Error> {
567 let read_len = read.len();
568
569 let mut bytes_to_read = read_len;
570 for (number, chunk) in read.chunks_mut(FIFO_SIZE).enumerate() {
571 bytes_to_read -= chunk.len();
572 // if the current transaction is the last & end_w_stop, send stop
573 let send_stop = bytes_to_read == 0 && end_w_stop;
574 // if there are still bytes to read, send ACK
575 let send_ack_nack = bytes_to_read != 0;
576
577 if number == 0 {
578 self.master_blocking_read(address, chunk.len().min(FIFO_SIZE), restart, send_ack_nack, send_stop)?
579 } else {
580 self.master_blocking_continue(chunk.len(), send_ack_nack, send_stop)?;
581 }
582
583 // check errors
584 if let Err(err) = self.check_error() {
585 self.master_stop();
586 return Err(err);
587 }
588
589 for byte in chunk {
590 *byte = self.info.regs.controller(0).crxdata().read().value();
591 }
592 }
593 Ok(())
594 }
595
596 fn write_blocking_internal(&mut self, address: u8, write: &[u8], end_w_stop: bool) -> Result<(), Error> {
597 if write.is_empty() {
598 return Err(Error::ZeroLengthTransfer);
599 }
600
601 let mut bytes_to_send = write.len();
602 for (number, chunk) in write.chunks(FIFO_SIZE).enumerate() {
603 for byte in chunk {
604 let ctrl0 = self.info.regs.controller(0).ctxdata();
605 ctrl0.write(|w| w.set_value(*byte));
606 }
607
608 // if the current transaction is the last & end_w_stop, send stop
609 bytes_to_send -= chunk.len();
610 let send_stop = end_w_stop && bytes_to_send == 0;
611
612 if number == 0 {
613 self.master_blocking_write(address, chunk.len(), send_stop)?;
614 } else {
615 self.master_blocking_continue(chunk.len(), false, send_stop)?;
616 }
617
618 // check errors
619 if let Err(err) = self.check_error() {
620 self.master_stop();
621 return Err(err);
622 }
623 }
624 Ok(())
625 }
626
627 // =========================
628 // Blocking public API
629
630 /// Blocking read.
631 pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
632 // wait until bus is free
633 while self.info.regs.controller(0).csr().read().busbsy() {}
634 self.read_blocking_internal(address, read, false, true)
635 }
636
637 /// Blocking write.
638 pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
639 // wait until bus is free
640 while self.info.regs.controller(0).csr().read().busbsy() {}
641 self.write_blocking_internal(address, write, true)
642 }
643
644 /// Blocking write, restart, read.
645 pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
646 // wait until bus is free
647 while self.info.regs.controller(0).csr().read().busbsy() {}
648 let err = self.write_blocking_internal(address, write, false);
649 if err != Ok(()) {
650 return err;
651 }
652 self.read_blocking_internal(address, read, true, true)
653 }
654}
655
656impl<'d> I2c<'d, Async> {
657 async fn write_async_internal(&mut self, addr: u8, write: &[u8], end_w_stop: bool) -> Result<(), Error> {
658 let ctrl = self.info.regs.controller(0);
659
660 let mut bytes_to_send = write.len();
661 for (number, chunk) in write.chunks(FIFO_SIZE).enumerate() {
662 self.info.regs.cpu_int(0).imask().modify(|w| {
663 w.set_carblost(true);
664 w.set_cnack(true);
665 w.set_ctxdone(true);
666 });
667
668 for byte in chunk {
669 ctrl.ctxdata().write(|w| w.set_value(*byte));
670 }
671
672 // if the current transaction is the last & end_w_stop, send stop
673 bytes_to_send -= chunk.len();
674 let send_stop = end_w_stop && bytes_to_send == 0;
675
676 if number == 0 {
677 self.master_write(addr, chunk.len(), send_stop)?;
678 } else {
679 self.master_continue(chunk.len(), false, send_stop)?;
680 }
681
682 let res: Result<(), Error> = future::poll_fn(|cx| {
683 use crate::i2c::vals::CpuIntIidxStat;
684 // Register prior to checking the condition
685 self.state.waker.register(cx.waker());
686
687 let result = match self.info.regs.cpu_int(0).iidx().read().stat() {
688 CpuIntIidxStat::NO_INTR => Poll::Pending,
689 CpuIntIidxStat::CNACKFG => Poll::Ready(Err(Error::Nack)),
690 CpuIntIidxStat::CARBLOSTFG => Poll::Ready(Err(Error::Arbitration)),
691 CpuIntIidxStat::CTXDONEFG => Poll::Ready(Ok(())),
692 _ => Poll::Pending,
693 };
694
695 if !result.is_pending() {
696 self.info
697 .regs
698 .cpu_int(0)
699 .imask()
700 .write_value(i2c::regs::CpuInt::default());
701 }
702 return result;
703 })
704 .await;
705
706 if res.is_err() {
707 self.master_stop();
708 return res;
709 }
710 }
711 Ok(())
712 }
713
714 async fn read_async_internal(
715 &mut self,
716 addr: u8,
717 read: &mut [u8],
718 restart: bool,
719 end_w_stop: bool,
720 ) -> Result<(), Error> {
721 let read_len = read.len();
722
723 let mut bytes_to_read = read_len;
724 for (number, chunk) in read.chunks_mut(FIFO_SIZE).enumerate() {
725 bytes_to_read -= chunk.len();
726 // if the current transaction is the last & end_w_stop, send stop
727 let send_stop = bytes_to_read == 0 && end_w_stop;
728 // if there are still bytes to read, send ACK
729 let send_ack_nack = bytes_to_read != 0;
730
731 self.info.regs.cpu_int(0).imask().modify(|w| {
732 w.set_carblost(true);
733 w.set_cnack(true);
734 w.set_crxdone(true);
735 });
736
737 if number == 0 {
738 self.master_read(addr, chunk.len(), restart, send_ack_nack, send_stop)?
739 } else {
740 self.master_continue(chunk.len(), send_ack_nack, send_stop)?;
741 }
742
743 let res: Result<(), Error> = future::poll_fn(|cx| {
744 use crate::i2c::vals::CpuIntIidxStat;
745 // Register prior to checking the condition
746 self.state.waker.register(cx.waker());
747
748 let result = match self.info.regs.cpu_int(0).iidx().read().stat() {
749 CpuIntIidxStat::NO_INTR => Poll::Pending,
750 CpuIntIidxStat::CNACKFG => Poll::Ready(Err(Error::Nack)),
751 CpuIntIidxStat::CARBLOSTFG => Poll::Ready(Err(Error::Arbitration)),
752 CpuIntIidxStat::CRXDONEFG => Poll::Ready(Ok(())),
753 _ => Poll::Pending,
754 };
755
756 if !result.is_pending() {
757 self.info
758 .regs
759 .cpu_int(0)
760 .imask()
761 .write_value(i2c::regs::CpuInt::default());
762 }
763 return result;
764 })
765 .await;
766
767 if res.is_err() {
768 self.master_stop();
769 return res;
770 }
771
772 for byte in chunk {
773 *byte = self.info.regs.controller(0).crxdata().read().value();
774 }
775 }
776 Ok(())
777 }
778
779 // =========================
780 // Async public API
781
782 pub async fn async_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
783 // wait until bus is free
784 while self.info.regs.controller(0).csr().read().busbsy() {}
785 self.write_async_internal(address, write, true).await
786 }
787
788 pub async fn async_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
789 // wait until bus is free
790 while self.info.regs.controller(0).csr().read().busbsy() {}
791 self.read_async_internal(address, read, false, true).await
792 }
793
794 pub async fn async_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
795 // wait until bus is free
796 while self.info.regs.controller(0).csr().read().busbsy() {}
797
798 let err = self.write_async_internal(address, write, false).await;
799 if err != Ok(()) {
800 return err;
801 }
802 self.read_async_internal(address, read, true, true).await
803 }
804}
805
806impl<'d> embedded_hal_02::blocking::i2c::Read for I2c<'d, Blocking> {
807 type Error = Error;
808
809 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
810 self.blocking_read(address, buffer)
811 }
812}
813
814impl<'d> embedded_hal_02::blocking::i2c::Write for I2c<'d, Blocking> {
815 type Error = Error;
816
817 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
818 self.blocking_write(address, bytes)
819 }
820}
821
822impl<'d> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, Blocking> {
823 type Error = Error;
824
825 fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
826 self.blocking_write_read(address, bytes, buffer)
827 }
828}
829
830impl<'d> embedded_hal_02::blocking::i2c::Transactional for I2c<'d, Blocking> {
831 type Error = Error;
832
833 fn exec(
834 &mut self,
835 address: u8,
836 operations: &mut [embedded_hal_02::blocking::i2c::Operation<'_>],
837 ) -> Result<(), Self::Error> {
838 // wait until bus is free
839 while self.info.regs.controller(0).csr().read().busbsy() {}
840 for i in 0..operations.len() {
841 match &mut operations[i] {
842 embedded_hal_02::blocking::i2c::Operation::Read(buf) => {
843 self.read_blocking_internal(address, buf, false, false)?
844 }
845 embedded_hal_02::blocking::i2c::Operation::Write(buf) => {
846 self.write_blocking_internal(address, buf, false)?
847 }
848 }
849 }
850 self.master_stop();
851 Ok(())
852 }
853}
854
855impl embedded_hal::i2c::Error for Error {
856 fn kind(&self) -> embedded_hal::i2c::ErrorKind {
857 match *self {
858 Self::Bus => embedded_hal::i2c::ErrorKind::Bus,
859 Self::Arbitration => embedded_hal::i2c::ErrorKind::ArbitrationLoss,
860 Self::Nack => embedded_hal::i2c::ErrorKind::NoAcknowledge(embedded_hal::i2c::NoAcknowledgeSource::Unknown),
861 Self::Timeout => embedded_hal::i2c::ErrorKind::Other,
862 Self::Crc => embedded_hal::i2c::ErrorKind::Other,
863 Self::Overrun => embedded_hal::i2c::ErrorKind::Overrun,
864 Self::ZeroLengthTransfer => embedded_hal::i2c::ErrorKind::Other,
865 }
866 }
867}
868
869impl<'d, M: Mode> embedded_hal::i2c::ErrorType for I2c<'d, M> {
870 type Error = Error;
871}
872
873impl<'d> embedded_hal::i2c::I2c for I2c<'d, Blocking> {
874 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
875 self.blocking_read(address, read)
876 }
877
878 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
879 self.blocking_write(address, write)
880 }
881
882 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
883 self.blocking_write_read(address, write, read)
884 }
885
886 fn transaction(
887 &mut self,
888 address: u8,
889 operations: &mut [embedded_hal::i2c::Operation<'_>],
890 ) -> Result<(), Self::Error> {
891 // wait until bus is free
892 while self.info.regs.controller(0).csr().read().busbsy() {}
893 for i in 0..operations.len() {
894 match &mut operations[i] {
895 embedded_hal::i2c::Operation::Read(buf) => self.read_blocking_internal(address, buf, false, false)?,
896 embedded_hal::i2c::Operation::Write(buf) => self.write_blocking_internal(address, buf, false)?,
897 }
898 }
899 self.master_stop();
900 Ok(())
901 }
902}
903
904impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> {
905 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
906 self.async_read(address, read).await
907 }
908
909 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
910 self.async_write(address, write).await
911 }
912
913 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
914 self.async_write_read(address, write, read).await
915 }
916
917 async fn transaction(
918 &mut self,
919 address: u8,
920 operations: &mut [embedded_hal::i2c::Operation<'_>],
921 ) -> Result<(), Self::Error> {
922 // wait until bus is free
923 while self.info.regs.controller(0).csr().read().busbsy() {}
924 for i in 0..operations.len() {
925 match &mut operations[i] {
926 embedded_hal::i2c::Operation::Read(buf) => self.read_async_internal(address, buf, false, false).await?,
927 embedded_hal::i2c::Operation::Write(buf) => self.write_async_internal(address, buf, false).await?,
928 }
929 }
930 self.master_stop();
931 Ok(())
932 }
933}
934
935/// Interrupt handler.
936pub struct InterruptHandler<T: Instance> {
937 _i2c: PhantomData<T>,
938}
939
940impl<T: Instance> crate::interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
941 // Mask interrupts and wake any task waiting for this interrupt
942 unsafe fn on_interrupt() {
943 T::state().waker.wake();
944 }
945}
946
947/// Peripheral instance trait.
948#[allow(private_bounds)]
949pub trait Instance: SealedInstance + PeripheralType {
950 type Interrupt: crate::interrupt::typelevel::Interrupt;
951}
952
953/// I2C `SDA` pin trait
954pub trait SdaPin<T: Instance>: crate::gpio::Pin {
955 /// Get the PF number needed to use this pin as `SDA`.
956 fn pf_num(&self) -> u8;
957}
958
959/// I2C `SCL` pin trait
960pub trait SclPin<T: Instance>: crate::gpio::Pin {
961 /// Get the PF number needed to use this pin as `SCL`.
962 fn pf_num(&self) -> u8;
963}
964
965// ==== IMPL types ====
966
967pub(crate) struct Info {
968 pub(crate) regs: Regs,
969 pub(crate) interrupt: Interrupt,
970}
971
972pub(crate) struct State {
973 /// The clock rate of the I2C. This might be configured.
974 pub(crate) clock: AtomicU32,
975 pub(crate) waker: AtomicWaker,
976}
977
978impl<'d, M: Mode> I2c<'d, M> {
979 fn new_inner<T: Instance>(
980 _peri: Peri<'d, T>,
981 scl: Peri<'d, impl SclPin<T>>,
982 sda: Peri<'d, impl SdaPin<T>>,
983 config: Config,
984 ) -> Result<Self, ConfigError> {
985 // Init power for I2C
986 T::info().regs.gprcm(0).rstctl().write(|w| {
987 w.set_resetstkyclr(true);
988 w.set_resetassert(true);
989 w.set_key(vals::ResetKey::KEY);
990 });
991
992 T::info().regs.gprcm(0).pwren().write(|w| {
993 w.set_enable(true);
994 w.set_key(vals::PwrenKey::KEY);
995 });
996
997 // init delay, 16 cycles
998 cortex_m::asm::delay(16);
999
1000 // Init GPIO
1001 let scl_inner = new_pin!(scl, config.scl_pf());
1002 let sda_inner = new_pin!(sda, config.sda_pf());
1003
1004 if let Some(ref scl) = scl_inner {
1005 let pincm = pac::IOMUX.pincm(scl._pin_cm() as usize);
1006 pincm.modify(|w| {
1007 w.set_hiz1(true);
1008 });
1009 }
1010
1011 if let Some(ref sda) = sda_inner {
1012 let pincm = pac::IOMUX.pincm(sda._pin_cm() as usize);
1013 pincm.modify(|w| {
1014 w.set_hiz1(true);
1015 });
1016 }
1017
1018 let mut this = Self {
1019 info: T::info(),
1020 state: T::state(),
1021 scl: scl_inner,
1022 sda: sda_inner,
1023 _phantom: PhantomData,
1024 };
1025 this.init(&config)?;
1026
1027 Ok(this)
1028 }
1029}
1030
1031pub(crate) trait SealedInstance {
1032 fn info() -> &'static Info;
1033 fn state() -> &'static State;
1034}
1035
1036macro_rules! impl_i2c_instance {
1037 ($instance: ident) => {
1038 impl crate::i2c::SealedInstance for crate::peripherals::$instance {
1039 fn info() -> &'static crate::i2c::Info {
1040 use crate::i2c::Info;
1041 use crate::interrupt::typelevel::Interrupt;
1042
1043 const INFO: Info = Info {
1044 regs: crate::pac::$instance,
1045 interrupt: crate::interrupt::typelevel::$instance::IRQ,
1046 };
1047 &INFO
1048 }
1049
1050 fn state() -> &'static crate::i2c::State {
1051 use crate::i2c::State;
1052 use crate::interrupt::typelevel::Interrupt;
1053
1054 static STATE: State = State {
1055 clock: core::sync::atomic::AtomicU32::new(0),
1056 waker: embassy_sync::waitqueue::AtomicWaker::new(),
1057 };
1058 &STATE
1059 }
1060 }
1061
1062 impl crate::i2c::Instance for crate::peripherals::$instance {
1063 type Interrupt = crate::interrupt::typelevel::$instance;
1064 }
1065 };
1066}
1067
1068macro_rules! impl_i2c_sda_pin {
1069 ($instance: ident, $pin: ident, $pf: expr) => {
1070 impl crate::i2c::SdaPin<crate::peripherals::$instance> for crate::peripherals::$pin {
1071 fn pf_num(&self) -> u8 {
1072 $pf
1073 }
1074 }
1075 };
1076}
1077
1078macro_rules! impl_i2c_scl_pin {
1079 ($instance: ident, $pin: ident, $pf: expr) => {
1080 impl crate::i2c::SclPin<crate::peripherals::$instance> for crate::peripherals::$pin {
1081 fn pf_num(&self) -> u8 {
1082 $pf
1083 }
1084 }
1085 };
1086}
1087
1088#[cfg(test)]
1089mod tests {
1090 use crate::i2c::{BusSpeed, ClockDiv, ClockSel, Config};
1091
1092 /// These tests are based on TI's reference caluclation.
1093 #[test]
1094 fn ti_timer_period() {
1095 let mut config = Config::default();
1096 config.clock_div = ClockDiv::DivBy1;
1097 config.bus_speed = BusSpeed::FastMode;
1098 assert!(matches!(config.timer_period(32_000_000), 7));
1099 }
1100
1101 #[test]
1102 fn ti_timer_period_2() {
1103 let mut config = Config::default();
1104 config.clock_div = ClockDiv::DivBy2;
1105 config.bus_speed = BusSpeed::FastMode;
1106 assert!(matches!(config.timer_period(32_000_000), 3));
1107 }
1108
1109 #[test]
1110 fn ti_timer_period_3() {
1111 let mut config = Config::default();
1112 config.clock_div = ClockDiv::DivBy2;
1113 config.bus_speed = BusSpeed::Standard;
1114 assert!(matches!(config.timer_period(32_000_000), 15));
1115 }
1116
1117 #[test]
1118 fn ti_timer_period_4() {
1119 let mut config = Config::default();
1120 config.clock_div = ClockDiv::DivBy2;
1121 config.bus_speed = BusSpeed::Custom(100_000);
1122 assert!(matches!(config.timer_period(32_000_000), 15));
1123 }
1124
1125 #[test]
1126 fn clock_check_fastmodeplus_rate_with_busclk() {
1127 let mut config = Config::default();
1128 config.clock_source = ClockSel::BusClk;
1129 config.bus_speed = BusSpeed::FastModePlus;
1130 assert!(config.check_clock_rate());
1131 }
1132
1133 #[test]
1134 fn clock_check_fastmode_rate_with_busclk() {
1135 let mut config = Config::default();
1136 config.clock_source = ClockSel::BusClk;
1137 config.bus_speed = BusSpeed::FastMode;
1138 assert!(config.check_clock_rate());
1139 }
1140
1141 #[test]
1142 fn clock_check_fastmodeplus_rate_with_mfclk() {
1143 let mut config = Config::default();
1144 config.clock_source = ClockSel::MfClk;
1145 config.bus_speed = BusSpeed::FastModePlus;
1146 assert!(!config.check_clock_rate());
1147 }
1148
1149 #[test]
1150 fn clock_check_fastmode_rate_with_mfclk() {
1151 let mut config = Config::default();
1152 config.clock_source = ClockSel::MfClk;
1153 config.bus_speed = BusSpeed::FastMode;
1154 assert!(!config.check_clock_rate());
1155 }
1156}
diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs
index bb8d91403..403f9d50c 100644
--- a/embassy-mspm0/src/lib.rs
+++ b/embassy-mspm0/src/lib.rs
@@ -15,6 +15,7 @@ mod macros;
15 15
16pub mod dma; 16pub mod dma;
17pub mod gpio; 17pub mod gpio;
18pub mod i2c;
18pub mod timer; 19pub mod timer;
19pub mod uart; 20pub mod uart;
20 21
@@ -179,6 +180,10 @@ pub fn init(config: Config) -> Peripherals {
179 w.set_mfpclken(true); 180 w.set_mfpclken(true);
180 }); 181 });
181 182
183 pac::SYSCTL.sysosccfg().modify(|w| {
184 w.set_freq(pac::sysctl::vals::SysosccfgFreq::SYSOSCBASE);
185 });
186
182 pac::SYSCTL.borthreshold().modify(|w| { 187 pac::SYSCTL.borthreshold().modify(|w| {
183 w.set_level(0); 188 w.set_level(0);
184 }); 189 });