1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#![cfg_attr(
feature = "min-samd51g",
doc = "
# Undocumented features
The ATSAMx5x chips contain certain features that aren't documented in the datasheet.
These features are implemented in the HAL based on experimentation with certain boards
which have verifiably demonstrated that those features work as intended.
* [`UndocIoSet1`](pad::UndocIoSet1): Implement an undocumented `IoSet` for PA16, PA17,
PB22 & PB23 configured for [`Sercom1`]. The pygamer & feather_m4 use this combination,
but it is not listed as valid in the datasheet.
* [`UndocIoSet2`](pad::UndocIoSet2): Implement an undocumented `IoSet` for PA00, PA01,
PB22 & PB23 configured for [`Sercom1`]. The itsybitsy_m4 uses this combination, but it is
not listed as valid in the datasheet.
* [`PB02`] is I2C-capable according to metro_m4. As such, [`PB02`]
implements [`IsI2cPad`].
* [`PB03`] is I2C-capable according to metro_m4. As such, [`PB03`]
implements [`IsI2cPad`](pad::IsI2cPad).
[`PB02`]: crate::gpio::pin::PB02
[`PB03`]: crate::gpio::pin::PB03
[`IsI2cPad`]: pad::IsI2cPad
"
)]
use core::ops::Deref;
use paste::paste;
use seq_macro::seq;
use crate::pac;
#[cfg(feature = "min-samd51g")]
use pac::MCLK as APB_CLK_CTRL;
#[cfg(any(feature = "samd11", feature = "samd21"))]
use pac::PM as APB_CLK_CTRL;
use pac::{sercom0, SERCOM0, SERCOM1};
#[cfg(any(feature = "samd21", feature = "min-samd51g"))]
use pac::{SERCOM2, SERCOM3};
#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))]
use pac::{SERCOM4, SERCOM5};
#[cfg(feature = "min-samd51n")]
use pac::{SERCOM6, SERCOM7};
#[cfg(feature = "dma")]
use crate::dmac::TriggerSource;
use crate::typelevel::Sealed;
pub mod pad;
pub use pad::*;
pub mod i2c;
pub mod spi;
pub mod spi_future;
pub mod uart;
#[cfg(feature = "dma")]
pub mod dma;
pub trait Sercom: Sealed + Deref<Target = sercom0::RegisterBlock> {
const NUM: usize;
#[cfg(feature = "dma")]
const DMA_RX_TRIGGER: TriggerSource;
#[cfg(feature = "dma")]
const DMA_TX_TRIGGER: TriggerSource;
fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL);
}
macro_rules! sercom {
( $apbmask:ident: ($start:literal, $end:literal) ) => {
seq!(N in $start..=$end {
paste! {
pub type Sercom~N = SERCOM~N;
impl Sealed for Sercom~N {}
impl Sercom for Sercom~N {
const NUM: usize = N;
#[cfg(feature = "dma")]
const DMA_RX_TRIGGER: TriggerSource = TriggerSource::[<SERCOM~N _RX>];
#[cfg(feature = "dma")]
const DMA_TX_TRIGGER: TriggerSource = TriggerSource::[<SERCOM~N _TX>];
#[inline]
fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL) {
ctrl.$apbmask.modify(|_, w| w.[<sercom~N _>]().set_bit());
}
}
}
});
};
}
#[cfg(any(feature = "samd11", feature = "samd21"))]
sercom!(apbcmask: (0, 1));
#[cfg(feature = "samd21")]
sercom!(apbcmask: (2, 3));
#[cfg(feature = "min-samd21g")]
sercom!(apbcmask: (4, 5));
#[cfg(feature = "min-samd51g")]
sercom!(apbamask: (0, 1));
#[cfg(feature = "min-samd51g")]
sercom!(apbbmask: (2, 3));
#[cfg(feature = "min-samd51g")]
sercom!(apbdmask: (4, 5));
#[cfg(feature = "min-samd51n")]
sercom!(apbdmask: (6, 7));