aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authori509VCB <[email protected]>2025-10-25 13:14:06 -0500
committeri509VCB <[email protected]>2025-11-16 22:04:12 -0500
commit21dd55b69ed2418f62a86185b52d6c7df9d6292b (patch)
tree6e3f752c0edb0fd854348c903ebc7f3213689bc4
parentc8c4c6f40bd8a2e548f3c8e06b798d448f67b884 (diff)
nxp: generate all chip peripherals and impls from metadata
-rw-r--r--embassy-nxp/CHANGELOG.md1
-rw-r--r--embassy-nxp/Cargo.toml4
-rw-r--r--embassy-nxp/build.rs353
-rw-r--r--embassy-nxp/src/chips/lpc55.rs127
-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.rs47
-rw-r--r--embassy-nxp/src/gpio/lpc55.rs93
-rw-r--r--embassy-nxp/src/gpio/rt1xxx.rs50
-rw-r--r--embassy-nxp/src/iomuxc.rs29
-rw-r--r--embassy-nxp/src/lib.rs16
-rw-r--r--embassy-nxp/src/pwm.rs2
-rw-r--r--embassy-nxp/src/pwm/lpc55.rs113
-rw-r--r--embassy-nxp/src/sct.rs56
-rw-r--r--embassy-nxp/src/usart.rs2
-rw-r--r--embassy-nxp/src/usart/lpc55.rs115
-rw-r--r--examples/lpc55s69/src/bin/pwm.rs2
-rw-r--r--examples/lpc55s69/src/bin/usart_async.rs4
19 files changed, 549 insertions, 843 deletions
diff --git a/embassy-nxp/CHANGELOG.md b/embassy-nxp/CHANGELOG.md
index 39f5c75bd..e6f117da4 100644
--- a/embassy-nxp/CHANGELOG.md
+++ b/embassy-nxp/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7 7
8<!-- next-header --> 8<!-- next-header -->
9## Unreleased - ReleaseDate 9## Unreleased - ReleaseDate
10- Codegen using `nxp-pac` metadata
10- LPC55: PWM simple 11- LPC55: PWM simple
11- LPC55: Move ALT definitions for USART to TX/RX pin impls. 12- LPC55: Move ALT definitions for USART to TX/RX pin impls.
12- LPC55: Remove internal match_iocon macro 13- LPC55: Remove internal match_iocon macro
diff --git a/embassy-nxp/Cargo.toml b/embassy-nxp/Cargo.toml
index f8c63ba29..b78c26c77 100644
--- a/embassy-nxp/Cargo.toml
+++ b/embassy-nxp/Cargo.toml
@@ -38,13 +38,13 @@ embassy-time-queue-utils = { version = "0.3.0", path = "../embassy-time-queue-ut
38embedded-io = "0.6.1" 38embedded-io = "0.6.1"
39embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 39embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
40## Chip dependencies 40## Chip dependencies
41nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "477dfdbfd5e6c75c0730c56494b601c1b2257263"} 41nxp-pac = { version = "0.1.0", optional = true, git = "https://github.com/i509VCB/nxp-pac", rev = "af5122e1cbe1483833c5d2e5af96b26a34ed5d62"}
42 42
43imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] } 43imxrt-rt = { version = "0.1.7", optional = true, features = ["device"] }
44 44
45[build-dependencies] 45[build-dependencies]
46cfg_aliases = "0.2.1" 46cfg_aliases = "0.2.1"
47nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "477dfdbfd5e6c75c0730c56494b601c1b2257263", features = ["metadata"], optional = true } 47nxp-pac = { version = "0.1.0", git = "https://github.com/i509VCB/nxp-pac", rev = "af5122e1cbe1483833c5d2e5af96b26a34ed5d62", features = ["metadata"], optional = true }
48proc-macro2 = "1.0.95" 48proc-macro2 = "1.0.95"
49quote = "1.0.15" 49quote = "1.0.15"
50 50
diff --git a/embassy-nxp/build.rs b/embassy-nxp/build.rs
index f3c062c87..f53c29161 100644
--- a/embassy-nxp/build.rs
+++ b/embassy-nxp/build.rs
@@ -4,10 +4,12 @@ use std::process::Command;
4use std::{env, fs}; 4use std::{env, fs};
5 5
6use cfg_aliases::cfg_aliases; 6use cfg_aliases::cfg_aliases;
7#[cfg(feature = "_rt1xxx")]
8use nxp_pac::metadata; 7use nxp_pac::metadata;
8use nxp_pac::metadata::{METADATA, Peripheral};
9#[allow(unused)] 9#[allow(unused)]
10use proc_macro2::TokenStream; 10use proc_macro2::TokenStream;
11use proc_macro2::{Ident, Literal, Span};
12use quote::format_ident;
11#[allow(unused)] 13#[allow(unused)]
12use quote::quote; 14use quote::quote;
13 15
@@ -31,56 +33,188 @@ fn main() {
31 .unwrap() 33 .unwrap()
32 .to_ascii_lowercase(); 34 .to_ascii_lowercase();
33 35
36 let singletons = singletons(&mut cfgs);
37
34 cfg_aliases! { 38 cfg_aliases! {
35 rt1xxx: { any(feature = "mimxrt1011", feature = "mimxrt1062") }, 39 rt1xxx: { any(feature = "mimxrt1011", feature = "mimxrt1062") },
36 gpio1: { any(feature = "mimxrt1011", feature = "mimxrt1062") },
37 gpio2: { any(feature = "mimxrt1011", feature = "mimxrt1062") },
38 gpio3: { feature = "mimxrt1062" },
39 gpio4: { feature = "mimxrt1062" },
40 gpio5: { any(feature = "mimxrt1011", feature = "mimxrt1062") },
41 } 40 }
42 41
43 eprintln!("chip: {chip_name}"); 42 eprintln!("chip: {chip_name}");
44 43
45 generate_code(); 44 generate_code(&mut cfgs, &singletons);
46} 45}
47 46
48#[cfg(feature = "_rt1xxx")] 47/// A peripheral singleton returned by `embassy_nxp::init`.
49fn generate_iomuxc() -> TokenStream { 48struct Singleton {
50 use proc_macro2::{Ident, Span}; 49 name: String,
51 50
52 let pads = metadata::iomuxc::IOMUXC_REGISTERS.iter().map(|registers| { 51 /// A cfg guard which indicates whether the `Peripherals` struct will give the user this singleton.
53 let name = Ident::new(&registers.name, Span::call_site()); 52 cfg: Option<TokenStream>,
54 let address = registers.pad_ctl; 53}
55 54
56 quote! { 55fn singletons(cfgs: &mut common::CfgSet) -> Vec<Singleton> {
57 pub const #name: u32 = #address; 56 let mut singletons = Vec::new();
57
58 for peripheral in METADATA.peripherals {
59 // GPIO and DMA are generated in a 2nd pass.
60 let skip_singleton = if peripheral.name.starts_with("GPIO") || peripheral.name.starts_with("DMA") {
61 true
62 } else {
63 false
64 };
65
66 if !skip_singleton {
67 singletons.push(Singleton {
68 name: peripheral.name.into(),
69 cfg: None,
70 });
58 } 71 }
59 }); 72 }
60 73
61 let muxes = metadata::iomuxc::IOMUXC_REGISTERS.iter().map(|registers| { 74 cfgs.declare_all(&[
62 let name = Ident::new(&registers.name, Span::call_site()); 75 "gpio1",
63 let address = registers.mux_ctl; 76 "gpio1_hi",
77 "gpio2",
78 "gpio2_hi",
79 "gpio3",
80 "gpio3_hi",
81 "gpio4",
82 "gpio4_hi",
83 "gpio5",
84 "gpio5_hi",
85 "gpio10",
86 "gpio10_hi",
87 ]);
64 88
65 quote! { 89 for peripheral in METADATA.peripherals.iter().filter(|p| p.name.starts_with("GPIO")) {
66 pub const #name: u32 = #address; 90 let number = peripheral.name.strip_prefix("GPIO").unwrap();
91 assert!(number.parse::<u8>().is_ok());
92 cfgs.enable(format!("gpio{}", number));
93
94 for signal in peripheral.signals.iter() {
95 let pin_number = signal.name.parse::<u8>().unwrap();
96
97 if pin_number > 15 {
98 cfgs.enable(format!("gpio{}_hi", number));
99 }
100
101 // GPIO signals only defined a single signal, on a single pin.
102 assert_eq!(signal.pins.len(), 1);
103
104 singletons.push(Singleton {
105 name: signal.pins[0].pin.into(),
106 cfg: None,
107 });
108 }
109 }
110
111 for peripheral in METADATA.peripherals.iter().filter(|p| p.name.starts_with("DMA")) {
112 let instance = peripheral.name.strip_prefix("DMA").unwrap();
113 assert!(instance.parse::<u8>().is_ok());
114
115 for signal in peripheral.signals.iter() {
116 let channel_number = signal.name.parse::<u8>().unwrap();
117 let name = format!("DMA{instance}_CH{channel_number}");
118
119 // DMA has no pins.
120 assert!(signal.pins.is_empty());
121
122 singletons.push(Singleton { name, cfg: None });
123 }
124 }
125
126 for peripheral in METADATA.peripherals.iter().filter(|p| p.name.starts_with("SCT")) {
127 let instance = peripheral.name.strip_prefix("SCT").unwrap();
128 assert!(instance.parse::<u8>().is_ok());
129
130 for signal in peripheral.signals.iter() {
131 if !signal.name.starts_with("OUT") {
132 continue;
133 }
134
135 let channel_number = signal.name.strip_prefix("OUT").unwrap().parse::<u8>().unwrap();
136 let name = format!("SCT{instance}_OUT{channel_number}");
137
138 singletons.push(Singleton { name, cfg: None });
67 } 139 }
140 }
141
142 singletons
143}
144
145#[cfg(feature = "_rt1xxx")]
146fn generate_iomuxc() -> TokenStream {
147 let iomuxc_pad_impls = metadata::METADATA
148 .pins
149 .iter()
150 .filter(|p| p.iomuxc.as_ref().filter(|i| i.mux.is_some()).is_some())
151 .map(|pin| {
152 let Some(ref iomuxc) = pin.iomuxc else {
153 panic!("Pin {} has no IOMUXC definitions", pin.name);
154 };
155
156 let name = Ident::new(pin.name, Span::call_site());
157 let mux = iomuxc.mux.unwrap();
158 let pad = iomuxc.pad;
159
160 quote! {
161 impl_iomuxc_pad!(#name, #pad, #mux);
162 }
163 });
164
165 let base_match_arms = metadata::METADATA
166 .peripherals
167 .iter()
168 .filter(|p| p.name.starts_with("GPIO"))
169 .map(|peripheral| {
170 peripheral.signals.iter().map(|signal| {
171 // All GPIO signals have a single pin.
172 let pin = &signal.pins[0];
173 let instance = peripheral.name.strip_prefix("GPIO").unwrap();
174 let bank_match = format_ident!("Gpio{}", instance);
175 let pin_number = signal.name.parse::<u8>().unwrap();
176 let pin_ident = Ident::new(pin.pin, Span::call_site());
177
178 quote! {
179 (Bank::#bank_match, #pin_number) => <crate::peripherals::#pin_ident as crate::iomuxc::SealedPad>
180 }
181 })
182 })
183 .flatten()
184 .collect::<Vec<_>>();
185
186 let pad_match_arms = base_match_arms.iter().map(|arm| {
187 quote! { #arm::PAD }
188 });
189
190 let mux_match_arms = base_match_arms.iter().map(|arm| {
191 quote! { #arm::MUX }
68 }); 192 });
69 193
70 quote! { 194 quote! {
71 pub mod iomuxc { 195 #(#iomuxc_pad_impls)*
72 pub mod pads { 196
73 #(#pads)* 197 pub(crate) fn iomuxc_pad(bank: crate::gpio::Bank, pin: u8) -> *mut () {
198 use crate::gpio::Bank;
199
200 match (bank, pin) {
201 #(#pad_match_arms),*,
202 _ => unreachable!()
74 } 203 }
204 }
205
206 pub(crate) fn iomuxc_mux(bank: crate::gpio::Bank, pin: u8) -> Option<*mut ()> {
207 use crate::gpio::Bank;
75 208
76 pub mod muxes { 209 match (bank, pin) {
77 #(#muxes)* 210 #(#mux_match_arms),*,
211 _ => unreachable!()
78 } 212 }
79 } 213 }
80 } 214 }
81} 215}
82 216
83fn generate_code() { 217fn generate_code(cfgs: &mut common::CfgSet, singletons: &[Singleton]) {
84 #[allow(unused)] 218 #[allow(unused)]
85 use std::fmt::Write; 219 use std::fmt::Write;
86 220
@@ -88,14 +222,179 @@ fn generate_code() {
88 #[allow(unused_mut)] 222 #[allow(unused_mut)]
89 let mut output = String::new(); 223 let mut output = String::new();
90 224
225 writeln!(&mut output, "{}", peripherals(singletons)).unwrap();
226
91 #[cfg(feature = "_rt1xxx")] 227 #[cfg(feature = "_rt1xxx")]
92 writeln!(&mut output, "{}", generate_iomuxc()).unwrap(); 228 writeln!(&mut output, "{}", generate_iomuxc()).unwrap();
93 229
230 writeln!(&mut output, "{}", interrupts()).unwrap();
231 writeln!(&mut output, "{}", impl_peripherals(cfgs, singletons)).unwrap();
232
94 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); 233 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
95 fs::write(&out_file, output).unwrap(); 234 fs::write(&out_file, output).unwrap();
96 rustfmt(&out_file); 235 rustfmt(&out_file);
97} 236}
98 237
238fn interrupts() -> TokenStream {
239 let interrupts = METADATA.interrupts.iter().map(|interrupt| format_ident!("{interrupt}"));
240
241 quote! {
242 embassy_hal_internal::interrupt_mod!(#(#interrupts),*);
243 }
244}
245
246fn peripherals(singletons: &[Singleton]) -> TokenStream {
247 let defs = singletons.iter().map(|s| {
248 let ident = Ident::new(&s.name, Span::call_site());
249 quote! { #ident }
250 });
251
252 let peripherals = singletons.iter().map(|s| {
253 let ident = Ident::new(&s.name, Span::call_site());
254 let cfg = s.cfg.clone().unwrap_or_else(|| quote! {});
255 quote! {
256 #cfg
257 #ident
258 }
259 });
260
261 quote! {
262 embassy_hal_internal::peripherals_definition!(#(#defs),*);
263 embassy_hal_internal::peripherals_struct!(#(#peripherals),*);
264 }
265}
266
267fn impl_gpio_pin(impls: &mut Vec<TokenStream>, peripheral: &Peripheral) {
268 let instance = peripheral.name.strip_prefix("GPIO").unwrap();
269 let bank = format_ident!("Gpio{}", instance);
270 // let pin =
271
272 for signal in peripheral.signals.iter() {
273 let pin_number = signal.name.parse::<u8>().unwrap();
274 let pin = Ident::new(signal.pins[0].pin, Span::call_site());
275
276 impls.push(quote! {
277 impl_pin!(#pin, #bank, #pin_number);
278 });
279 }
280}
281
282fn impl_dma_channel(impls: &mut Vec<TokenStream>, peripheral: &Peripheral) {
283 let instance = Ident::new(peripheral.name, Span::call_site());
284
285 for signal in peripheral.signals.iter() {
286 let channel_number = signal.name.parse::<u8>().unwrap();
287 let channel_name = format_ident!("{instance}_CH{channel_number}");
288
289 impls.push(quote! {
290 impl_dma_channel!(#instance, #channel_name, #channel_number);
291 });
292 }
293}
294
295fn impl_usart(impls: &mut Vec<TokenStream>, peripheral: &Peripheral) {
296 let instance = Ident::new(peripheral.name, Span::call_site());
297 let flexcomm = Ident::new(
298 peripheral.flexcomm.expect("LPC55 must specify FLEXCOMM instance"),
299 Span::call_site(),
300 );
301 let number = Literal::u8_unsuffixed(peripheral.name.strip_prefix("USART").unwrap().parse::<u8>().unwrap());
302
303 impls.push(quote! {
304 impl_usart_instance!(#instance, #flexcomm, #number);
305 });
306
307 for signal in peripheral.signals {
308 let r#macro = match signal.name {
309 "TXD" => format_ident!("impl_usart_txd_pin"),
310 "RXD" => format_ident!("impl_usart_rxd_pin"),
311 _ => unreachable!(),
312 };
313
314 for pin in signal.pins {
315 let alt = format_ident!("ALT{}", pin.alt);
316 let pin = format_ident!("{}", pin.pin);
317
318 impls.push(quote! {
319 #r#macro!(#pin, #instance, #alt);
320 });
321 }
322 }
323
324 for dma_mux in peripheral.dma_muxing {
325 assert_eq!(dma_mux.mux, "DMA0", "TODO: USART for more than LPC55");
326
327 let r#macro = match dma_mux.signal {
328 "TX" => format_ident!("impl_usart_tx_channel"),
329 "RX" => format_ident!("impl_usart_rx_channel"),
330 _ => unreachable!(),
331 };
332
333 let channel = format_ident!("DMA0_CH{}", dma_mux.request);
334
335 impls.push(quote! {
336 #r#macro!(#instance, #channel);
337 });
338 }
339}
340
341fn impl_sct(impls: &mut Vec<TokenStream>, peripheral: &Peripheral) {
342 let instance = Ident::new(peripheral.name, Span::call_site());
343
344 impls.push(quote! {
345 impl_sct_instance!(#instance);
346 });
347
348 for signal in peripheral.signals.iter() {
349 if signal.name.starts_with("OUT") {
350 let channel_number = signal.name.strip_prefix("OUT").unwrap().parse::<u8>().unwrap();
351
352 let channel_name = format_ident!("{instance}_OUT{channel_number}");
353
354 impls.push(quote! {
355 impl_sct_output_instance!(#instance, #channel_name, #channel_number);
356 });
357
358 if signal.name.starts_with("OUT") {
359 for pin in signal.pins {
360 let pin_name = format_ident!("{}", pin.pin);
361 let alt = format_ident!("ALT{}", pin.alt);
362
363 impls.push(quote! {
364 impl_sct_output_pin!(#instance, #channel_name, #pin_name, #alt);
365 });
366 }
367 }
368 }
369 }
370}
371
372fn impl_peripherals(_cfgs: &mut common::CfgSet, _singletons: &[Singleton]) -> TokenStream {
373 let mut impls = Vec::new();
374
375 for peripheral in metadata::METADATA.peripherals.iter() {
376 if peripheral.name.starts_with("GPIO") {
377 impl_gpio_pin(&mut impls, peripheral);
378 }
379
380 if peripheral.name.starts_with("DMA") {
381 impl_dma_channel(&mut impls, peripheral);
382 }
383
384 if peripheral.name.starts_with("USART") {
385 impl_usart(&mut impls, peripheral);
386 }
387
388 if peripheral.name.starts_with("SCT") {
389 impl_sct(&mut impls, peripheral);
390 }
391 }
392
393 quote! {
394 #(#impls)*
395 }
396}
397
99/// rustfmt a given path. 398/// rustfmt a given path.
100/// Failures are logged to stderr and ignored. 399/// Failures are logged to stderr and ignored.
101fn rustfmt(path: impl AsRef<Path>) { 400fn rustfmt(path: impl AsRef<Path>) {
diff --git a/embassy-nxp/src/chips/lpc55.rs b/embassy-nxp/src/chips/lpc55.rs
index e9addddb6..7967e07d1 100644
--- a/embassy-nxp/src/chips/lpc55.rs
+++ b/embassy-nxp/src/chips/lpc55.rs
@@ -1,121 +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 // Pulse-Width Modulation Outputs.
101 PWM_OUTPUT0,
102 PWM_OUTPUT1,
103 PWM_OUTPUT2,
104 PWM_OUTPUT3,
105 PWM_OUTPUT4,
106 PWM_OUTPUT5,
107 PWM_OUTPUT6,
108 PWM_OUTPUT7,
109 PWM_OUTPUT8,
110 PWM_OUTPUT9,
111
112 // Universal Synchronous/Asynchronous Receiver/Transmitter (USART) instances.
113 USART0,
114 USART1,
115 USART2,
116 USART3,
117 USART4,
118 USART5,
119 USART6,
120 USART7
121} 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 5bd763f03..623644bf1 100644
--- a/embassy-nxp/src/dma/lpc55.rs
+++ b/embassy-nxp/src/dma/lpc55.rs
@@ -1,3 +1,5 @@
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;
@@ -9,9 +11,12 @@ use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_hal_internal::{PeripheralType, impl_peripheral}; 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::{Peri, peripherals}; 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/gpio/lpc55.rs b/embassy-nxp/src/gpio/lpc55.rs
index 6039d8ca8..6be405463 100644
--- a/embassy-nxp/src/gpio/lpc55.rs
+++ b/embassy-nxp/src/gpio/lpc55.rs
@@ -1,9 +1,11 @@
1#![macro_use]
2
1use embassy_hal_internal::{PeripheralType, impl_peripheral}; 3use embassy_hal_internal::{PeripheralType, impl_peripheral};
2 4
5use crate::Peri;
3use crate::pac::common::{RW, Reg}; 6use crate::pac::common::{RW, Reg};
4use crate::pac::iocon::vals::{PioDigimode, PioMode}; 7use crate::pac::iocon::vals::{PioDigimode, PioMode};
5use crate::pac::{GPIO, IOCON, SYSCON, iocon}; 8use crate::pac::{GPIO, IOCON, SYSCON, iocon};
6use crate::{Peri, peripherals};
7 9
8pub(crate) fn init() { 10pub(crate) fn init() {
9 // Enable clocks for GPIO, PINT, and IOCON 11 // Enable clocks for GPIO, PINT, and IOCON
@@ -39,8 +41,8 @@ pub enum Pull {
39/// 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.
40#[derive(Debug, Eq, PartialEq, Clone, Copy)] 42#[derive(Debug, Eq, PartialEq, Clone, Copy)]
41pub enum Bank { 43pub enum Bank {
42 Bank0 = 0, 44 Gpio0 = 0,
43 Bank1 = 1, 45 Gpio1 = 1,
44} 46}
45 47
46/// GPIO output driver. Internally, this is a specialized [Flex] pin. 48/// GPIO output driver. Internally, this is a specialized [Flex] pin.
@@ -228,8 +230,8 @@ pub(crate) trait SealedPin: Sized {
228 #[inline] 230 #[inline]
229 fn pio(&self) -> Reg<iocon::regs::Pio, RW> { 231 fn pio(&self) -> Reg<iocon::regs::Pio, RW> {
230 match self.pin_bank() { 232 match self.pin_bank() {
231 Bank::Bank0 => IOCON.pio0(self.pin_number() as usize), 233 Bank::Gpio0 => IOCON.pio0(self.pin_number() as usize),
232 Bank::Bank1 => IOCON.pio1(self.pin_number() as usize), 234 Bank::Gpio1 => IOCON.pio1(self.pin_number() as usize),
233 } 235 }
234 } 236 }
235} 237}
@@ -254,8 +256,8 @@ pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
254 256
255/// Type-erased GPIO pin. 257/// Type-erased GPIO pin.
256pub struct AnyPin { 258pub struct AnyPin {
257 pin_bank: Bank, 259 pub(crate) pin_bank: Bank,
258 pin_number: u8, 260 pub(crate) pin_number: u8,
259} 261}
260 262
261impl AnyPin { 263impl AnyPin {
@@ -285,12 +287,12 @@ impl SealedPin for AnyPin {
285} 287}
286 288
287macro_rules! impl_pin { 289macro_rules! impl_pin {
288 ($name:ident, $bank:expr, $pin_num:expr) => { 290 ($name:ident, $bank:ident, $pin_num:expr) => {
289 impl Pin for peripherals::$name {} 291 impl crate::gpio::Pin for peripherals::$name {}
290 impl SealedPin for peripherals::$name { 292 impl crate::gpio::SealedPin for peripherals::$name {
291 #[inline] 293 #[inline]
292 fn pin_bank(&self) -> Bank { 294 fn pin_bank(&self) -> crate::gpio::Bank {
293 $bank 295 crate::gpio::Bank::$bank
294 } 296 }
295 297
296 #[inline] 298 #[inline]
@@ -301,6 +303,8 @@ macro_rules! impl_pin {
301 303
302 impl From<peripherals::$name> for crate::gpio::AnyPin { 304 impl From<peripherals::$name> for crate::gpio::AnyPin {
303 fn from(val: peripherals::$name) -> Self { 305 fn from(val: peripherals::$name) -> Self {
306 use crate::gpio::SealedPin;
307
304 Self { 308 Self {
305 pin_bank: val.pin_bank(), 309 pin_bank: val.pin_bank(),
306 pin_number: val.pin_number(), 310 pin_number: val.pin_number(),
@@ -309,68 +313,3 @@ macro_rules! impl_pin {
309 } 313 }
310 }; 314 };
311} 315}
312
313impl_pin!(PIO0_0, Bank::Bank0, 0);
314impl_pin!(PIO0_1, Bank::Bank0, 1);
315impl_pin!(PIO0_2, Bank::Bank0, 2);
316impl_pin!(PIO0_3, Bank::Bank0, 3);
317impl_pin!(PIO0_4, Bank::Bank0, 4);
318impl_pin!(PIO0_5, Bank::Bank0, 5);
319impl_pin!(PIO0_6, Bank::Bank0, 6);
320impl_pin!(PIO0_7, Bank::Bank0, 7);
321impl_pin!(PIO0_8, Bank::Bank0, 8);
322impl_pin!(PIO0_9, Bank::Bank0, 9);
323impl_pin!(PIO0_10, Bank::Bank0, 10);
324impl_pin!(PIO0_11, Bank::Bank0, 11);
325impl_pin!(PIO0_12, Bank::Bank0, 12);
326impl_pin!(PIO0_13, Bank::Bank0, 13);
327impl_pin!(PIO0_14, Bank::Bank0, 14);
328impl_pin!(PIO0_15, Bank::Bank0, 15);
329impl_pin!(PIO0_16, Bank::Bank0, 16);
330impl_pin!(PIO0_17, Bank::Bank0, 17);
331impl_pin!(PIO0_18, Bank::Bank0, 18);
332impl_pin!(PIO0_19, Bank::Bank0, 19);
333impl_pin!(PIO0_20, Bank::Bank0, 20);
334impl_pin!(PIO0_21, Bank::Bank0, 21);
335impl_pin!(PIO0_22, Bank::Bank0, 22);
336impl_pin!(PIO0_23, Bank::Bank0, 23);
337impl_pin!(PIO0_24, Bank::Bank0, 24);
338impl_pin!(PIO0_25, Bank::Bank0, 25);
339impl_pin!(PIO0_26, Bank::Bank0, 26);
340impl_pin!(PIO0_27, Bank::Bank0, 27);
341impl_pin!(PIO0_28, Bank::Bank0, 28);
342impl_pin!(PIO0_29, Bank::Bank0, 29);
343impl_pin!(PIO0_30, Bank::Bank0, 30);
344impl_pin!(PIO0_31, Bank::Bank0, 31);
345impl_pin!(PIO1_0, Bank::Bank1, 0);
346impl_pin!(PIO1_1, Bank::Bank1, 1);
347impl_pin!(PIO1_2, Bank::Bank1, 2);
348impl_pin!(PIO1_3, Bank::Bank1, 3);
349impl_pin!(PIO1_4, Bank::Bank1, 4);
350impl_pin!(PIO1_5, Bank::Bank1, 5);
351impl_pin!(PIO1_6, Bank::Bank1, 6);
352impl_pin!(PIO1_7, Bank::Bank1, 7);
353impl_pin!(PIO1_8, Bank::Bank1, 8);
354impl_pin!(PIO1_9, Bank::Bank1, 9);
355impl_pin!(PIO1_10, Bank::Bank1, 10);
356impl_pin!(PIO1_11, Bank::Bank1, 11);
357impl_pin!(PIO1_12, Bank::Bank1, 12);
358impl_pin!(PIO1_13, Bank::Bank1, 13);
359impl_pin!(PIO1_14, Bank::Bank1, 14);
360impl_pin!(PIO1_15, Bank::Bank1, 15);
361impl_pin!(PIO1_16, Bank::Bank1, 16);
362impl_pin!(PIO1_17, Bank::Bank1, 17);
363impl_pin!(PIO1_18, Bank::Bank1, 18);
364impl_pin!(PIO1_19, Bank::Bank1, 19);
365impl_pin!(PIO1_20, Bank::Bank1, 20);
366impl_pin!(PIO1_21, Bank::Bank1, 21);
367impl_pin!(PIO1_22, Bank::Bank1, 22);
368impl_pin!(PIO1_23, Bank::Bank1, 23);
369impl_pin!(PIO1_24, Bank::Bank1, 24);
370impl_pin!(PIO1_25, Bank::Bank1, 25);
371impl_pin!(PIO1_26, Bank::Bank1, 26);
372impl_pin!(PIO1_27, Bank::Bank1, 27);
373impl_pin!(PIO1_28, Bank::Bank1, 28);
374impl_pin!(PIO1_29, Bank::Bank1, 29);
375impl_pin!(PIO1_30, Bank::Bank1, 30);
376impl_pin!(PIO1_31, Bank::Bank1, 31);
diff --git a/embassy-nxp/src/gpio/rt1xxx.rs b/embassy-nxp/src/gpio/rt1xxx.rs
index c4dc110ff..8a560310c 100644
--- a/embassy-nxp/src/gpio/rt1xxx.rs
+++ b/embassy-nxp/src/gpio/rt1xxx.rs
@@ -10,7 +10,7 @@ use 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::{RW, Reg}; 14use crate::pac::common::{RW, Reg};
15use crate::pac::gpio::Gpio; 15use crate::pac::gpio::Gpio;
16#[cfg(feature = "rt")] 16#[cfg(feature = "rt")]
@@ -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 4058881a5..4c3dbebb9 100644
--- a/embassy-nxp/src/lib.rs
+++ b/embassy-nxp/src/lib.rs
@@ -12,8 +12,13 @@ pub mod pint;
12#[cfg(feature = "lpc55-core0")] 12#[cfg(feature = "lpc55-core0")]
13pub mod pwm; 13pub mod pwm;
14#[cfg(feature = "lpc55-core0")] 14#[cfg(feature = "lpc55-core0")]
15pub mod sct;
16#[cfg(feature = "lpc55-core0")]
15pub mod usart; 17pub mod usart;
16 18
19#[cfg(rt1xxx)]
20mod iomuxc;
21
17#[cfg(feature = "_time_driver")] 22#[cfg(feature = "_time_driver")]
18#[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")] 23#[cfg_attr(feature = "time-driver-pit", path = "time_driver/pit.rs")]
19#[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")] 24#[cfg_attr(feature = "time-driver-rtc", path = "time_driver/rtc.rs")]
@@ -25,15 +30,12 @@ mod time_driver;
25#[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")] 30#[cfg_attr(feature = "mimxrt1062", path = "chips/mimxrt1062.rs")]
26mod chip; 31mod chip;
27 32
28// TODO: Remove when this module is implemented for other chips 33pub use chip::{Peripherals, interrupt, peripherals};
29#[cfg(feature = "lpc55-core0")] 34pub use embassy_hal_internal::{Peri, PeripheralType};
30pub use chip::interrupt;
31#[cfg(feature = "unstable-pac")] 35#[cfg(feature = "unstable-pac")]
32pub use chip::pac; 36pub use nxp_pac as pac;
33#[cfg(not(feature = "unstable-pac"))] 37#[cfg(not(feature = "unstable-pac"))]
34pub(crate) use chip::pac; 38pub(crate) use nxp_pac as pac;
35pub use chip::{Peripherals, peripherals};
36pub use embassy_hal_internal::{Peri, PeripheralType};
37 39
38/// Macro to bind interrupts to handlers. 40/// Macro to bind interrupts to handlers.
39/// (Copied from `embassy-rp`) 41/// (Copied from `embassy-rp`)
diff --git a/embassy-nxp/src/pwm.rs b/embassy-nxp/src/pwm.rs
index 68980924a..c87a39c34 100644
--- a/embassy-nxp/src/pwm.rs
+++ b/embassy-nxp/src/pwm.rs
@@ -1,3 +1,5 @@
1#![macro_use]
2
1//! Pulse-Width Modulation (PWM) driver. 3//! Pulse-Width Modulation (PWM) driver.
2 4
3#[cfg_attr(feature = "lpc55-core0", path = "./pwm/lpc55.rs")] 5#[cfg_attr(feature = "lpc55-core0", path = "./pwm/lpc55.rs")]
diff --git a/embassy-nxp/src/pwm/lpc55.rs b/embassy-nxp/src/pwm/lpc55.rs
index 197184ad6..4cdbd8526 100644
--- a/embassy-nxp/src/pwm/lpc55.rs
+++ b/embassy-nxp/src/pwm/lpc55.rs
@@ -1,12 +1,15 @@
1#![macro_use]
2
1use core::sync::atomic::{AtomicU8, AtomicU32, Ordering}; 3use core::sync::atomic::{AtomicU8, AtomicU32, Ordering};
2 4
3use embassy_hal_internal::{Peri, PeripheralType}; 5use embassy_hal_internal::Peri;
4 6
5use crate::gpio::AnyPin; 7use crate::gpio::AnyPin;
6use crate::pac::iocon::vals::{PioDigimode, PioFunc, PioMode, PioOd, PioSlew}; 8use crate::pac::iocon::vals::{PioDigimode, PioMode, PioOd, PioSlew};
7use crate::pac::sct0::vals; 9use crate::pac::sct0::vals;
8use crate::pac::syscon::vals::{SctRst, SctclkselSel}; 10use crate::pac::syscon::vals::{SctRst, SctclkselSel};
9use crate::pac::{SCT0, SYSCON}; 11use crate::pac::{SCT0, SYSCON};
12use crate::sct;
10 13
11// Since for now the counter is shared, the TOP value has to be kept. 14// Since for now the counter is shared, the TOP value has to be kept.
12static TOP_VALUE: AtomicU32 = AtomicU32::new(0); 15static TOP_VALUE: AtomicU32 = AtomicU32::new(0);
@@ -75,7 +78,11 @@ impl<'d> Pwm<'d> {
75 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::ASSERTED)); 78 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::ASSERTED));
76 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::RELEASED)); 79 SYSCON.presetctrl1().modify(|w| w.set_sct_rst(SctRst::RELEASED));
77 } 80 }
78 fn new_inner<T: Output>(output: usize, channel: Peri<'d, impl OutputChannelPin<T>>, config: Config) -> Self { 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 {
79 // Enable clocks (Syscon is enabled by default) 86 // Enable clocks (Syscon is enabled by default)
80 critical_section::with(|_cs| { 87 critical_section::with(|_cs| {
81 if !SYSCON.ahbclkctrl0().read().iocon() { 88 if !SYSCON.ahbclkctrl0().read().iocon() {
@@ -109,12 +116,12 @@ impl<'d> Pwm<'d> {
109 116
110 /// Create PWM driver with a single 'a' pin as output. 117 /// Create PWM driver with a single 'a' pin as output.
111 #[inline] 118 #[inline]
112 pub fn new_output<T: Output>( 119 pub fn new_output<T: sct::Instance, O: sct::Output<T>>(
113 output: Peri<'d, T>, 120 output: Peri<'d, O>,
114 channel: Peri<'d, impl OutputChannelPin<T>>, 121 channel: Peri<'d, impl sct::OutputPin<T, O>>,
115 config: Config, 122 config: Config,
116 ) -> Self { 123 ) -> Self {
117 Self::new_inner(output.number(), channel, config) 124 Self::new_inner::<T, O>(output.number(), channel, config)
118 } 125 }
119 126
120 /// Set the PWM config. 127 /// Set the PWM config.
@@ -196,18 +203,18 @@ impl<'d> Pwm<'d> {
196 // TODO(frihetselsker): optimize nxp-pac so that `set_clr` and `set_set` are turned into a bit array. 203 // TODO(frihetselsker): optimize nxp-pac so that `set_clr` and `set_set` are turned into a bit array.
197 if config.invert { 204 if config.invert {
198 // Low when event 0 is active 205 // Low when event 0 is active
199 SCT0.out(output_number).out_clr().modify(|w| w.set_clr(1 << 0)); 206 SCT0.out(output_number).out_clr().modify(|w| w.set_clr(0, true));
200 // High when event `output_number + 1` is active 207 // High when event `output_number + 1` is active
201 SCT0.out(output_number) 208 SCT0.out(output_number)
202 .out_set() 209 .out_set()
203 .modify(|w| w.set_set(1 << (output_number + 1))); 210 .modify(|w| w.set_set(output_number, true));
204 } else { 211 } else {
205 // High when event 0 is active 212 // High when event 0 is active
206 SCT0.out(output_number).out_set().modify(|w| w.set_set(1 << 0)); 213 SCT0.out(output_number).out_set().modify(|w| w.set_set(0, true));
207 // Low when event `output_number + 1` is active 214 // Low when event `output_number + 1` is active
208 SCT0.out(output_number) 215 SCT0.out(output_number)
209 .out_clr() 216 .out_clr()
210 .modify(|w| w.set_clr(1 << (output_number + 1))); 217 .modify(|w| w.set_clr(output_number, true));
211 } 218 }
212 219
213 if config.phase_correct { 220 if config.phase_correct {
@@ -239,87 +246,3 @@ impl<'d> Drop for Pwm<'d> {
239 } 246 }
240 } 247 }
241} 248}
242
243trait SealedOutput {
244 /// Output number.
245 fn number(&self) -> usize;
246}
247
248/// PWM Output.
249#[allow(private_bounds)]
250pub trait Output: PeripheralType + SealedOutput {}
251
252macro_rules! output {
253 ($name:ident, $num:expr) => {
254 impl SealedOutput for crate::peripherals::$name {
255 fn number(&self) -> usize {
256 $num
257 }
258 }
259 impl Output for crate::peripherals::$name {}
260 };
261}
262
263output!(PWM_OUTPUT0, 0);
264output!(PWM_OUTPUT1, 1);
265output!(PWM_OUTPUT2, 2);
266output!(PWM_OUTPUT3, 3);
267output!(PWM_OUTPUT4, 4);
268output!(PWM_OUTPUT5, 5);
269output!(PWM_OUTPUT6, 6);
270output!(PWM_OUTPUT7, 7);
271output!(PWM_OUTPUT8, 8);
272output!(PWM_OUTPUT9, 9);
273
274/// PWM Output Channel.
275pub trait OutputChannelPin<T: Output>: crate::gpio::Pin {
276 fn pin_func(&self) -> PioFunc;
277}
278
279macro_rules! impl_pin {
280 ($pin:ident, $output:ident, $func:ident) => {
281 impl crate::pwm::inner::OutputChannelPin<crate::peripherals::$output> for crate::peripherals::$pin {
282 fn pin_func(&self) -> PioFunc {
283 PioFunc::$func
284 }
285 }
286 };
287}
288
289impl_pin!(PIO0_2, PWM_OUTPUT0, ALT3);
290impl_pin!(PIO0_17, PWM_OUTPUT0, ALT4);
291impl_pin!(PIO1_4, PWM_OUTPUT0, ALT4);
292impl_pin!(PIO1_23, PWM_OUTPUT0, ALT2);
293
294impl_pin!(PIO0_3, PWM_OUTPUT1, ALT3);
295impl_pin!(PIO0_18, PWM_OUTPUT1, ALT4);
296impl_pin!(PIO1_8, PWM_OUTPUT1, ALT4);
297impl_pin!(PIO1_24, PWM_OUTPUT1, ALT2);
298
299impl_pin!(PIO0_10, PWM_OUTPUT2, ALT5);
300impl_pin!(PIO0_15, PWM_OUTPUT2, ALT4);
301impl_pin!(PIO0_19, PWM_OUTPUT2, ALT4);
302impl_pin!(PIO1_9, PWM_OUTPUT2, ALT4);
303impl_pin!(PIO1_25, PWM_OUTPUT2, ALT2);
304
305impl_pin!(PIO0_22, PWM_OUTPUT3, ALT4);
306impl_pin!(PIO0_31, PWM_OUTPUT3, ALT4);
307impl_pin!(PIO1_10, PWM_OUTPUT3, ALT4);
308impl_pin!(PIO1_26, PWM_OUTPUT3, ALT2);
309
310impl_pin!(PIO0_23, PWM_OUTPUT4, ALT4);
311impl_pin!(PIO1_3, PWM_OUTPUT4, ALT4);
312impl_pin!(PIO1_17, PWM_OUTPUT4, ALT4);
313
314impl_pin!(PIO0_26, PWM_OUTPUT5, ALT4);
315impl_pin!(PIO1_18, PWM_OUTPUT5, ALT4);
316
317impl_pin!(PIO0_27, PWM_OUTPUT6, ALT4);
318impl_pin!(PIO1_31, PWM_OUTPUT6, ALT4);
319
320impl_pin!(PIO0_28, PWM_OUTPUT7, ALT4);
321impl_pin!(PIO1_19, PWM_OUTPUT7, ALT2);
322
323impl_pin!(PIO0_29, PWM_OUTPUT8, ALT4);
324
325impl_pin!(PIO0_30, PWM_OUTPUT9, ALT4);
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/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 d54927b25..d77f08fd8 100644
--- a/embassy-nxp/src/usart/lpc55.rs
+++ b/embassy-nxp/src/usart/lpc55.rs
@@ -1,3 +1,5 @@
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;
@@ -13,7 +15,7 @@ use embedded_io::{self, ErrorKind};
13use crate::dma::{AnyChannel, Channel}; 15use crate::dma::{AnyChannel, Channel};
14use crate::gpio::{AnyPin, SealedPin}; 16use crate::gpio::{AnyPin, SealedPin};
15use crate::interrupt::Interrupt; 17use crate::interrupt::Interrupt;
16use crate::interrupt::typelevel::{Binding, Interrupt as _}; 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
@@ -818,13 +820,13 @@ impl<'d> embedded_io::Read for Usart<'d, Blocking> {
818 } 820 }
819} 821}
820 822
821struct Info { 823pub(crate) struct Info {
822 usart_reg: UsartReg, 824 pub(crate) usart_reg: UsartReg,
823 fc_reg: FlexcommReg, 825 pub(crate) fc_reg: FlexcommReg,
824 interrupt: Interrupt, 826 pub(crate) interrupt: Interrupt,
825} 827}
826 828
827trait SealedInstance { 829pub(crate) trait SealedInstance {
828 fn info() -> &'static Info; 830 fn info() -> &'static Info;
829 fn dma_state() -> &'static DmaState; 831 fn dma_state() -> &'static DmaState;
830 fn instance_number() -> usize; 832 fn instance_number() -> usize;
@@ -837,10 +839,13 @@ pub trait Instance: SealedInstance + PeripheralType {
837 type Interrupt: crate::interrupt::typelevel::Interrupt; 839 type Interrupt: crate::interrupt::typelevel::Interrupt;
838} 840}
839 841
840macro_rules! impl_instance { 842macro_rules! impl_usart_instance {
841 ($inst:ident, $fc:ident, $fc_num:expr) => { 843 ($inst:ident, $fc:ident, $fc_num:expr) => {
842 impl $crate::usart::inner::SealedInstance for $crate::peripherals::$inst { 844 impl crate::usart::SealedInstance for $crate::peripherals::$inst {
843 fn info() -> &'static Info { 845 fn info() -> &'static crate::usart::Info {
846 use crate::interrupt::typelevel::Interrupt;
847 use crate::usart::Info;
848
844 static INFO: Info = Info { 849 static INFO: Info = Info {
845 usart_reg: crate::pac::$inst, 850 usart_reg: crate::pac::$inst,
846 fc_reg: crate::pac::$fc, 851 fc_reg: crate::pac::$fc,
@@ -849,7 +854,13 @@ macro_rules! impl_instance {
849 &INFO 854 &INFO
850 } 855 }
851 856
852 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
853 static STATE: DmaState = DmaState { 864 static STATE: DmaState = DmaState {
854 rx_err_waker: AtomicWaker::new(), 865 rx_err_waker: AtomicWaker::new(),
855 rx_err: AtomicBool::new(false), 866 rx_err: AtomicBool::new(false),
@@ -867,15 +878,6 @@ macro_rules! impl_instance {
867 }; 878 };
868} 879}
869 880
870impl_instance!(USART0, FLEXCOMM0, 0);
871impl_instance!(USART1, FLEXCOMM1, 1);
872impl_instance!(USART2, FLEXCOMM2, 2);
873impl_instance!(USART3, FLEXCOMM3, 3);
874impl_instance!(USART4, FLEXCOMM4, 4);
875impl_instance!(USART5, FLEXCOMM5, 5);
876impl_instance!(USART6, FLEXCOMM6, 6);
877impl_instance!(USART7, FLEXCOMM7, 7);
878
879pub(crate) trait SealedTxPin<T: Instance>: crate::gpio::Pin { 881pub(crate) trait SealedTxPin<T: Instance>: crate::gpio::Pin {
880 fn pin_func(&self) -> PioFunc; 882 fn pin_func(&self) -> PioFunc;
881} 883}
@@ -892,75 +894,46 @@ pub trait TxPin<T: Instance>: SealedTxPin<T> + crate::gpio::Pin {}
892#[allow(private_bounds)] 894#[allow(private_bounds)]
893pub trait RxPin<T: Instance>: SealedRxPin<T> + crate::gpio::Pin {} 895pub trait RxPin<T: Instance>: SealedRxPin<T> + crate::gpio::Pin {}
894 896
895macro_rules! impl_tx_pin { 897macro_rules! impl_usart_txd_pin {
896 ($pin:ident, $instance:ident, $func: ident) => { 898 ($pin:ident, $instance:ident, $func: ident) => {
897 impl SealedTxPin<crate::peripherals::$instance> for crate::peripherals::$pin { 899 impl crate::usart::SealedTxPin<crate::peripherals::$instance> for crate::peripherals::$pin {
898 fn pin_func(&self) -> PioFunc { 900 fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc {
901 use crate::pac::iocon::vals::PioFunc;
899 PioFunc::$func 902 PioFunc::$func
900 } 903 }
901 } 904 }
902 905
903 impl TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} 906 impl crate::usart::TxPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
904 }; 907 };
905} 908}
906 909
907macro_rules! impl_rx_pin { 910macro_rules! impl_usart_rxd_pin {
908 ($pin:ident, $instance:ident, $func: ident) => { 911 ($pin:ident, $instance:ident, $func: ident) => {
909 impl SealedRxPin<crate::peripherals::$instance> for crate::peripherals::$pin { 912 impl crate::usart::SealedRxPin<crate::peripherals::$instance> for crate::peripherals::$pin {
910 fn pin_func(&self) -> PioFunc { 913 fn pin_func(&self) -> crate::pac::iocon::vals::PioFunc {
914 use crate::pac::iocon::vals::PioFunc;
911 PioFunc::$func 915 PioFunc::$func
912 } 916 }
913 } 917 }
914 918
915 impl RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {} 919 impl crate::usart::RxPin<crate::peripherals::$instance> for crate::peripherals::$pin {}
916 }; 920 };
917} 921}
918 922
919impl_tx_pin!(PIO1_6, USART0, ALT1); 923/// Marker trait indicating a DMA channel may be used for USART transmit.
920impl_tx_pin!(PIO1_11, USART1, ALT2);
921impl_tx_pin!(PIO0_27, USART2, ALT1);
922impl_tx_pin!(PIO0_2, USART3, ALT1);
923impl_tx_pin!(PIO0_16, USART4, ALT1);
924impl_tx_pin!(PIO0_9, USART5, ALT3);
925impl_tx_pin!(PIO1_16, USART6, ALT2);
926impl_tx_pin!(PIO0_19, USART7, ALT7);
927
928impl_rx_pin!(PIO1_5, USART0, ALT1);
929impl_rx_pin!(PIO1_10, USART1, ALT2);
930impl_rx_pin!(PIO1_24, USART2, ALT1);
931impl_rx_pin!(PIO0_3, USART3, ALT1);
932impl_rx_pin!(PIO0_5, USART4, ALT2);
933impl_rx_pin!(PIO0_8, USART5, ALT3);
934impl_rx_pin!(PIO1_13, USART6, ALT2);
935impl_rx_pin!(PIO0_20, USART7, ALT7);
936
937/// Trait for TX DMA channels.
938pub trait TxChannel<T: Instance>: crate::dma::Channel {} 924pub trait TxChannel<T: Instance>: crate::dma::Channel {}
939/// Trait for RX DMA channels. 925
926/// Marker trait indicating a DMA channel may be used for USART recieve.
940pub trait RxChannel<T: Instance>: crate::dma::Channel {} 927pub trait RxChannel<T: Instance>: crate::dma::Channel {}
941 928
942macro_rules! impl_channel { 929macro_rules! impl_usart_tx_channel {
943 ($dma:ident, $instance:ident, Tx) => { 930 ($instance: ident, $channel: ident) => {
944 impl TxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {} 931 impl crate::usart::TxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {}
945 };
946 ($dma:ident, $instance:ident, Rx) => {
947 impl RxChannel<crate::peripherals::$instance> for crate::peripherals::$dma {}
948 }; 932 };
949} 933}
950 934
951impl_channel!(DMA_CH4, USART0, Rx); 935macro_rules! impl_usart_rx_channel {
952impl_channel!(DMA_CH5, USART0, Tx); 936 ($instance: ident, $channel: ident) => {
953impl_channel!(DMA_CH6, USART1, Rx); 937 impl crate::usart::RxChannel<crate::peripherals::$instance> for crate::peripherals::$channel {}
954impl_channel!(DMA_CH7, USART1, Tx); 938 };
955impl_channel!(DMA_CH10, USART2, Rx); 939}
956impl_channel!(DMA_CH11, USART2, Tx);
957impl_channel!(DMA_CH8, USART3, Rx);
958impl_channel!(DMA_CH9, USART3, Tx);
959impl_channel!(DMA_CH12, USART4, Rx);
960impl_channel!(DMA_CH13, USART4, Tx);
961impl_channel!(DMA_CH14, USART5, Rx);
962impl_channel!(DMA_CH15, USART5, Tx);
963impl_channel!(DMA_CH16, USART6, Rx);
964impl_channel!(DMA_CH17, USART6, Tx);
965impl_channel!(DMA_CH18, USART7, Rx);
966impl_channel!(DMA_CH19, USART7, Tx);
diff --git a/examples/lpc55s69/src/bin/pwm.rs b/examples/lpc55s69/src/bin/pwm.rs
index 93b898b9d..8a9894b94 100644
--- a/examples/lpc55s69/src/bin/pwm.rs
+++ b/examples/lpc55s69/src/bin/pwm.rs
@@ -10,7 +10,7 @@ use {defmt_rtt as _, panic_halt as _};
10#[embassy_executor::main] 10#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 11async fn main(_spawner: Spawner) {
12 let p = embassy_nxp::init(Default::default()); 12 let p = embassy_nxp::init(Default::default());
13 let pwm = Pwm::new_output(p.PWM_OUTPUT1, p.PIO0_18, Config::new(1_000_000_000, 2_000_000_000)); 13 let pwm = Pwm::new_output(p.SCT0_OUT1, p.PIO0_18, Config::new(1_000_000_000, 2_000_000_000));
14 loop { 14 loop {
15 info!("Counter: {}", pwm.counter()); 15 info!("Counter: {}", pwm.counter());
16 Timer::after_millis(50).await; 16 Timer::after_millis(50).await;
diff --git a/examples/lpc55s69/src/bin/usart_async.rs b/examples/lpc55s69/src/bin/usart_async.rs
index b06abd477..a9815b920 100644
--- a/examples/lpc55s69/src/bin/usart_async.rs
+++ b/examples/lpc55s69/src/bin/usart_async.rs
@@ -38,8 +38,8 @@ async fn main(spawner: Spawner) {
38 p.PIO0_27, 38 p.PIO0_27,
39 p.PIO1_24, 39 p.PIO1_24,
40 Irqs, 40 Irqs,
41 p.DMA_CH11, 41 p.DMA0_CH11,
42 p.DMA_CH10, 42 p.DMA0_CH10,
43 Config::default(), 43 Config::default(),
44 ); 44 );
45 let led = Output::new(p.PIO1_6, Level::Low); 45 let led = Output::new(p.PIO1_6, Level::Low);