aboutsummaryrefslogtreecommitdiff
path: root/embassy-nxp/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nxp/src')
-rw-r--r--embassy-nxp/src/chips/lpc55.rs115
-rw-r--r--embassy-nxp/src/chips/mimxrt1011.rs104
-rw-r--r--embassy-nxp/src/chips/mimxrt1062.rs273
-rw-r--r--embassy-nxp/src/dma.rs1
-rw-r--r--embassy-nxp/src/dma/lpc55.rs51
-rw-r--r--embassy-nxp/src/fmt.rs1
-rw-r--r--embassy-nxp/src/gpio/lpc55.rs157
-rw-r--r--embassy-nxp/src/gpio/rt1xxx.rs54
-rw-r--r--embassy-nxp/src/iomuxc.rs29
-rw-r--r--embassy-nxp/src/lib.rs26
-rw-r--r--embassy-nxp/src/pint.rs4
-rw-r--r--embassy-nxp/src/pwm.rs7
-rw-r--r--embassy-nxp/src/pwm/lpc55.rs248
-rw-r--r--embassy-nxp/src/sct.rs56
-rw-r--r--embassy-nxp/src/time_driver/rtc.rs4
-rw-r--r--embassy-nxp/src/usart.rs2
-rw-r--r--embassy-nxp/src/usart/lpc55.rs226
17 files changed, 560 insertions, 798 deletions
diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs
index 9f4e7269f..7967e07d1 100644
--- a/embassy-nxp/src/chips/lpc55.rs
+++ b/embassy-nxp/src/chips/lpc55.rs
@@ -1,109 +1,10 @@
1pub use nxp_pac as pac; 1pub(crate) mod _generated {
2 #![allow(dead_code)]
3 #![allow(unused_imports)]
4 #![allow(non_snake_case)]
5 #![allow(missing_docs)]
2 6
3embassy_hal_internal::interrupt_mod!( 7 include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
4 FLEXCOMM0, FLEXCOMM1, FLEXCOMM2, FLEXCOMM3, FLEXCOMM4, FLEXCOMM5, FLEXCOMM6, FLEXCOMM7
5);
6
7embassy_hal_internal::peripherals! {
8 // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other
9 // peripheral types (e.g. I2C).
10 PIO0_0,
11 PIO0_1,
12 PIO0_2,
13 PIO0_3,
14 PIO0_4,
15 PIO0_5,
16 PIO0_6,
17 PIO0_7,
18 PIO0_8,
19 PIO0_9,
20 PIO0_10,
21 PIO0_11,
22 PIO0_12,
23 PIO0_13,
24 PIO0_14,
25 PIO0_15,
26 PIO0_16,
27 PIO0_17,
28 PIO0_18,
29 PIO0_19,
30 PIO0_20,
31 PIO0_21,
32 PIO0_22,
33 PIO0_23,
34 PIO0_24,
35 PIO0_25,
36 PIO0_26,
37 PIO0_27,
38 PIO0_28,
39 PIO0_29,
40 PIO0_30,
41 PIO0_31,
42 PIO1_0,
43 PIO1_1,
44 PIO1_2,
45 PIO1_3,
46 PIO1_4,
47 PIO1_5,
48 PIO1_6,
49 PIO1_7,
50 PIO1_8,
51 PIO1_9,
52 PIO1_10,
53 PIO1_11,
54 PIO1_12,
55 PIO1_13,
56 PIO1_14,
57 PIO1_15,
58 PIO1_16,
59 PIO1_17,
60 PIO1_18,
61 PIO1_19,
62 PIO1_20,
63 PIO1_21,
64 PIO1_22,
65 PIO1_23,
66 PIO1_24,
67 PIO1_25,
68 PIO1_26,
69 PIO1_27,
70 PIO1_28,
71 PIO1_29,
72 PIO1_30,
73 PIO1_31,
74
75 // Direct Memory Access (DMA) channels. They are used for asynchronous modes of peripherals.
76 DMA_CH0,
77 DMA_CH1,
78 DMA_CH2,
79 DMA_CH3,
80 DMA_CH4,
81 DMA_CH5,
82 DMA_CH6,
83 DMA_CH7,
84 DMA_CH8,
85 DMA_CH9,
86 DMA_CH10,
87 DMA_CH11,
88 DMA_CH12,
89 DMA_CH13,
90 DMA_CH14,
91 DMA_CH15,
92 DMA_CH16,
93 DMA_CH17,
94 DMA_CH18,
95 DMA_CH19,
96 DMA_CH20,
97 DMA_CH21,
98 DMA_CH22,
99
100 // Universal Synchronous/Asynchronous Receiver/Transmitter (USART) instances.
101 USART0,
102 USART1,
103 USART2,
104 USART3,
105 USART4,
106 USART5,
107 USART6,
108 USART7
109} 8}
9
10pub use _generated::*;
diff --git a/embassy-nxp/src/chips/mimxrt1011.rs b/embassy-nxp/src/chips/mimxrt1011.rs
index a74d953fc..d5969a24b 100644
--- a/embassy-nxp/src/chips/mimxrt1011.rs
+++ b/embassy-nxp/src/chips/mimxrt1011.rs
@@ -1,107 +1,5 @@
1// This must be imported so that __preinit is defined. 1// This must be imported so that __preinit is defined.
2use imxrt_rt as _; 2use imxrt_rt as _;
3pub use nxp_pac as pac;
4
5embassy_hal_internal::peripherals! {
6 // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other
7 // peripheral types (e.g. I2C).
8 GPIO_00,
9 GPIO_01,
10 GPIO_02,
11 GPIO_03,
12 GPIO_04,
13 GPIO_05,
14 GPIO_06,
15 GPIO_07,
16 GPIO_08,
17 GPIO_09,
18 GPIO_10,
19 GPIO_11,
20 GPIO_12,
21 GPIO_13,
22 GPIO_AD_00,
23 GPIO_AD_01,
24 GPIO_AD_02,
25 GPIO_AD_03,
26 GPIO_AD_04,
27 GPIO_AD_05,
28 GPIO_AD_06,
29 GPIO_AD_07,
30 GPIO_AD_08,
31 GPIO_AD_09,
32 GPIO_AD_10,
33 GPIO_AD_11,
34 GPIO_AD_12,
35 GPIO_AD_13,
36 GPIO_AD_14,
37 GPIO_SD_00,
38 GPIO_SD_01,
39 GPIO_SD_02,
40 GPIO_SD_03,
41 GPIO_SD_04,
42 GPIO_SD_05,
43 GPIO_SD_06,
44 GPIO_SD_07,
45 GPIO_SD_08,
46 GPIO_SD_09,
47 GPIO_SD_10,
48 GPIO_SD_11,
49 GPIO_SD_12,
50 GPIO_SD_13,
51 PMIC_ON_REQ,
52}
53
54impl_gpio! {
55 // GPIO Bank 1
56 GPIO_00(Gpio1, 0);
57 GPIO_01(Gpio1, 1);
58 GPIO_02(Gpio1, 2);
59 GPIO_03(Gpio1, 3);
60 GPIO_04(Gpio1, 4);
61 GPIO_05(Gpio1, 5);
62 GPIO_06(Gpio1, 6);
63 GPIO_07(Gpio1, 7);
64 GPIO_08(Gpio1, 8);
65 GPIO_09(Gpio1, 9);
66 GPIO_10(Gpio1, 10);
67 GPIO_11(Gpio1, 11);
68 GPIO_12(Gpio1, 12);
69 GPIO_13(Gpio1, 13);
70 GPIO_AD_00(Gpio1, 14);
71 GPIO_AD_01(Gpio1, 15);
72 GPIO_AD_02(Gpio1, 16);
73 GPIO_AD_03(Gpio1, 17);
74 GPIO_AD_04(Gpio1, 18);
75 GPIO_AD_05(Gpio1, 19);
76 GPIO_AD_06(Gpio1, 20);
77 GPIO_AD_07(Gpio1, 21);
78 GPIO_AD_08(Gpio1, 22);
79 GPIO_AD_09(Gpio1, 23);
80 GPIO_AD_10(Gpio1, 24);
81 GPIO_AD_11(Gpio1, 25);
82 GPIO_AD_12(Gpio1, 26);
83 GPIO_AD_13(Gpio1, 27);
84 GPIO_AD_14(Gpio1, 28);
85
86 // GPIO Bank 2
87 GPIO_SD_00(Gpio2, 0);
88 GPIO_SD_01(Gpio2, 1);
89 GPIO_SD_02(Gpio2, 2);
90 GPIO_SD_03(Gpio2, 3);
91 GPIO_SD_04(Gpio2, 4);
92 GPIO_SD_05(Gpio2, 5);
93 GPIO_SD_06(Gpio2, 6);
94 GPIO_SD_07(Gpio2, 7);
95 GPIO_SD_08(Gpio2, 8);
96 GPIO_SD_09(Gpio2, 9);
97 GPIO_SD_10(Gpio2, 10);
98 GPIO_SD_11(Gpio2, 11);
99 GPIO_SD_12(Gpio2, 12);
100 GPIO_SD_13(Gpio2, 13);
101
102 // GPIO Bank 5
103 PMIC_ON_REQ(Gpio5, 0);
104}
105 3
106pub(crate) mod _generated { 4pub(crate) mod _generated {
107 #![allow(dead_code)] 5 #![allow(dead_code)]
@@ -111,3 +9,5 @@ pub(crate) mod _generated {
111 9
112 include!(concat!(env!("OUT_DIR"), "/_generated.rs")); 10 include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
113} 11}
12
13pub use _generated::*;
diff --git a/embassy-nxp/src/chips/mimxrt1062.rs b/embassy-nxp/src/chips/mimxrt1062.rs
index ef153bd66..d5969a24b 100644
--- a/embassy-nxp/src/chips/mimxrt1062.rs
+++ b/embassy-nxp/src/chips/mimxrt1062.rs
@@ -1,276 +1,5 @@
1// This must be imported so that __preinit is defined. 1// This must be imported so that __preinit is defined.
2use imxrt_rt as _; 2use imxrt_rt as _;
3pub use nxp_pac as pac;
4
5embassy_hal_internal::peripherals! {
6 // External pins. These are not only GPIOs, they are multi-purpose pins and can be used by other
7 // peripheral types (e.g. I2C).
8 GPIO_AD_B0_00,
9 GPIO_AD_B0_01,
10 GPIO_AD_B0_02,
11 GPIO_AD_B0_03,
12 GPIO_AD_B0_04,
13 GPIO_AD_B0_05,
14 GPIO_AD_B0_06,
15 GPIO_AD_B0_07,
16 GPIO_AD_B0_08,
17 GPIO_AD_B0_09,
18 GPIO_AD_B0_10,
19 GPIO_AD_B0_11,
20 GPIO_AD_B0_12,
21 GPIO_AD_B0_13,
22 GPIO_AD_B0_14,
23 GPIO_AD_B0_15,
24 GPIO_AD_B1_00,
25 GPIO_AD_B1_01,
26 GPIO_AD_B1_02,
27 GPIO_AD_B1_03,
28 GPIO_AD_B1_04,
29 GPIO_AD_B1_05,
30 GPIO_AD_B1_06,
31 GPIO_AD_B1_07,
32 GPIO_AD_B1_08,
33 GPIO_AD_B1_09,
34 GPIO_AD_B1_10,
35 GPIO_AD_B1_11,
36 GPIO_AD_B1_12,
37 GPIO_AD_B1_13,
38 GPIO_AD_B1_14,
39 GPIO_AD_B1_15,
40 GPIO_B0_00,
41 GPIO_B0_01,
42 GPIO_B0_02,
43 GPIO_B0_03,
44 GPIO_B0_04,
45 GPIO_B0_05,
46 GPIO_B0_06,
47 GPIO_B0_07,
48 GPIO_B0_08,
49 GPIO_B0_09,
50 GPIO_B0_10,
51 GPIO_B0_11,
52 GPIO_B0_12,
53 GPIO_B0_13,
54 GPIO_B0_14,
55 GPIO_B0_15,
56 GPIO_B1_00,
57 GPIO_B1_01,
58 GPIO_B1_02,
59 GPIO_B1_03,
60 GPIO_B1_04,
61 GPIO_B1_05,
62 GPIO_B1_06,
63 GPIO_B1_07,
64 GPIO_B1_08,
65 GPIO_B1_09,
66 GPIO_B1_10,
67 GPIO_B1_11,
68 GPIO_B1_12,
69 GPIO_B1_13,
70 GPIO_B1_14,
71 GPIO_B1_15,
72 GPIO_EMC_00,
73 GPIO_EMC_01,
74 GPIO_EMC_02,
75 GPIO_EMC_03,
76 GPIO_EMC_04,
77 GPIO_EMC_05,
78 GPIO_EMC_06,
79 GPIO_EMC_07,
80 GPIO_EMC_08,
81 GPIO_EMC_09,
82 GPIO_EMC_10,
83 GPIO_EMC_11,
84 GPIO_EMC_12,
85 GPIO_EMC_13,
86 GPIO_EMC_14,
87 GPIO_EMC_15,
88 GPIO_EMC_16,
89 GPIO_EMC_17,
90 GPIO_EMC_18,
91 GPIO_EMC_19,
92 GPIO_EMC_20,
93 GPIO_EMC_21,
94 GPIO_EMC_22,
95 GPIO_EMC_23,
96 GPIO_EMC_24,
97 GPIO_EMC_25,
98 GPIO_EMC_26,
99 GPIO_EMC_27,
100 GPIO_EMC_28,
101 GPIO_EMC_29,
102 GPIO_EMC_30,
103 GPIO_EMC_31,
104 GPIO_EMC_32,
105 GPIO_EMC_33,
106 GPIO_EMC_34,
107 GPIO_EMC_35,
108 GPIO_EMC_36,
109 GPIO_EMC_37,
110 GPIO_EMC_38,
111 GPIO_EMC_39,
112 GPIO_EMC_40,
113 GPIO_EMC_41,
114 GPIO_SD_B0_00,
115 GPIO_SD_B0_01,
116 GPIO_SD_B0_02,
117 GPIO_SD_B0_03,
118 GPIO_SD_B0_04,
119 GPIO_SD_B0_05,
120 GPIO_SD_B1_00,
121 GPIO_SD_B1_01,
122 GPIO_SD_B1_02,
123 GPIO_SD_B1_03,
124 GPIO_SD_B1_04,
125 GPIO_SD_B1_05,
126 GPIO_SD_B1_06,
127 GPIO_SD_B1_07,
128 GPIO_SD_B1_08,
129 GPIO_SD_B1_09,
130 GPIO_SD_B1_10,
131 GPIO_SD_B1_11,
132 WAKEUP,
133 PMIC_ON_REQ,
134 PMIC_STBY_REQ,
135}
136
137impl_gpio! {
138 // GPIO Bank 1
139 GPIO_AD_B0_00(Gpio1, 0);
140 GPIO_AD_B0_01(Gpio1, 1);
141 GPIO_AD_B0_02(Gpio1, 2);
142 GPIO_AD_B0_03(Gpio1, 3);
143 GPIO_AD_B0_04(Gpio1, 4);
144 GPIO_AD_B0_05(Gpio1, 5);
145 GPIO_AD_B0_06(Gpio1, 6);
146 GPIO_AD_B0_07(Gpio1, 7);
147 GPIO_AD_B0_08(Gpio1, 8);
148 GPIO_AD_B0_09(Gpio1, 9);
149 GPIO_AD_B0_10(Gpio1, 10);
150 GPIO_AD_B0_11(Gpio1, 11);
151 GPIO_AD_B0_12(Gpio1, 12);
152 GPIO_AD_B0_13(Gpio1, 13);
153 GPIO_AD_B0_14(Gpio1, 14);
154 GPIO_AD_B0_15(Gpio1, 15);
155 GPIO_AD_B1_00(Gpio1, 16);
156 GPIO_AD_B1_01(Gpio1, 17);
157 GPIO_AD_B1_02(Gpio1, 18);
158 GPIO_AD_B1_03(Gpio1, 19);
159 GPIO_AD_B1_04(Gpio1, 20);
160 GPIO_AD_B1_05(Gpio1, 21);
161 GPIO_AD_B1_06(Gpio1, 22);
162 GPIO_AD_B1_07(Gpio1, 23);
163 GPIO_AD_B1_08(Gpio1, 24);
164 GPIO_AD_B1_09(Gpio1, 25);
165 GPIO_AD_B1_10(Gpio1, 26);
166 GPIO_AD_B1_11(Gpio1, 27);
167 GPIO_AD_B1_12(Gpio1, 28);
168 GPIO_AD_B1_13(Gpio1, 29);
169 GPIO_AD_B1_14(Gpio1, 30);
170 GPIO_AD_B1_15(Gpio1, 31);
171
172 // GPIO Bank 2
173 GPIO_B0_00(Gpio2, 0);
174 GPIO_B0_01(Gpio2, 1);
175 GPIO_B0_02(Gpio2, 2);
176 GPIO_B0_03(Gpio2, 3);
177 GPIO_B0_04(Gpio2, 4);
178 GPIO_B0_05(Gpio2, 5);
179 GPIO_B0_06(Gpio2, 6);
180 GPIO_B0_07(Gpio2, 7);
181 GPIO_B0_08(Gpio2, 8);
182 GPIO_B0_09(Gpio2, 9);
183 GPIO_B0_10(Gpio2, 10);
184 GPIO_B0_11(Gpio2, 11);
185 GPIO_B0_12(Gpio2, 12);
186 GPIO_B0_13(Gpio2, 13);
187 GPIO_B0_14(Gpio2, 14);
188 GPIO_B0_15(Gpio2, 15);
189 GPIO_B1_00(Gpio2, 16);
190 GPIO_B1_01(Gpio2, 17);
191 GPIO_B1_02(Gpio2, 18);
192 GPIO_B1_03(Gpio2, 19);
193 GPIO_B1_04(Gpio2, 20);
194 GPIO_B1_05(Gpio2, 21);
195 GPIO_B1_06(Gpio2, 22);
196 GPIO_B1_07(Gpio2, 23);
197 GPIO_B1_08(Gpio2, 24);
198 GPIO_B1_09(Gpio2, 25);
199 GPIO_B1_10(Gpio2, 26);
200 GPIO_B1_11(Gpio2, 27);
201 GPIO_B1_12(Gpio2, 28);
202 GPIO_B1_13(Gpio2, 29);
203 GPIO_B1_14(Gpio2, 30);
204 GPIO_B1_15(Gpio2, 31);
205
206 // GPIO Bank 4 (EMC is 4, then 3)
207 GPIO_EMC_00(Gpio4, 0);
208 GPIO_EMC_01(Gpio4, 1);
209 GPIO_EMC_02(Gpio4, 2);
210 GPIO_EMC_03(Gpio4, 3);
211 GPIO_EMC_04(Gpio4, 4);
212 GPIO_EMC_05(Gpio4, 5);
213 GPIO_EMC_06(Gpio4, 6);
214 GPIO_EMC_07(Gpio4, 7);
215 GPIO_EMC_08(Gpio4, 8);
216 GPIO_EMC_09(Gpio4, 9);
217 GPIO_EMC_10(Gpio4, 10);
218 GPIO_EMC_11(Gpio4, 11);
219 GPIO_EMC_12(Gpio4, 12);
220 GPIO_EMC_13(Gpio4, 13);
221 GPIO_EMC_14(Gpio4, 14);
222 GPIO_EMC_15(Gpio4, 15);
223 GPIO_EMC_16(Gpio4, 16);
224 GPIO_EMC_17(Gpio4, 17);
225 GPIO_EMC_18(Gpio4, 18);
226 GPIO_EMC_19(Gpio4, 19);
227 GPIO_EMC_20(Gpio4, 20);
228 GPIO_EMC_21(Gpio4, 21);
229 GPIO_EMC_22(Gpio4, 22);
230 GPIO_EMC_23(Gpio4, 23);
231 GPIO_EMC_24(Gpio4, 24);
232 GPIO_EMC_25(Gpio4, 25);
233 GPIO_EMC_26(Gpio4, 26);
234 GPIO_EMC_27(Gpio4, 27);
235 GPIO_EMC_28(Gpio4, 28);
236 GPIO_EMC_29(Gpio4, 29);
237 GPIO_EMC_30(Gpio4, 30);
238 GPIO_EMC_31(Gpio4, 31);
239
240 // GPIO Bank 3
241 GPIO_EMC_32(Gpio3, 18);
242 GPIO_EMC_33(Gpio3, 19);
243 GPIO_EMC_34(Gpio3, 20);
244 GPIO_EMC_35(Gpio3, 21);
245 GPIO_EMC_36(Gpio3, 22);
246 GPIO_EMC_37(Gpio3, 23);
247 GPIO_EMC_38(Gpio3, 24);
248 GPIO_EMC_39(Gpio3, 25);
249 GPIO_EMC_40(Gpio3, 26);
250 GPIO_EMC_41(Gpio3, 27);
251 GPIO_SD_B0_00(Gpio3, 12);
252 GPIO_SD_B0_01(Gpio3, 13);
253 GPIO_SD_B0_02(Gpio3, 14);
254 GPIO_SD_B0_03(Gpio3, 15);
255 GPIO_SD_B0_04(Gpio3, 16);
256 GPIO_SD_B0_05(Gpio3, 17);
257 GPIO_SD_B1_00(Gpio3, 0);
258 GPIO_SD_B1_01(Gpio3, 1);
259 GPIO_SD_B1_02(Gpio3, 2);
260 GPIO_SD_B1_03(Gpio3, 3);
261 GPIO_SD_B1_04(Gpio3, 4);
262 GPIO_SD_B1_05(Gpio3, 5);
263 GPIO_SD_B1_06(Gpio3, 6);
264 GPIO_SD_B1_07(Gpio3, 7);
265 GPIO_SD_B1_08(Gpio3, 8);
266 GPIO_SD_B1_09(Gpio3, 9);
267 GPIO_SD_B1_10(Gpio3, 10);
268 GPIO_SD_B1_11(Gpio3, 11);
269
270 WAKEUP(Gpio5, 0);
271 PMIC_ON_REQ(Gpio5, 1);
272 PMIC_STBY_REQ(Gpio5, 2);
273}
274 3
275pub(crate) mod _generated { 4pub(crate) mod _generated {
276 #![allow(dead_code)] 5 #![allow(dead_code)]
@@ -280,3 +9,5 @@ pub(crate) mod _generated {
280 9
281 include!(concat!(env!("OUT_DIR"), "/_generated.rs")); 10 include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
282} 11}
12
13pub use _generated::*;
diff --git a/embassy-nxp/src/dma.rs b/embassy-nxp/src/dma.rs
index e2df65fc9..1f479122d 100644
--- a/embassy-nxp/src/dma.rs
+++ b/embassy-nxp/src/dma.rs
@@ -1,3 +1,4 @@
1#![macro_use]
1//! Direct Memory Access (DMA) driver. 2//! Direct Memory Access (DMA) driver.
2 3
3#[cfg_attr(feature = "lpc55-core0", path = "./dma/lpc55.rs")] 4#[cfg_attr(feature = "lpc55-core0", path = "./dma/lpc55.rs")]
diff --git a/embassy-nxp/src/dma/lpc55.rs b/embassy-nxp/src/dma/lpc55.rs
index 578d1fd88..623644bf1 100644
--- a/embassy-nxp/src/dma/lpc55.rs
+++ b/embassy-nxp/src/dma/lpc55.rs
@@ -1,17 +1,22 @@
1#![macro_use]
2
1use core::cell::RefCell; 3use core::cell::RefCell;
2use core::future::Future; 4use core::future::Future;
3use core::pin::Pin; 5use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering}; 6use core::sync::atomic::{Ordering, compiler_fence};
5use core::task::{Context, Poll}; 7use core::task::{Context, Poll};
6 8
7use critical_section::Mutex; 9use critical_section::Mutex;
8use embassy_hal_internal::interrupt::InterruptExt; 10use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_hal_internal::{impl_peripheral, PeripheralType}; 11use embassy_hal_internal::{PeripheralType, impl_peripheral};
10use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
11 13
12use crate::pac::{DMA0, SYSCON, *}; 14use crate::Peri;
13use crate::{peripherals, Peri}; 15#[cfg(feature = "rt")]
16use crate::pac::interrupt;
17use crate::pac::{SYSCON, *};
14 18
19#[cfg(feature = "rt")]
15#[interrupt] 20#[interrupt]
16fn DMA0() { 21fn DMA0() {
17 let inta = DMA0.inta0().read().ia(); 22 let inta = DMA0.inta0().read().ia();
@@ -278,7 +283,7 @@ static DMA_DESCRIPTORS: Mutex<RefCell<DmaDescriptorTable>> = Mutex::new(RefCell:
278 }; CHANNEL_COUNT], 283 }; CHANNEL_COUNT],
279})); 284}));
280 285
281trait SealedChannel {} 286pub(crate) trait SealedChannel {}
282trait SealedWord {} 287trait SealedWord {}
283 288
284/// DMA channel interface. 289/// DMA channel interface.
@@ -323,7 +328,7 @@ impl Word for u32 {
323 328
324/// Type erased DMA channel. 329/// Type erased DMA channel.
325pub struct AnyChannel { 330pub struct AnyChannel {
326 number: u8, 331 pub(crate) number: u8,
327} 332}
328 333
329impl_peripheral!(AnyChannel); 334impl_peripheral!(AnyChannel);
@@ -335,10 +340,10 @@ impl Channel for AnyChannel {
335 } 340 }
336} 341}
337 342
338macro_rules! channel { 343macro_rules! impl_dma_channel {
339 ($name:ident, $num:expr) => { 344 ($instance:ident, $name:ident, $num:expr) => {
340 impl SealedChannel for peripherals::$name {} 345 impl crate::dma::SealedChannel for crate::peripherals::$name {}
341 impl Channel for peripherals::$name { 346 impl crate::dma::Channel for crate::peripherals::$name {
342 fn number(&self) -> u8 { 347 fn number(&self) -> u8 {
343 $num 348 $num
344 } 349 }
@@ -346,32 +351,10 @@ macro_rules! channel {
346 351
347 impl From<peripherals::$name> for crate::dma::AnyChannel { 352 impl From<peripherals::$name> for crate::dma::AnyChannel {
348 fn from(val: peripherals::$name) -> Self { 353 fn from(val: peripherals::$name) -> Self {
354 use crate::dma::Channel;
355
349 Self { number: val.number() } 356 Self { number: val.number() }
350 } 357 }
351 } 358 }
352 }; 359 };
353} 360}
354
355channel!(DMA_CH0, 0);
356channel!(DMA_CH1, 1);
357channel!(DMA_CH2, 2);
358channel!(DMA_CH3, 3);
359channel!(DMA_CH4, 4);
360channel!(DMA_CH5, 5);
361channel!(DMA_CH6, 6);
362channel!(DMA_CH7, 7);
363channel!(DMA_CH8, 8);
364channel!(DMA_CH9, 9);
365channel!(DMA_CH10, 10);
366channel!(DMA_CH11, 11);
367channel!(DMA_CH12, 12);
368channel!(DMA_CH13, 13);
369channel!(DMA_CH14, 14);
370channel!(DMA_CH15, 15);
371channel!(DMA_CH16, 16);
372channel!(DMA_CH17, 17);
373channel!(DMA_CH18, 18);
374channel!(DMA_CH19, 19);
375channel!(DMA_CH20, 20);
376channel!(DMA_CH21, 21);
377channel!(DMA_CH22, 22);
diff --git a/embassy-nxp/src/fmt.rs b/embassy-nxp/src/fmt.rs
index 27d41ace6..11275235e 100644
--- a/embassy-nxp/src/fmt.rs
+++ b/embassy-nxp/src/fmt.rs
@@ -1,5 +1,4 @@
1//! Copied from embassy-rp 1//! Copied from embassy-rp
2
3#![macro_use] 2#![macro_use]
4#![allow(unused)] 3#![allow(unused)]
5 4
diff --git a/embassy-nxp/src/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs
index 36ea99d21..6be405463 100644
--- a/embassy-nxp/src/gpio/lpc55.rs
+++ b/embassy-nxp/src/gpio/lpc55.rs
@@ -1,8 +1,11 @@
1use embassy_hal_internal::{impl_peripheral, PeripheralType}; 1#![macro_use]
2 2
3use embassy_hal_internal::{PeripheralType, impl_peripheral};
4
5use crate::Peri;
6use crate::pac::common::{RW, Reg};
3use crate::pac::iocon::vals::{PioDigimode, PioMode}; 7use crate::pac::iocon::vals::{PioDigimode, PioMode};
4use crate::pac::{GPIO, IOCON, SYSCON}; 8use crate::pac::{GPIO, IOCON, SYSCON, iocon};
5use crate::{peripherals, Peri};
6 9
7pub(crate) fn init() { 10pub(crate) fn init() {
8 // Enable clocks for GPIO, PINT, and IOCON 11 // Enable clocks for GPIO, PINT, and IOCON
@@ -38,8 +41,8 @@ pub enum Pull {
38/// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks. 41/// The LPC55 boards have two GPIO banks, each with 32 pins. This enum represents the two banks.
39#[derive(Debug, Eq, PartialEq, Clone, Copy)] 42#[derive(Debug, Eq, PartialEq, Clone, Copy)]
40pub enum Bank { 43pub enum Bank {
41 Bank0 = 0, 44 Gpio0 = 0,
42 Bank1 = 1, 45 Gpio1 = 1,
43} 46}
44 47
45/// GPIO output driver. Internally, this is a specialized [Flex] pin. 48/// GPIO output driver. Internally, this is a specialized [Flex] pin.
@@ -109,13 +112,7 @@ impl<'d> Input<'d> {
109 112
110 /// Set the pull configuration for the pin. To disable the pull, use [Pull::None]. 113 /// Set the pull configuration for the pin. To disable the pull, use [Pull::None].
111 pub fn set_pull(&mut self, pull: Pull) { 114 pub fn set_pull(&mut self, pull: Pull) {
112 match_iocon!(register, self.pin.pin_bank(), self.pin.pin_number(), { 115 self.pin.set_pull(pull);
113 register.modify(|w| match pull {
114 Pull::None => w.set_mode(PioMode::INACTIVE),
115 Pull::Up => w.set_mode(PioMode::PULL_UP),
116 Pull::Down => w.set_mode(PioMode::PULL_DOWN),
117 });
118 });
119 } 116 }
120 117
121 /// Get the current input level of the pin. 118 /// Get the current input level of the pin.
@@ -193,11 +190,20 @@ impl<'d> Flex<'d> {
193 1 << self.pin.pin_number() 190 1 << self.pin.pin_number()
194 } 191 }
195 192
193 /// Set the pull configuration for the pin. To disable the pull, use [Pull::None].
194 pub fn set_pull(&mut self, pull: Pull) {
195 self.pin.pio().modify(|w| match pull {
196 Pull::None => w.set_mode(PioMode::INACTIVE),
197 Pull::Up => w.set_mode(PioMode::PULL_UP),
198 Pull::Down => w.set_mode(PioMode::PULL_DOWN),
199 });
200 }
201
196 /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default 202 /// Set the pin to digital mode. This is required for using a pin as a GPIO pin. The default
197 /// setting for pins is (usually) non-digital. 203 /// setting for pins is (usually) non-digital.
198 fn set_as_digital(&mut self) { 204 fn set_as_digital(&mut self) {
199 match_iocon!(register, self.pin_bank(), self.pin_number(), { 205 self.pin.pio().modify(|w| {
200 register.modify(|w| w.set_digimode(PioDigimode::DIGITAL)); 206 w.set_digimode(PioDigimode::DIGITAL);
201 }); 207 });
202 } 208 }
203 209
@@ -220,6 +226,14 @@ impl<'d> Flex<'d> {
220pub(crate) trait SealedPin: Sized { 226pub(crate) trait SealedPin: Sized {
221 fn pin_bank(&self) -> Bank; 227 fn pin_bank(&self) -> Bank;
222 fn pin_number(&self) -> u8; 228 fn pin_number(&self) -> u8;
229
230 #[inline]
231 fn pio(&self) -> Reg<iocon::regs::Pio, RW> {
232 match self.pin_bank() {
233 Bank::Gpio0 => IOCON.pio0(self.pin_number() as usize),
234 Bank::Gpio1 => IOCON.pio1(self.pin_number() as usize),
235 }
236 }
223} 237}
224 238
225/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an 239/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an
@@ -242,8 +256,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
242 256
243/// Type-erased GPIO pin. 257/// Type-erased GPIO pin.
244pub struct AnyPin { 258pub struct AnyPin {
245 pin_bank: Bank, 259 pub(crate) pin_bank: Bank,
246 pin_number: u8, 260 pub(crate) pin_number: u8,
247} 261}
248 262
249impl AnyPin { 263impl AnyPin {
@@ -272,47 +286,13 @@ impl SealedPin for AnyPin {
272 } 286 }
273} 287}
274 288
275/// Match the pin bank and number of a pin to the corresponding IOCON register.
276///
277/// # Example
278/// ```
279/// use embassy_nxp::gpio::Bank;
280/// use embassy_nxp::pac_utils::{iocon_reg, match_iocon};
281///
282/// // Make pin PIO1_6 digital and set it to pull-down mode.
283/// match_iocon!(register, Bank::Bank1, 6, {
284/// register.modify(|w|{
285/// w.set_mode(PioMode::PULL_DOWN);
286/// w.set_digimode(PioDigimode::DIGITAL);
287///
288/// }
289/// });
290/// ```
291macro_rules! match_iocon {
292 ($register:ident, $pin_bank:expr, $pin_number:expr, $action:expr) => {
293 match $pin_bank {
294 Bank::Bank0 => {
295 let $register = IOCON.pio0($pin_number as usize);
296 $action;
297 }
298
299 Bank::Bank1 => {
300 let $register = IOCON.pio1($pin_number as usize);
301 $action;
302 }
303 }
304 };
305}
306
307pub(crate) use match_iocon;
308
309macro_rules! impl_pin { 289macro_rules! impl_pin {
310 ($name:ident, $bank:expr, $pin_num:expr) => { 290 ($name:ident, $bank:ident, $pin_num:expr) => {
311 impl Pin for peripherals::$name {} 291 impl crate::gpio::Pin for peripherals::$name {}
312 impl SealedPin for peripherals::$name { 292 impl crate::gpio::SealedPin for peripherals::$name {
313 #[inline] 293 #[inline]
314 fn pin_bank(&self) -> Bank { 294 fn pin_bank(&self) -> crate::gpio::Bank {
315 $bank 295 crate::gpio::Bank::$bank
316 } 296 }
317 297
318 #[inline] 298 #[inline]
@@ -323,6 +303,8 @@ macro_rules! impl_pin {
323 303
324 impl From<peripherals::$name> for crate::gpio::AnyPin { 304 impl From<peripherals::$name> for crate::gpio::AnyPin {
325 fn from(val: peripherals::$name) -> Self { 305 fn from(val: peripherals::$name) -> Self {
306 use crate::gpio::SealedPin;
307
326 Self { 308 Self {
327 pin_bank: val.pin_bank(), 309 pin_bank: val.pin_bank(),
328 pin_number: val.pin_number(), 310 pin_number: val.pin_number(),
@@ -331,68 +313,3 @@ macro_rules! impl_pin {
331 } 313 }
332 }; 314 };
333} 315}
334
335impl_pin!(PIO0_0, Bank::Bank0, 0);
336impl_pin!(PIO0_1, Bank::Bank0, 1);
337impl_pin!(PIO0_2, Bank::Bank0, 2);
338impl_pin!(PIO0_3, Bank::Bank0, 3);
339impl_pin!(PIO0_4, Bank::Bank0, 4);
340impl_pin!(PIO0_5, Bank::Bank0, 5);
341impl_pin!(PIO0_6, Bank::Bank0, 6);
342impl_pin!(PIO0_7, Bank::Bank0, 7);
343impl_pin!(PIO0_8, Bank::Bank0, 8);
344impl_pin!(PIO0_9, Bank::Bank0, 9);
345impl_pin!(PIO0_10, Bank::Bank0, 10);
346impl_pin!(PIO0_11, Bank::Bank0, 11);
347impl_pin!(PIO0_12, Bank::Bank0, 12);
348impl_pin!(PIO0_13, Bank::Bank0, 13);
349impl_pin!(PIO0_14, Bank::Bank0, 14);
350impl_pin!(PIO0_15, Bank::Bank0, 15);
351impl_pin!(PIO0_16, Bank::Bank0, 16);
352impl_pin!(PIO0_17, Bank::Bank0, 17);
353impl_pin!(PIO0_18, Bank::Bank0, 18);
354impl_pin!(PIO0_19, Bank::Bank0, 19);
355impl_pin!(PIO0_20, Bank::Bank0, 20);
356impl_pin!(PIO0_21, Bank::Bank0, 21);
357impl_pin!(PIO0_22, Bank::Bank0, 22);
358impl_pin!(PIO0_23, Bank::Bank0, 23);
359impl_pin!(PIO0_24, Bank::Bank0, 24);
360impl_pin!(PIO0_25, Bank::Bank0, 25);
361impl_pin!(PIO0_26, Bank::Bank0, 26);
362impl_pin!(PIO0_27, Bank::Bank0, 27);
363impl_pin!(PIO0_28, Bank::Bank0, 28);
364impl_pin!(PIO0_29, Bank::Bank0, 29);
365impl_pin!(PIO0_30, Bank::Bank0, 30);
366impl_pin!(PIO0_31, Bank::Bank0, 31);
367impl_pin!(PIO1_0, Bank::Bank1, 0);
368impl_pin!(PIO1_1, Bank::Bank1, 1);
369impl_pin!(PIO1_2, Bank::Bank1, 2);
370impl_pin!(PIO1_3, Bank::Bank1, 3);
371impl_pin!(PIO1_4, Bank::Bank1, 4);
372impl_pin!(PIO1_5, Bank::Bank1, 5);
373impl_pin!(PIO1_6, Bank::Bank1, 6);
374impl_pin!(PIO1_7, Bank::Bank1, 7);
375impl_pin!(PIO1_8, Bank::Bank1, 8);
376impl_pin!(PIO1_9, Bank::Bank1, 9);
377impl_pin!(PIO1_10, Bank::Bank1, 10);
378impl_pin!(PIO1_11, Bank::Bank1, 11);
379impl_pin!(PIO1_12, Bank::Bank1, 12);
380impl_pin!(PIO1_13, Bank::Bank1, 13);
381impl_pin!(PIO1_14, Bank::Bank1, 14);
382impl_pin!(PIO1_15, Bank::Bank1, 15);
383impl_pin!(PIO1_16, Bank::Bank1, 16);
384impl_pin!(PIO1_17, Bank::Bank1, 17);
385impl_pin!(PIO1_18, Bank::Bank1, 18);
386impl_pin!(PIO1_19, Bank::Bank1, 19);
387impl_pin!(PIO1_20, Bank::Bank1, 20);
388impl_pin!(PIO1_21, Bank::Bank1, 21);
389impl_pin!(PIO1_22, Bank::Bank1, 22);
390impl_pin!(PIO1_23, Bank::Bank1, 23);
391impl_pin!(PIO1_24, Bank::Bank1, 24);
392impl_pin!(PIO1_25, Bank::Bank1, 25);
393impl_pin!(PIO1_26, Bank::Bank1, 26);
394impl_pin!(PIO1_27, Bank::Bank1, 27);
395impl_pin!(PIO1_28, Bank::Bank1, 28);
396impl_pin!(PIO1_29, Bank::Bank1, 29);
397impl_pin!(PIO1_30, Bank::Bank1, 30);
398impl_pin!(PIO1_31, Bank::Bank1, 31);
diff --git a/embassy-nxp/src/gpio/rt1xxx.rs b/embassy-nxp/src/gpio/rt1xxx.rs
index 1d60a0d51..8a560310c 100644
--- a/embassy-nxp/src/gpio/rt1xxx.rs
+++ b/embassy-nxp/src/gpio/rt1xxx.rs
@@ -5,13 +5,13 @@ use core::ops::Not;
5use core::pin::Pin as FuturePin; 5use core::pin::Pin as FuturePin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; 8use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use nxp_pac::gpio::vals::Icr; 10use nxp_pac::gpio::vals::Icr;
11use nxp_pac::iomuxc::vals::Pus; 11use nxp_pac::iomuxc::vals::Pus;
12 12
13use crate::chip::{mux_address, pad_address}; 13use crate::chip::{iomuxc_mux, iomuxc_pad};
14use crate::pac::common::{Reg, RW}; 14use crate::pac::common::{RW, Reg};
15use crate::pac::gpio::Gpio; 15use crate::pac::gpio::Gpio;
16#[cfg(feature = "rt")] 16#[cfg(feature = "rt")]
17use crate::pac::interrupt; 17use crate::pac::interrupt;
@@ -121,6 +121,10 @@ pub enum Bank {
121 /// Bank 5 121 /// Bank 5
122 #[cfg(gpio5)] 122 #[cfg(gpio5)]
123 Gpio5, 123 Gpio5,
124
125 #[cfg(gpio10)]
126 /// Bank 10
127 Gpio10,
124} 128}
125 129
126/// GPIO flexible pin. 130/// GPIO flexible pin.
@@ -656,6 +660,8 @@ static GPIO3_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
656static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; 660static GPIO4_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
657#[cfg(gpio5)] 661#[cfg(gpio5)]
658static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32]; 662static GPIO5_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
663#[cfg(gpio10)]
664static GPIO10_WAKERS: [AtomicWaker; 32] = [const { AtomicWaker::new() }; 32];
659 665
660/// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate. 666/// Sealed trait for pins. This trait is sealed and cannot be implemented outside of this crate.
661pub(crate) trait SealedPin: Sized { 667pub(crate) trait SealedPin: Sized {
@@ -676,13 +682,15 @@ pub(crate) trait SealedPin: Sized {
676 Bank::Gpio4 => pac::GPIO4, 682 Bank::Gpio4 => pac::GPIO4,
677 #[cfg(gpio5)] 683 #[cfg(gpio5)]
678 Bank::Gpio5 => pac::GPIO5, 684 Bank::Gpio5 => pac::GPIO5,
685 #[cfg(gpio10)]
686 Bank::Gpio10 => pac::GPIO10,
679 } 687 }
680 } 688 }
681 689
682 #[inline] 690 #[inline]
683 fn mux(&self) -> Reg<MuxCtl, RW> { 691 fn mux(&self) -> Reg<MuxCtl, RW> {
684 // SAFETY: The generated mux address table is valid since it is generated from the SVD files. 692 // SAFETY: The generated mux address table is valid since it is generated from the SVD files.
685 let address = unsafe { mux_address(self._bank(), self.pin_number()).unwrap_unchecked() }; 693 let address = unsafe { iomuxc_mux(self._bank(), self.pin_number()).unwrap_unchecked() };
686 694
687 // SAFETY: The register at the address is an instance of MuxCtl. 695 // SAFETY: The register at the address is an instance of MuxCtl.
688 unsafe { Reg::from_ptr(address as *mut _) } 696 unsafe { Reg::from_ptr(address as *mut _) }
@@ -690,8 +698,7 @@ pub(crate) trait SealedPin: Sized {
690 698
691 #[inline] 699 #[inline]
692 fn pad(&self) -> Reg<Ctl, RW> { 700 fn pad(&self) -> Reg<Ctl, RW> {
693 // SAFETY: The generated pad address table is valid since it is generated from the SVD files. 701 let address = iomuxc_pad(self._bank(), self.pin_number());
694 let address = unsafe { pad_address(self._bank(), self.pin_number()).unwrap_unchecked() };
695 702
696 // SAFETY: The register at the address is an instance of Ctl. 703 // SAFETY: The register at the address is an instance of Ctl.
697 unsafe { Reg::from_ptr(address as *mut _) } 704 unsafe { Reg::from_ptr(address as *mut _) }
@@ -709,6 +716,8 @@ pub(crate) trait SealedPin: Sized {
709 Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize], 716 Bank::Gpio4 => &GPIO4_WAKERS[self.pin_number() as usize],
710 #[cfg(gpio5)] 717 #[cfg(gpio5)]
711 Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize], 718 Bank::Gpio5 => &GPIO5_WAKERS[self.pin_number() as usize],
719 #[cfg(gpio10)]
720 Bank::Gpio10 => &GPIO10_WAKERS[self.pin_number() as usize],
712 } 721 }
713 } 722 }
714} 723}
@@ -793,39 +802,6 @@ impl<'d> Future for InputFuture<'d> {
793 } 802 }
794} 803}
795 804
796/// A macro to generate all GPIO pins.
797///
798/// This generates a lookup table for IOMUX register addresses.
799macro_rules! impl_gpio {
800 (
801 $($name: ident($bank: ident, $pin_number: expr);)*
802 ) => {
803 #[inline]
804 pub(crate) const fn pad_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> {
805 match (bank, pin) {
806 $(
807 (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::pads::$name),
808 )*
809 _ => None
810 }
811 }
812
813 #[inline]
814 pub(crate) const fn mux_address(bank: crate::gpio::Bank, pin: u8) -> Option<u32> {
815 match (bank, pin) {
816 $(
817 (crate::gpio::Bank::$bank, $pin_number) => Some(crate::chip::_generated::iomuxc::muxes::$name),
818 )*
819 _ => None
820 }
821 }
822
823 $(
824 impl_pin!($name, $bank, $pin_number);
825 )*
826 };
827}
828
829macro_rules! impl_pin { 805macro_rules! impl_pin {
830 ($name: ident, $bank: ident, $pin_num: expr) => { 806 ($name: ident, $bank: ident, $pin_num: expr) => {
831 impl crate::gpio::Pin for crate::peripherals::$name {} 807 impl crate::gpio::Pin for crate::peripherals::$name {}
diff --git a/embassy-nxp/src/iomuxc.rs b/embassy-nxp/src/iomuxc.rs
new file mode 100644
index 000000000..c015ecbc2
--- /dev/null
+++ b/embassy-nxp/src/iomuxc.rs
@@ -0,0 +1,29 @@
1#![macro_use]
2
3/// An IOMUXC pad.
4///
5/// This trait does not imply that GPIO can be used with this pad. [`Pin`](crate::gpio::Pin) must
6/// also be implemented for GPIO.
7#[allow(private_bounds)]
8pub trait Pad: SealedPad {}
9
10pub(crate) trait SealedPad {
11 /// Address of the pad register for this pad.
12 const PAD: *mut ();
13
14 /// Address of the mux register for this pad.
15 ///
16 /// Some pads do not allow muxing (e.g. ONOFF).
17 const MUX: Option<*mut ()>;
18}
19
20macro_rules! impl_iomuxc_pad {
21 ($name: ident, $pad: expr, $mux: expr) => {
22 impl crate::iomuxc::SealedPad for crate::peripherals::$name {
23 const PAD: *mut () = $pad as *mut ();
24 const MUX: Option<*mut ()> = Some($mux as *mut ());
25 }
26
27 impl crate::iomuxc::Pad for crate::peripherals::$name {}
28 };
29}
diff --git a/embassy-nxp/src/lib.rs b/embassy-nxp/src/lib.rs
index f0f0afb6c..4c3dbebb9 100644
--- a/embassy-nxp/src/lib.rs
+++ b/embassy-nxp/src/lib.rs
@@ -1,4 +1,5 @@
1#![no_std] 1#![no_std]
2#![allow(unsafe_op_in_unsafe_fn)]
2 3
3// This mod MUST go first, so that the others see its macros. 4// This mod MUST go first, so that the others see its macros.
4pub(crate) mod fmt; 5pub(crate) mod fmt;
@@ -9,8 +10,15 @@ pub mod gpio;
9#[cfg(feature = "lpc55-core0")] 10#[cfg(feature = "lpc55-core0")]
10pub mod pint; 11pub mod pint;
11#[cfg(feature = "lpc55-core0")] 12#[cfg(feature = "lpc55-core0")]
13pub mod pwm;
14#[cfg(feature = "lpc55-core0")]
15pub mod sct;
16#[cfg(feature = "lpc55-core0")]
12pub mod usart; 17pub mod usart;
13 18
19#[cfg(rt1xxx)]
20mod iomuxc;
21
14#[cfg(feature = "_time_driver")] 22#[cfg(feature = "_time_driver")]
15#[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")] 23#[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")]
16#[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")] 24#[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")]
@@ -22,15 +30,12 @@ mod time_driver;
22#[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")] 30#[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")]
23mod chip; 31mod chip;
24 32
25// TODO: Remove when this module is implemented for other chips 33pub use chip::{Peripherals, interrupt, peripherals};
26#[cfg(feature = "lpc55-core0")] 34pub use embassy_hal_internal::{Peri, PeripheralType};
27pub use chip::interrupt;
28#[cfg(feature = "unstable-pac")] 35#[cfg(feature = "unstable-pac")]
29pub use chip::pac; 36pub use nxp_pac as pac;
30#[cfg(not(feature = "unstable-pac"))] 37#[cfg(not(feature = "unstable-pac"))]
31pub(crate) use chip::pac; 38pub(crate) use nxp_pac as pac;
32pub use chip::{peripherals, Peripherals};
33pub use embassy_hal_internal::{Peri, PeripheralType};
34 39
35/// Macro to bind interrupts to handlers. 40/// Macro to bind interrupts to handlers.
36/// (Copied from `embassy-rp`) 41/// (Copied from `embassy-rp`)
@@ -67,7 +72,7 @@ macro_rules! bind_interrupts {
67 72
68 $( 73 $(
69 #[allow(non_snake_case)] 74 #[allow(non_snake_case)]
70 #[no_mangle] 75 #[unsafe(no_mangle)]
71 $(#[cfg($cond_irq)])? 76 $(#[cfg($cond_irq)])?
72 unsafe extern "C" fn $irq() { 77 unsafe extern "C" fn $irq() {
73 unsafe { 78 unsafe {
@@ -153,7 +158,10 @@ pub fn init(_config: config::Config) -> Peripherals {
153 gpio::init(); 158 gpio::init();
154 159
155 #[cfg(feature = "lpc55-core0")] 160 #[cfg(feature = "lpc55-core0")]
156 pint::init(); 161 {
162 pint::init();
163 pwm::Pwm::reset();
164 }
157 165
158 #[cfg(feature = "_time_driver")] 166 #[cfg(feature = "_time_driver")]
159 time_driver::init(); 167 time_driver::init();
diff --git a/embassy-nxp/src/pint.rs b/embassy-nxp/src/pint.rs
index e594aaa6a..5b10b4540 100644
--- a/embassy-nxp/src/pint.rs
+++ b/embassy-nxp/src/pint.rs
@@ -8,9 +8,9 @@ use critical_section::Mutex;
8use embassy_hal_internal::interrupt::InterruptExt; 8use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::gpio::{self, AnyPin, Level, SealedPin};
12use crate::pac::{interrupt, INPUTMUX, PINT, SYSCON};
13use crate::Peri; 11use crate::Peri;
12use crate::gpio::{self, AnyPin, Level, SealedPin};
13use crate::pac::{INPUTMUX, PINT, SYSCON, interrupt};
14 14
15struct PinInterrupt { 15struct PinInterrupt {
16 assigned: bool, 16 assigned: bool,
diff --git a/embassy-nxp/src/pwm.rs b/embassy-nxp/src/pwm.rs
new file mode 100644
index 000000000..c87a39c34
--- /dev/null
+++ b/embassy-nxp/src/pwm.rs
@@ -0,0 +1,7 @@
1#![macro_use]
2
3//! Pulse-Width Modulation (PWM) driver.
4
5#[cfg_attr(feature = "lpc55-core0", path = "./pwm/lpc55.rs")]
6mod inner;
7pub use inner::*;
diff --git a/embassy-nxp/src/pwm/lpc55.rs b/embassy-nxp/src/pwm/lpc55.rs
new file mode 100644
index 000000000..4cdbd8526
--- /dev/null
+++ b/embassy-nxp/src/pwm/lpc55.rs
@@ -0,0 +1,248 @@
1#![macro_use]
2
3use core::sync::atomic::{AtomicU8, AtomicU32, Ordering};
4
5use embassy_hal_internal::Peri;
6
7use crate::gpio::AnyPin;
8use crate::pac::iocon::vals::{PioDigimode, PioMode, PioOd, PioSlew};
9use crate::pac::sct0::vals;
10use crate::pac::syscon::vals::{SctRst, SctclkselSel};
11use crate::pac::{SCT0, SYSCON};
12use crate::sct;
13
14// Since for now the counter is shared, the TOP value has to be kept.
15static TOP_VALUE: AtomicU32 = AtomicU32::new(0);
16// To check if there are still active instances.
17static REF_COUNT: AtomicU8 = AtomicU8::new(0);
18
19/// The configuration of a PWM output.
20/// Note the period in clock cycles of an output can be computed as:
21/// `(top + 1) * (phase_correct ? 1 : 2) * divider * prescale_factor`
22/// By default, the clock used is 96 MHz.
23#[non_exhaustive]
24#[derive(Clone)]
25pub struct Config {
26 /// Inverts the PWM output signal.
27 pub invert: bool,
28 /// Enables phase-correct mode for PWM operation.
29 /// In phase-correct mode, the PWM signal is generated in such a way that
30 /// the pulse is always centered regardless of the duty cycle.
31 /// The output frequency is halved when phase-correct mode is enabled.
32 pub phase_correct: bool,
33 /// Enables the PWM output, allowing it to generate an output.
34 pub enable: bool,
35 /// A SYSCON clock divider allows precise control over
36 /// the PWM output frequency by gating the PWM counter increment.
37 /// A higher value will result in a slower output frequency.
38 /// The clock is divided by `divider + 1`.
39 pub divider: u8,
40 /// Specifies the factor by which the SCT clock is prescaled to produce the unified
41 /// counter clock. The counter clock is clocked at the rate of the SCT clock divided by
42 /// `PRE + 1`.
43 pub prescale_factor: u8,
44 /// The output goes high when `compare` is higher than the
45 /// counter. A compare of 0 will produce an always low output, while a
46 /// compare of `top` will produce an always high output.
47 pub compare: u32,
48 /// The point at which the counter resets, representing the maximum possible
49 /// period. The counter will either wrap to 0 or reverse depending on the
50 /// setting of `phase_correct`.
51 pub top: u32,
52}
53
54impl Config {
55 pub fn new(compare: u32, top: u32) -> Self {
56 Self {
57 invert: false,
58 phase_correct: false,
59 enable: true,
60 divider: 255,
61 prescale_factor: 255,
62 compare,
63 top,
64 }
65 }
66}
67
68/// PWM driver.
69pub struct Pwm<'d> {
70 _pin: Peri<'d, AnyPin>,
71 output: usize,
72}
73
74impl<'d> Pwm<'d> {
75 pub(crate) fn reset() {
76 // Reset SCTimer => Reset counter and halt it.
77 // It should be done only once during the initialization of the board.
78 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::ASSERTED));
79 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::RELEASED));
80 }
81 fn new_inner<T: sct::Instance, O: sct::Output<T>>(
82 output: usize,
83 channel: Peri<'d, impl sct::OutputPin<T, O>>,
84 config: Config,
85 ) -> Self {
86 // Enable clocks (Syscon is enabled by default)
87 critical_section::with(|_cs| {
88 if !SYSCON.ahbclkctrl0().read().iocon() {
89 SYSCON.ahbclkctrl0().modify(|w| w.set_iocon(true));
90 }
91 if !SYSCON.ahbclkctrl1().read().sct() {
92 SYSCON.ahbclkctrl1().modify(|w| w.set_sct(true));
93 }
94 });
95
96 // Choose the clock for PWM.
97 SYSCON.sctclksel().modify(|w| w.set_sel(SctclkselSel::ENUM_0X3));
98 // For now, 96 MHz.
99
100 // IOCON Setup
101 channel.pio().modify(|w| {
102 w.set_func(channel.pin_func());
103 w.set_digimode(PioDigimode::DIGITAL);
104 w.set_slew(PioSlew::STANDARD);
105 w.set_mode(PioMode::INACTIVE);
106 w.set_od(PioOd::NORMAL);
107 });
108
109 Self::configure(output, &config);
110 REF_COUNT.fetch_add(1, Ordering::Relaxed);
111 Self {
112 _pin: channel.into(),
113 output,
114 }
115 }
116
117 /// Create PWM driver with a single 'a' pin as output.
118 #[inline]
119 pub fn new_output<T: sct::Instance, O: sct::Output<T>>(
120 output: Peri<'d, O>,
121 channel: Peri<'d, impl sct::OutputPin<T, O>>,
122 config: Config,
123 ) -> Self {
124 Self::new_inner::<T, O>(output.number(), channel, config)
125 }
126
127 /// Set the PWM config.
128 pub fn set_config(&mut self, config: &Config) {
129 Self::configure(self.output, config);
130 }
131
132 fn configure(output_number: usize, config: &Config) {
133 // Stop and reset the counter
134 SCT0.ctrl().modify(|w| {
135 if config.phase_correct {
136 w.set_bidir_l(vals::Bidir::UP_DOWN);
137 } else {
138 w.set_bidir_l(vals::Bidir::UP);
139 }
140 w.set_halt_l(true); // halt the counter to make new changes
141 w.set_clrctr_l(true); // clear the counter
142 });
143 // Divides clock by 1-255
144 SYSCON.sctclkdiv().modify(|w| w.set_div(config.divider));
145
146 SCT0.config().modify(|w| {
147 w.set_unify(vals::Unify::UNIFIED_COUNTER);
148 w.set_clkmode(vals::Clkmode::SYSTEM_CLOCK_MODE);
149 w.set_noreload_l(true);
150 w.set_autolimit_l(true);
151 });
152
153 // Before setting the match registers, we have to make sure that `compare` is lower or equal to `top`,
154 // otherwise the counter will not reach the match and, therefore, no events will happen.
155 assert!(config.compare <= config.top);
156
157 if TOP_VALUE.load(Ordering::Relaxed) == 0 {
158 // Match 0 will reset the timer using TOP value
159 SCT0.match_(0).modify(|w| {
160 w.set_matchn_l((config.top & 0xFFFF) as u16);
161 w.set_matchn_h((config.top >> 16) as u16);
162 });
163 } else {
164 panic!("The top value cannot be changed after the initialization.");
165 }
166 // The actual matches that are used for event logic
167 SCT0.match_(output_number + 1).modify(|w| {
168 w.set_matchn_l((config.compare & 0xFFFF) as u16);
169 w.set_matchn_h((config.compare >> 16) as u16);
170 });
171
172 SCT0.match_(15).modify(|w| {
173 w.set_matchn_l(0);
174 w.set_matchn_h(0);
175 });
176
177 // Event configuration
178 critical_section::with(|_cs| {
179 // If it is already set, don't change
180 if SCT0.ev(0).ev_ctrl().read().matchsel() != 15 {
181 SCT0.ev(0).ev_ctrl().modify(|w| {
182 w.set_matchsel(15);
183 w.set_combmode(vals::Combmode::MATCH);
184 // STATE + statev, where STATE is a on-board variable.
185 w.set_stateld(vals::Stateld::ADD);
186 w.set_statev(0);
187 });
188 }
189 });
190 SCT0.ev(output_number + 1).ev_ctrl().modify(|w| {
191 w.set_matchsel((output_number + 1) as u8);
192 w.set_combmode(vals::Combmode::MATCH);
193 w.set_stateld(vals::Stateld::ADD);
194 // STATE + statev, where STATE is a on-board variable.
195 w.set_statev(0);
196 });
197
198 // Assign events to states
199 SCT0.ev(0).ev_state().modify(|w| w.set_statemskn(1 << 0));
200 SCT0.ev(output_number + 1)
201 .ev_state()
202 .modify(|w| w.set_statemskn(1 << 0));
203 // TODO(frihetselsker): optimize nxp-pac so that `set_clr` and `set_set` are turned into a bit array.
204 if config.invert {
205 // Low when event 0 is active
206 SCT0.out(output_number).out_clr().modify(|w| w.set_clr(0, true));
207 // High when event `output_number + 1` is active
208 SCT0.out(output_number)
209 .out_set()
210 .modify(|w| w.set_set(output_number, true));
211 } else {
212 // High when event 0 is active
213 SCT0.out(output_number).out_set().modify(|w| w.set_set(0, true));
214 // Low when event `output_number + 1` is active
215 SCT0.out(output_number)
216 .out_clr()
217 .modify(|w| w.set_clr(output_number, true));
218 }
219
220 if config.phase_correct {
221 // Take into account the set matches and reverse their actions while counting back.
222 SCT0.outputdirctrl()
223 .modify(|w| w.set_setclr(output_number, vals::Setclr::L_REVERSED));
224 }
225
226 // State 0 by default
227 SCT0.state().modify(|w| w.set_state_l(0));
228 // Remove halt and start the actual counter
229 SCT0.ctrl().modify(|w| {
230 w.set_halt_l(!config.enable);
231 });
232 }
233
234 /// Read PWM counter.
235 #[inline]
236 pub fn counter(&self) -> u32 {
237 SCT0.count().read().0
238 }
239}
240
241impl<'d> Drop for Pwm<'d> {
242 fn drop(&mut self) {
243 REF_COUNT.fetch_sub(1, Ordering::AcqRel);
244 if REF_COUNT.load(Ordering::Acquire) == 0 {
245 TOP_VALUE.store(0, Ordering::Release);
246 }
247 }
248}
diff --git a/embassy-nxp/src/sct.rs b/embassy-nxp/src/sct.rs
new file mode 100644
index 000000000..b6b0e35a9
--- /dev/null
+++ b/embassy-nxp/src/sct.rs
@@ -0,0 +1,56 @@
1#![macro_use]
2
3use embassy_hal_internal::PeripheralType;
4use nxp_pac::iocon::vals::PioFunc;
5
6use crate::gpio;
7
8/// SCT instance.
9#[allow(private_bounds)]
10pub trait Instance: SealedInstance + PeripheralType {}
11
12pub(crate) trait SealedInstance {}
13
14/// An SCT output.
15#[allow(private_bounds)]
16pub trait Output<T: Instance>: SealedOutput + PeripheralType {}
17
18pub(crate) trait SealedOutput {
19 /// Output number.
20 fn number(&self) -> usize;
21}
22
23/// An SCT output capable pin.
24pub trait OutputPin<T: Instance, O: Output<T>>: gpio::Pin {
25 fn pin_func(&self) -> PioFunc;
26}
27
28macro_rules! impl_sct_instance {
29 ($instance: ident) => {
30 impl crate::sct::SealedInstance for crate::peripherals::$instance {}
31 impl crate::sct::Instance for crate::peripherals::$instance {}
32 };
33}
34
35macro_rules! impl_sct_output_instance {
36 ($instance: ident, $name: ident, $num: expr) => {
37 impl crate::sct::SealedOutput for crate::peripherals::$name {
38 fn number(&self) -> usize {
39 $num as usize
40 }
41 }
42 impl crate::sct::Output<crate::peripherals::$instance> for crate::peripherals::$name {}
43 };
44}
45
46macro_rules! impl_sct_output_pin {
47 ($instance: ident, $output_instance: ident, $pin: ident, $alt: ident) => {
48 impl crate::sct::OutputPin<crate::peripherals::$instance, crate::peripherals::$output_instance>
49 for crate::peripherals::$pin
50 {
51 fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc {
52 crate::pac::iocon::vals::PioFunc::$alt
53 }
54 }
55 };
56}
diff --git a/embassy-nxp/src/time_driver/rtc.rs b/embassy-nxp/src/time_driver/rtc.rs
index fb6de6a5e..0883fa2e8 100644
--- a/embassy-nxp/src/time_driver/rtc.rs
+++ b/embassy-nxp/src/time_driver/rtc.rs
@@ -4,10 +4,10 @@ use core::task::Waker;
4use critical_section::CriticalSection; 4use critical_section::CriticalSection;
5use embassy_hal_internal::interrupt::{InterruptExt, Priority}; 5use embassy_hal_internal::interrupt::{InterruptExt, Priority};
6use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; 6use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
7use embassy_time_driver::{time_driver_impl, Driver}; 7use embassy_time_driver::{Driver, time_driver_impl};
8use embassy_time_queue_utils::Queue; 8use embassy_time_queue_utils::Queue;
9 9
10use crate::pac::{interrupt, pmc, rtc, PMC, RTC, SYSCON}; 10use crate::pac::{PMC, RTC, SYSCON, interrupt, pmc, rtc};
11 11
12struct AlarmState { 12struct AlarmState {
13 timestamp: Cell<u64>, 13 timestamp: Cell<u64>,
diff --git a/embassy-nxp/src/usart.rs b/embassy-nxp/src/usart.rs
index 1d8886f24..af039dee4 100644
--- a/embassy-nxp/src/usart.rs
+++ b/embassy-nxp/src/usart.rs
@@ -1,3 +1,5 @@
1#![macro_use]
2
1//! Universal Synchronous/Asynchronous Receiver/Transmitter (USART) driver. 3//! Universal Synchronous/Asynchronous Receiver/Transmitter (USART) driver.
2 4
3#[cfg_attr(feature = "lpc55-core0", path = "./usart/lpc55.rs")] 5#[cfg_attr(feature = "lpc55-core0", path = "./usart/lpc55.rs")]
diff --git a/embassy-nxp/src/usart/lpc55.rs b/embassy-nxp/src/usart/lpc55.rs
index 9034ed429..d77f08fd8 100644
--- a/embassy-nxp/src/usart/lpc55.rs
+++ b/embassy-nxp/src/usart/lpc55.rs
@@ -1,19 +1,21 @@
1#![macro_use]
2
1use core::fmt::Debug; 3use core::fmt::Debug;
2use core::future::poll_fn; 4use core::future::poll_fn;
3use core::marker::PhantomData; 5use core::marker::PhantomData;
4use core::sync::atomic::{AtomicBool, Ordering}; 6use core::sync::atomic::{AtomicBool, Ordering};
5use core::task::Poll; 7use core::task::Poll;
6 8
7use embassy_futures::select::{select, Either}; 9use embassy_futures::select::{Either, select};
8use embassy_hal_internal::interrupt::InterruptExt; 10use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_hal_internal::{Peri, PeripheralType}; 11use embassy_hal_internal::{Peri, PeripheralType};
10use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
11use embedded_io::{self, ErrorKind}; 13use embedded_io::{self, ErrorKind};
12 14
13use crate::dma::{AnyChannel, Channel}; 15use crate::dma::{AnyChannel, Channel};
14use crate::gpio::{match_iocon, AnyPin, Bank, SealedPin}; 16use crate::gpio::{AnyPin, SealedPin};
15use crate::interrupt::typelevel::{Binding, Interrupt as _};
16use crate::interrupt::Interrupt; 17use crate::interrupt::Interrupt;
18use crate::interrupt::typelevel::Binding;
17use crate::pac::flexcomm::Flexcomm as FlexcommReg; 19use crate::pac::flexcomm::Flexcomm as FlexcommReg;
18use crate::pac::iocon::vals::PioFunc; 20use crate::pac::iocon::vals::PioFunc;
19use crate::pac::usart::Usart as UsartReg; 21use crate::pac::usart::Usart as UsartReg;
@@ -113,8 +115,8 @@ impl Default for Config {
113 115
114/// Internal DMA state of UART RX. 116/// Internal DMA state of UART RX.
115pub struct DmaState { 117pub struct DmaState {
116 rx_err_waker: AtomicWaker, 118 pub(crate) rx_err_waker: AtomicWaker,
117 rx_err: AtomicBool, 119 pub(crate) rx_err: AtomicBool,
118} 120}
119 121
120/// # Type parameters 122/// # Type parameters
@@ -146,7 +148,8 @@ impl<'d, M: Mode> UsartTx<'d, M> {
146 tx_dma: Peri<'d, impl Channel>, 148 tx_dma: Peri<'d, impl Channel>,
147 config: Config, 149 config: Config,
148 ) -> Self { 150 ) -> Self {
149 Usart::<M>::init::<T>(Some(tx.into()), None, config); 151 let tx_func = tx.pin_func();
152 Usart::<M>::init::<T>(Some((tx.into(), tx_func)), None, config);
150 Self::new_inner(T::info(), Some(tx_dma.into())) 153 Self::new_inner(T::info(), Some(tx_dma.into()))
151 } 154 }
152 155
@@ -179,7 +182,8 @@ impl<'d, M: Mode> UsartTx<'d, M> {
179 182
180impl<'d> UsartTx<'d, Blocking> { 183impl<'d> UsartTx<'d, Blocking> {
181 pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { 184 pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
182 Usart::<Blocking>::init::<T>(Some(tx.into()), None, config); 185 let tx_func = tx.pin_func();
186 Usart::<Blocking>::init::<T>(Some((tx.into(), tx_func)), None, config);
183 Self::new_inner(T::info(), None) 187 Self::new_inner(T::info(), None)
184 } 188 }
185} 189}
@@ -208,7 +212,8 @@ impl<'d, M: Mode> UsartRx<'d, M> {
208 rx_dma: Peri<'d, impl Channel>, 212 rx_dma: Peri<'d, impl Channel>,
209 config: Config, 213 config: Config,
210 ) -> Self { 214 ) -> Self {
211 Usart::<M>::init::<T>(None, Some(rx.into()), config); 215 let rx_func = rx.pin_func();
216 Usart::<M>::init::<T>(None, Some((rx.into(), rx_func)), config);
212 Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into())) 217 Self::new_inner(T::info(), T::dma_state(), has_irq, Some(rx_dma.into()))
213 } 218 }
214 219
@@ -280,7 +285,8 @@ impl<'d, M: Mode> UsartRx<'d, M> {
280 285
281impl<'d> UsartRx<'d, Blocking> { 286impl<'d> UsartRx<'d, Blocking> {
282 pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { 287 pub fn new_blocking<T: Instance>(_usart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
283 Usart::<Blocking>::init::<T>(None, Some(rx.into()), config); 288 let rx_func = rx.pin_func();
289 Usart::<Blocking>::init::<T>(None, Some((rx.into(), rx_func)), config);
284 Self::new_inner(T::info(), T::dma_state(), false, None) 290 Self::new_inner(T::info(), T::dma_state(), false, None)
285 } 291 }
286} 292}
@@ -405,7 +411,10 @@ impl<'d> Usart<'d, Blocking> {
405 rx: Peri<'d, impl RxPin<T>>, 411 rx: Peri<'d, impl RxPin<T>>,
406 config: Config, 412 config: Config,
407 ) -> Self { 413 ) -> Self {
408 Self::new_inner(usart, tx.into(), rx.into(), false, None, None, config) 414 let tx_func = tx.pin_func();
415 let rx_func = rx.pin_func();
416
417 Self::new_inner(usart, tx.into(), tx_func, rx.into(), rx_func, false, None, None, config)
409 } 418 }
410} 419}
411 420
@@ -419,10 +428,15 @@ impl<'d> Usart<'d, Async> {
419 rx_dma: Peri<'d, impl RxChannel<T>>, 428 rx_dma: Peri<'d, impl RxChannel<T>>,
420 config: Config, 429 config: Config,
421 ) -> Self { 430 ) -> Self {
431 let tx_func = tx.pin_func();
432 let rx_func = rx.pin_func();
433
422 Self::new_inner( 434 Self::new_inner(
423 uart, 435 uart,
424 tx.into(), 436 tx.into(),
437 tx_func,
425 rx.into(), 438 rx.into(),
439 rx_func,
426 true, 440 true,
427 Some(tx_dma.into()), 441 Some(tx_dma.into()),
428 Some(rx_dma.into()), 442 Some(rx_dma.into()),
@@ -435,20 +449,26 @@ impl<'d, M: Mode> Usart<'d, M> {
435 fn new_inner<T: Instance>( 449 fn new_inner<T: Instance>(
436 _usart: Peri<'d, T>, 450 _usart: Peri<'d, T>,
437 mut tx: Peri<'d, AnyPin>, 451 mut tx: Peri<'d, AnyPin>,
452 tx_func: PioFunc,
438 mut rx: Peri<'d, AnyPin>, 453 mut rx: Peri<'d, AnyPin>,
454 rx_func: PioFunc,
439 has_irq: bool, 455 has_irq: bool,
440 tx_dma: Option<Peri<'d, AnyChannel>>, 456 tx_dma: Option<Peri<'d, AnyChannel>>,
441 rx_dma: Option<Peri<'d, AnyChannel>>, 457 rx_dma: Option<Peri<'d, AnyChannel>>,
442 config: Config, 458 config: Config,
443 ) -> Self { 459 ) -> Self {
444 Self::init::<T>(Some(tx.reborrow()), Some(rx.reborrow()), config); 460 Self::init::<T>(Some((tx.reborrow(), tx_func)), Some((rx.reborrow(), rx_func)), config);
445 Self { 461 Self {
446 tx: UsartTx::new_inner(T::info(), tx_dma), 462 tx: UsartTx::new_inner(T::info(), tx_dma),
447 rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma), 463 rx: UsartRx::new_inner(T::info(), T::dma_state(), has_irq, rx_dma),
448 } 464 }
449 } 465 }
450 466
451 fn init<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>, config: Config) { 467 fn init<T: Instance>(
468 tx: Option<(Peri<'_, AnyPin>, PioFunc)>,
469 rx: Option<(Peri<'_, AnyPin>, PioFunc)>,
470 config: Config,
471 ) {
452 Self::configure_flexcomm(T::info().fc_reg, T::instance_number()); 472 Self::configure_flexcomm(T::info().fc_reg, T::instance_number());
453 Self::configure_clock::<T>(&config); 473 Self::configure_clock::<T>(&config);
454 Self::pin_config::<T>(tx, rx); 474 Self::pin_config::<T>(tx, rx);
@@ -553,31 +573,27 @@ impl<'d, M: Mode> Usart<'d, M> {
553 .modify(|w| w.set_brgval((brg_value - 1) as u16)); 573 .modify(|w| w.set_brgval((brg_value - 1) as u16));
554 } 574 }
555 575
556 fn pin_config<T: Instance>(tx: Option<Peri<'_, AnyPin>>, rx: Option<Peri<'_, AnyPin>>) { 576 fn pin_config<T: Instance>(tx: Option<(Peri<'_, AnyPin>, PioFunc)>, rx: Option<(Peri<'_, AnyPin>, PioFunc)>) {
557 if let Some(tx_pin) = tx { 577 if let Some((tx_pin, func)) = tx {
558 match_iocon!(register, tx_pin.pin_bank(), tx_pin.pin_number(), { 578 tx_pin.pio().modify(|w| {
559 register.modify(|w| { 579 w.set_func(func);
560 w.set_func(T::tx_pin_func()); 580 w.set_mode(iocon::vals::PioMode::INACTIVE);
561 w.set_mode(iocon::vals::PioMode::INACTIVE); 581 w.set_slew(iocon::vals::PioSlew::STANDARD);
562 w.set_slew(iocon::vals::PioSlew::STANDARD); 582 w.set_invert(false);
563 w.set_invert(false); 583 w.set_digimode(iocon::vals::PioDigimode::DIGITAL);
564 w.set_digimode(iocon::vals::PioDigimode::DIGITAL); 584 w.set_od(iocon::vals::PioOd::NORMAL);
565 w.set_od(iocon::vals::PioOd::NORMAL); 585 });
566 });
567 })
568 } 586 }
569 587
570 if let Some(rx_pin) = rx { 588 if let Some((rx_pin, func)) = rx {
571 match_iocon!(register, rx_pin.pin_bank(), rx_pin.pin_number(), { 589 rx_pin.pio().modify(|w| {
572 register.modify(|w| { 590 w.set_func(func);
573 w.set_func(T::rx_pin_func()); 591 w.set_mode(iocon::vals::PioMode::INACTIVE);
574 w.set_mode(iocon::vals::PioMode::INACTIVE); 592 w.set_slew(iocon::vals::PioSlew::STANDARD);
575 w.set_slew(iocon::vals::PioSlew::STANDARD); 593 w.set_invert(false);
576 w.set_invert(false); 594 w.set_digimode(iocon::vals::PioDigimode::DIGITAL);
577 w.set_digimode(iocon::vals::PioDigimode::DIGITAL); 595 w.set_od(iocon::vals::PioOd::NORMAL);
578 w.set_od(iocon::vals::PioOd::NORMAL); 596 });
579 });
580 })
581 }; 597 };
582 } 598 }
583 599
@@ -804,18 +820,16 @@ impl<'d> embedded_io::Read for Usart<'d, Blocking> {
804 } 820 }
805} 821}
806 822
807struct Info { 823pub(crate) struct Info {
808 usart_reg: UsartReg, 824 pub(crate) usart_reg: UsartReg,
809 fc_reg: FlexcommReg, 825 pub(crate) fc_reg: FlexcommReg,
810 interrupt: Interrupt, 826 pub(crate) interrupt: Interrupt,
811} 827}
812 828
813trait SealedInstance { 829pub(crate) trait SealedInstance {
814 fn info() -> &'static Info; 830 fn info() -> &'static Info;
815 fn dma_state() -> &'static DmaState; 831 fn dma_state() -> &'static DmaState;
816 fn instance_number() -> usize; 832 fn instance_number() -> usize;
817 fn tx_pin_func() -> PioFunc;
818 fn rx_pin_func() -> PioFunc;
819} 833}
820 834
821/// UART instance. 835/// UART instance.
@@ -825,10 +839,13 @@ pub trait Instance: SealedInstance + PeripheralType {
825 type Interrupt: crate::interrupt::typelevel::Interrupt; 839 type Interrupt: crate::interrupt::typelevel::Interrupt;
826} 840}
827 841
828macro_rules! impl_instance { 842macro_rules! impl_usart_instance {
829 ($inst:ident, $fc:ident, $tx_pin:ident, $rx_pin:ident, $fc_num:expr) => { 843 ($inst:ident, $fc:ident, $fc_num:expr) => {
830 impl $crate::usart::inner::SealedInstance for $crate::peripherals::$inst { 844 impl crate::usart::SealedInstance for $crate::peripherals::$inst {
831 fn info() -> &'static Info { 845 fn info() -> &'static crate::usart::Info {
846 use crate::interrupt::typelevel::Interrupt;
847 use crate::usart::Info;
848
832 static INFO: Info = Info { 849 static INFO: Info = Info {
833 usart_reg: crate::pac::$inst, 850 usart_reg: crate::pac::$inst,
834 fc_reg: crate::pac::$fc, 851 fc_reg: crate::pac::$fc,
@@ -837,7 +854,13 @@ macro_rules! impl_instance {
837 &INFO 854 &INFO
838 } 855 }
839 856
840 fn dma_state() -> &'static DmaState { 857 fn dma_state() -> &'static crate::usart::DmaState {
858 use core::sync::atomic::AtomicBool;
859
860 use embassy_sync::waitqueue::AtomicWaker;
861
862 use crate::usart::DmaState;
863
841 static STATE: DmaState = DmaState { 864 static STATE: DmaState = DmaState {
842 rx_err_waker: AtomicWaker::new(), 865 rx_err_waker: AtomicWaker::new(),
843 rx_err: AtomicBool::new(false), 866 rx_err: AtomicBool::new(false),
@@ -848,14 +871,6 @@ macro_rules! impl_instance {
848 fn instance_number() -> usize { 871 fn instance_number() -> usize {
849 $fc_num 872 $fc_num
850 } 873 }
851 #[inline]
852 fn tx_pin_func() -> PioFunc {
853 PioFunc::$tx_pin
854 }
855 #[inline]
856 fn rx_pin_func() -> PioFunc {
857 PioFunc::$rx_pin
858 }
859 } 874 }
860 impl $crate::usart::Instance for $crate::peripherals::$inst { 875 impl $crate::usart::Instance for $crate::peripherals::$inst {
861 type Interrupt = crate::interrupt::typelevel::$fc; 876 type Interrupt = crate::interrupt::typelevel::$fc;
@@ -863,73 +878,62 @@ macro_rules! impl_instance {
863 }; 878 };
864} 879}
865 880
866impl_instance!(USART0, FLEXCOMM0, ALT1, ALT1, 0); 881pub(crate) trait SealedTxPin<T: Instance>: crate::gpio::Pin {
867impl_instance!(USART1, FLEXCOMM1, ALT2, ALT2, 1); 882 fn pin_func(&self) -> PioFunc;
868impl_instance!(USART2, FLEXCOMM2, ALT1, ALT1, 2); 883}
869impl_instance!(USART3, FLEXCOMM3, ALT1, ALT1, 3); 884
870impl_instance!(USART4, FLEXCOMM4, ALT1, ALT2, 4); 885pub(crate) trait SealedRxPin<T: Instance>: crate::gpio::Pin {
871impl_instance!(USART5, FLEXCOMM5, ALT3, ALT3, 5); 886 fn pin_func(&self) -> PioFunc;
872impl_instance!(USART6, FLEXCOMM6, ALT2, ALT2, 6); 887}
873impl_instance!(USART7, FLEXCOMM7, ALT7, ALT7, 7);
874 888
875/// Trait for TX pins. 889/// Trait for TX pins.
876pub trait TxPin<T: Instance>: crate::gpio::Pin {} 890#[allow(private_bounds)]
891pub trait TxPin<T: Instance>: SealedTxPin<T> + crate::gpio::Pin {}
892
877/// Trait for RX pins. 893/// Trait for RX pins.
878pub trait RxPin<T: Instance>: crate::gpio::Pin {} 894#[allow(private_bounds)]
895pub trait RxPin<T: Instance>: SealedRxPin<T> + crate::gpio::Pin {}
896
897macro_rules! impl_usart_txd_pin {
898 ($pin:ident, $instance:ident, $func: ident) => {
899 impl crate::usart::SealedTxPin<crate::peripherals::$instance> for crate::peripherals::$pin {
900 fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc {
901 use crate::pac::iocon::vals::PioFunc;
902 PioFunc::$func
903 }
904 }
879 905
880macro_rules! impl_pin { 906 impl crate::usart::TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
881 ($pin:ident, $instance:ident, Tx) => {
882 impl TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
883 }; 907 };
884 ($pin:ident, $instance:ident, Rx) => { 908}
885 impl RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} 909
910macro_rules! impl_usart_rxd_pin {
911 ($pin:ident, $instance:ident, $func: ident) => {
912 impl crate::usart::SealedRxPin<crate::peripherals::$instance> for crate::peripherals::$pin {
913 fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc {
914 use crate::pac::iocon::vals::PioFunc;
915 PioFunc::$func
916 }
917 }
918
919 impl crate::usart::RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
886 }; 920 };
887} 921}
888 922
889impl_pin!(PIO1_6, USART0, Tx); 923/// Marker trait indicating a DMA channel may be used for USART transmit.
890impl_pin!(PIO1_5, USART0, Rx);
891impl_pin!(PIO1_11, USART1, Tx);
892impl_pin!(PIO1_10, USART1, Rx);
893impl_pin!(PIO0_27, USART2, Tx);
894impl_pin!(PIO1_24, USART2, Rx);
895impl_pin!(PIO0_2, USART3, Tx);
896impl_pin!(PIO0_3, USART3, Rx);
897impl_pin!(PIO0_16, USART4, Tx);
898impl_pin!(PIO0_5, USART4, Rx);
899impl_pin!(PIO0_9, USART5, Tx);
900impl_pin!(PIO0_8, USART5, Rx);
901impl_pin!(PIO1_16, USART6, Tx);
902impl_pin!(PIO1_13, USART6, Rx);
903impl_pin!(PIO0_19, USART7, Tx);
904impl_pin!(PIO0_20, USART7, Rx);
905
906/// Trait for TX DMA channels.
907pub trait TxChannel<T: Instance>: crate::dma::Channel {} 924pub trait TxChannel<T: Instance>: crate::dma::Channel {}
908/// Trait for RX DMA channels. 925
926/// Marker trait indicating a DMA channel may be used for USART recieve.
909pub trait RxChannel<T: Instance>: crate::dma::Channel {} 927pub trait RxChannel<T: Instance>: crate::dma::Channel {}
910 928
911macro_rules! impl_channel { 929macro_rules! impl_usart_tx_channel {
912 ($dma:ident, $instance:ident, Tx) => { 930 ($instance: ident, $channel: ident) => {
913 impl TxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {} 931 impl crate::usart::TxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {}
914 };
915 ($dma:ident, $instance:ident, Rx) => {
916 impl RxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {}
917 }; 932 };
918} 933}
919 934
920impl_channel!(DMA_CH4, USART0, Rx); 935macro_rules! impl_usart_rx_channel {
921impl_channel!(DMA_CH5, USART0, Tx); 936 ($instance: ident, $channel: ident) => {
922impl_channel!(DMA_CH6, USART1, Rx); 937 impl crate::usart::RxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {}
923impl_channel!(DMA_CH7, USART1, Tx); 938 };
924impl_channel!(DMA_CH10, USART2, Rx); 939}
925impl_channel!(DMA_CH11, USART2, Tx);
926impl_channel!(DMA_CH8, USART3, Rx);
927impl_channel!(DMA_CH9, USART3, Tx);
928impl_channel!(DMA_CH12, USART4, Rx);
929impl_channel!(DMA_CH13, USART4, Tx);
930impl_channel!(DMA_CH14, USART5, Rx);
931impl_channel!(DMA_CH15, USART5, Tx);
932impl_channel!(DMA_CH16, USART6, Rx);
933impl_channel!(DMA_CH17, USART6, Tx);
934impl_channel!(DMA_CH18, USART7, Rx);
935impl_channel!(DMA_CH19, USART7, Tx);