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