1use core::ops::Deref;
2
3use crate::{
4 raw,
5 typestates::{
6 init_state,
7 ClocksSupportFlexcommToken,
8 pin::{
9 flexcomm::{
10 I2c,
11 I2s,
12 Spi,
13 Usart,
14 },
15 },
16 },
17 peripherals::syscon,
18};
19
20
21pub type Flexcomm = (
22 Flexcomm0,
23 Flexcomm1,
24 Flexcomm2,
25 Flexcomm3,
26 Flexcomm4,
27 Flexcomm5,
28 Flexcomm6,
29 Flexcomm7,
30 Flexcomm8,
31);
32
33macro_rules! flexcomm {
34 ($fc_hal:ident, $i2c_hal:ident, $i2s_hal:ident, $spi_hal:ident, $usart_hal:ident,
35 $fc_pac:ident, $i2c_pac:ident, $i2s_pac:ident, $spi_pac:ident, $usart_pac:ident,
36 $register_sel:ident
37 ) => {
38 pub struct $fc_hal<State = init_state::Unknown> {
39 pub(crate) raw_fc: raw::$fc_pac,
40 pub(crate) raw_i2c: raw::$i2c_pac,
41 pub(crate) raw_i2s: raw::$i2s_pac,
42 pub(crate) raw_spi: raw::$spi_pac,
43 pub(crate) raw_usart: raw::$usart_pac,
44 pub _state: State,
45 }
46
47 pub struct $i2c_hal<State = init_state::Enabled> {
48 pub(crate) _raw_fc: raw::$fc_pac,
49 #[allow(dead_code)]
50 pub(crate) raw: raw::$i2c_pac,
51 pub(crate) _raw_i2s: raw::$i2s_pac,
52 pub(crate) _raw_spi: raw::$spi_pac,
53 pub(crate) _raw_usart: raw::$usart_pac,
54 pub _state: State,
55 }
56
57 impl Deref for $i2c_hal {
58 type Target = raw::i2c0::RegisterBlock;
59 fn deref(&self) -> &Self::Target {
60 &self.raw
61 }
62 }
63
64 impl I2c for $i2c_hal {}
65
66 pub struct $i2s_hal<State = init_state::Enabled> {
67 pub(crate) _raw_fc: raw::$fc_pac,
68 pub(crate) _raw_i2c: raw::$i2c_pac,
69 #[allow(dead_code)]
70 pub(crate) raw: raw::$i2s_pac,
71 pub(crate) _raw_spi: raw::$spi_pac,
72 pub(crate) _raw_usart: raw::$usart_pac,
73 pub _state: State,
74 }
75
76 impl I2s for $i2s_hal {}
77
78 pub struct $spi_hal<State = init_state::Enabled> {
79 pub(crate) _raw_fc: raw::$fc_pac,
80 pub(crate) _raw_i2c: raw::$i2c_pac,
81 pub(crate) _raw_i2s: raw::$i2s_pac,
82 #[allow(dead_code)]
83 pub(crate) raw: raw::$spi_pac,
84 pub(crate) _raw_usart: raw::$usart_pac,
85 pub _state: State,
86 }
87
88 impl Deref for $spi_hal {
89 type Target = raw::spi0::RegisterBlock;
90 fn deref(&self) -> &Self::Target {
91 &self.raw
92 }
93 }
94
95 impl Spi for $spi_hal {}
96
97 pub struct $usart_hal<State = init_state::Enabled> {
98 pub(crate) _raw_fc: raw::$fc_pac,
99 pub(crate) _raw_i2c: raw::$i2c_pac,
100 pub(crate) _raw_i2s: raw::$i2s_pac,
101 pub(crate) _raw_spi: raw::$spi_pac,
102 #[allow(dead_code)]
103 pub(crate) raw: raw::$usart_pac,
104 pub _state: State,
105 }
106
107 impl Deref for $usart_hal {
108 type Target = raw::usart0::RegisterBlock;
109 fn deref(&self) -> &Self::Target {
110 &self.raw
111 }
112 }
113
114 impl Usart for $usart_hal {}
115
116 impl core::convert::From<(raw::$fc_pac, raw::$i2c_pac, raw::$i2s_pac, raw::$spi_pac, raw::$usart_pac)> for $fc_hal {
117 fn from(raw: (raw::$fc_pac, raw::$i2c_pac, raw::$i2s_pac, raw::$spi_pac, raw::$usart_pac)) -> Self {
118 $fc_hal::new(raw)
119 }
120 }
121
122 impl $fc_hal {
123 fn new(raw: (raw::$fc_pac, raw::$i2c_pac, raw::$i2s_pac, raw::$spi_pac, raw::$usart_pac)) -> Self {
124 $fc_hal {
125 raw_fc: raw.0,
126 raw_i2c: raw.1,
127 raw_i2s: raw.2,
128 raw_spi: raw.3,
129 raw_usart: raw.4,
130 _state: init_state::Unknown,
131 }
132 }
133
134 }
139
140 impl<State> $fc_hal<State> {
141 pub fn release(self) -> (raw::$fc_pac, raw::$i2c_pac, raw::$i2s_pac, raw::$spi_pac, raw::$usart_pac) {
142 (self.raw_fc, self.raw_i2c, self.raw_i2s, self.raw_spi, self.raw_usart)
143 }
144 }
145
146 impl $fc_hal {
147 fn enabled(&mut self, syscon: &mut syscon::Syscon) {
148 syscon.reset(&mut self.raw_fc);
149 syscon.enable_clock(&mut self.raw_fc);
150 }
151
152 pub fn enabled_as_i2c(
153 mut self,
154 syscon: &mut syscon::Syscon,
155 _clocks_token: &ClocksSupportFlexcommToken,
156 ) -> $i2c_hal<init_state::Enabled> {
157
158 syscon.raw.$register_sel().modify(|_, w| w.sel().enum_0x2()); self.enabled(syscon);
166
167 self.raw_fc.pselid.modify(|_, w| w
168 .persel().i2c()
170 .lock().locked()
172 );
173 assert!(self.raw_fc.pselid.read().i2cpresent().is_present());
174
175 $i2c_hal {
176 _raw_fc: self.raw_fc,
177 raw: self.raw_i2c,
178 _raw_i2s: self.raw_i2s,
179 _raw_spi: self.raw_spi,
180 _raw_usart: self.raw_usart,
181 _state: init_state::Enabled(()),
182 }
183 }
184
185 pub fn enabled_as_spi(
186 mut self,
187 syscon: &mut syscon::Syscon,
188 _clocks_token: &ClocksSupportFlexcommToken,
189 ) -> $spi_hal<init_state::Enabled> {
190
191 syscon.raw.$register_sel().modify(|_, w| w.sel().enum_0x2()); self.enabled(syscon);
199
200 self.raw_fc.pselid.modify(|_, w| w
201 .persel().spi()
203 .lock().locked()
205 );
206 assert!(self.raw_fc.pselid.read().spipresent().is_present());
207
208 $spi_hal {
209 _raw_fc: self.raw_fc,
210 _raw_i2c: self.raw_i2c,
211 _raw_i2s: self.raw_i2s,
212 raw: self.raw_spi,
213 _raw_usart: self.raw_usart,
214 _state: init_state::Enabled(()),
215 }
216 }
217
218 pub fn enabled_as_usart(
219 mut self,
220 syscon: &mut syscon::Syscon,
221 _clocks_token: &ClocksSupportFlexcommToken,
222 ) -> $usart_hal<init_state::Enabled> {
223
224 syscon.raw.$register_sel().modify(|_, w| w.sel().enum_0x2()); self.enabled(syscon);
232
233 self.raw_fc.pselid.modify(|_, w| w
234 .persel().usart()
236 .lock().locked()
238 );
239 assert!(self.raw_fc.pselid.read().usartpresent().is_present());
240
241 $usart_hal {
242 _raw_fc: self.raw_fc,
243 _raw_i2c: self.raw_i2c,
244 _raw_i2s: self.raw_i2s,
245 _raw_spi: self.raw_spi,
246 raw: self.raw_usart,
247 _state: init_state::Enabled(()),
248 }
249 }
250 }
251 }
252}
253
254flexcomm!(Flexcomm0, I2c0, I2s0, Spi0, Usart0, FLEXCOMM0, I2C0, I2S0, SPI0, USART0, fcclksel0);
255flexcomm!(Flexcomm1, I2c1, I2s1, Spi1, Usart1, FLEXCOMM1, I2C1, I2S1, SPI1, USART1, fcclksel1);
256flexcomm!(Flexcomm2, I2c2, I2s2, Spi2, Usart2, FLEXCOMM2, I2C2, I2S2, SPI2, USART2, fcclksel2);
257flexcomm!(Flexcomm3, I2c3, I2s3, Spi3, Usart3, FLEXCOMM3, I2C3, I2S3, SPI3, USART3, fcclksel3);
258flexcomm!(Flexcomm4, I2c4, I2s4, Spi4, Usart4, FLEXCOMM4, I2C4, I2S4, SPI4, USART4, fcclksel4);
259flexcomm!(Flexcomm5, I2c5, I2s5, Spi5, Usart5, FLEXCOMM5, I2C5, I2S5, SPI5, USART5, fcclksel5);
260flexcomm!(Flexcomm6, I2c6, I2s6, Spi6, Usart6, FLEXCOMM6, I2C6, I2S6, SPI6, USART6, fcclksel6);
261flexcomm!(Flexcomm7, I2c7, I2s7, Spi7, Usart7, FLEXCOMM7, I2C7, I2S7, SPI7, USART7, fcclksel7);
262
263pub struct Flexcomm8<State = init_state::Unknown> {
264 pub(crate) raw_fc: raw::FLEXCOMM8,
265 pub(crate) raw_spi: raw::SPI8,
266 pub _state: State,
267}
268
269pub struct Spi8<State = init_state::Enabled> {
270 pub(crate) _raw_fc: raw::FLEXCOMM8,
271 #[allow(dead_code)]
272 pub(crate) raw: raw::SPI8,
273 pub _state: State,
274}
275
276impl Deref for Spi8 {
277 type Target = raw::spi0::RegisterBlock;
278 fn deref(&self) -> &Self::Target {
279 &self.raw
280 }
281}
282
283impl Spi for Spi8 {}
284
285impl core::convert::From<(raw::FLEXCOMM8, raw::SPI8)> for Flexcomm8 {
286 fn from(raw: (raw::FLEXCOMM8, raw::SPI8)) -> Self {
287 Flexcomm8::new(raw)
288 }
289}
290
291impl Flexcomm8 {
292 fn new(raw: (raw::FLEXCOMM8, raw::SPI8)) -> Self {
293 Flexcomm8 {
294 raw_fc: raw.0,
295 raw_spi: raw.1,
296 _state: init_state::Unknown,
297 }
298 }
299}
300
301impl<State> Flexcomm8<State> {
302 pub fn release(self) -> (raw::FLEXCOMM8, raw::SPI8) {
303 (self.raw_fc, self.raw_spi)
304 }
305}
306
307impl Flexcomm8 {
308 fn enabled(&mut self, syscon: &mut syscon::Syscon) {
309 syscon.reset(&mut self.raw_fc);
310 syscon.enable_clock(&mut self.raw_fc);
311 }
312
313 pub fn enabled_as_spi(
314 mut self,
315 syscon: &mut syscon::Syscon,
316 _clocks_token: &ClocksSupportFlexcommToken,
317 ) -> Spi8<init_state::Enabled> {
318
319 syscon.raw.hslspiclksel.modify(|_, w| w.sel().enum_0x2()); self.enabled(syscon);
329
330 self.raw_fc.pselid.modify(|_, w| w
331 .persel().spi()
333 .lock().locked()
335 );
336 assert!(self.raw_fc.pselid.read().spipresent().is_present());
337
338 Spi8 {
339 _raw_fc: self.raw_fc,
340 raw: self.raw_spi,
341 _state: init_state::Enabled(()),
342 }
343 }
344
345}