aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-11-14 19:03:26 +0100
committerJames Munns <[email protected]>2025-11-14 19:03:26 +0100
commit0bae6aa5aaab5d0f3a3e7e1ec83a0cee909de115 (patch)
tree1740876a3af2f06bcc129b62e3a6e87f4472d5f3
parent8cdccae3c6c4a805cf5003b1a859734c105d76e8 (diff)
parent77b2c602a60e41c7c977003a6d40367ac285930e (diff)
Merge remote-tracking branch 'origin/main' into james/impl-clocks
-rw-r--r--.cargo/config.toml19
-rw-r--r--.github/workflows/cargo-vet-pr-comment.yml2
-rw-r--r--.github/workflows/rolling.yml18
-rw-r--r--Cargo.lock24
-rw-r--r--Cargo.toml58
-rw-r--r--README.md361
-rw-r--r--examples/.cargo/config.toml17
-rw-r--r--examples/.gitignore1
-rw-r--r--examples/Cargo.lock625
-rw-r--r--examples/Cargo.toml21
-rw-r--r--examples/build.rs (renamed from build.rs)4
-rw-r--r--examples/memory.x5
-rw-r--r--examples/src/bin/adc_interrupt.rs (renamed from examples/adc_interrupt.rs)24
-rw-r--r--examples/src/bin/adc_polling.rs (renamed from examples/adc_polling.rs)33
-rw-r--r--examples/src/bin/blink.rs (renamed from examples/blink.rs)11
-rw-r--r--examples/src/bin/hello.rs (renamed from examples/hello.rs)9
-rw-r--r--examples/src/bin/lpuart_buffered.rs (renamed from examples/lpuart_buffered.rs)15
-rw-r--r--examples/src/bin/lpuart_polling.rs (renamed from examples/lpuart_polling.rs)7
-rw-r--r--examples/src/bin/ostimer_alarm.rs (renamed from examples/ostimer_alarm.rs)18
-rw-r--r--examples/src/bin/ostimer_async.rs (renamed from examples/ostimer_async.rs)15
-rw-r--r--examples/src/bin/ostimer_counter.rs (renamed from examples/ostimer_counter.rs)13
-rw-r--r--examples/src/bin/ostimer_race_test.rs (renamed from examples/ostimer_race_test.rs)15
-rw-r--r--examples/src/bin/rtc_alarm.rs (renamed from examples/rtc_alarm.rs)15
-rw-r--r--examples/src/lib.rs (renamed from examples/common/mod.rs)10
-rw-r--r--memory.x10
-rw-r--r--src/lib.rs44
-rw-r--r--src/ostimer.rs5
-rw-r--r--src/rtc.rs4
28 files changed, 789 insertions, 614 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
deleted file mode 100644
index 3286be01c..000000000
--- a/.cargo/config.toml
+++ /dev/null
@@ -1,19 +0,0 @@
1[build]
2target = "thumbv8m.main-none-eabihf"
3
4[target.thumbv8m.main-none-eabihf]
5runner = "./run.sh"
6# Use our custom ram.ld for RAM-execution
7rustflags = ["-C", "link-arg=-Tdefmt.x", "-C", "link-arg=-Tram.ld"]
8
9[alias]
10# Build examples with defmt+RTT and LPUART2 enabled
11build-defmt = ["build", "--features", "defmt defmt-rtt lpuart2", "--examples"]
12# Blocking run (uses run.sh). Good for one-terminal flash+run.
13run-defmt = ["run", "--features", "defmt defmt-rtt lpuart2", "--example", "hello"]
14# Non-blocking flash to RAM via J-Link; frees probe for RTT attach
15flash-nb = ["!./tools/run_jlink_noblock.sh", "target/thumbv8m.main-none-eabihf/debug/examples/hello", "1366:0101:000600110607", "MCXA276", "500"]
16# Attach-only viewer that decodes defmt over RTT using J-Link
17# Requires PROBE_RS_PROBE exported (or it will prompt)
18defmt-attach = ["embed", "--features", "defmt defmt-rtt lpuart2", "--example", "hello"]
19
diff --git a/.github/workflows/cargo-vet-pr-comment.yml b/.github/workflows/cargo-vet-pr-comment.yml
index fafb21641..66f27ceab 100644
--- a/.github/workflows/cargo-vet-pr-comment.yml
+++ b/.github/workflows/cargo-vet-pr-comment.yml
@@ -31,7 +31,7 @@ jobs:
31 if: github.event.workflow_run.event == 'pull_request' 31 if: github.event.workflow_run.event == 'pull_request'
32 steps: 32 steps:
33 - name: 'Download artifact' 33 - name: 'Download artifact'
34 uses: actions/download-artifact@v4 34 uses: actions/download-artifact@v6
35 with: 35 with:
36 github-token: ${{ secrets.GITHUB_TOKEN }} 36 github-token: ${{ secrets.GITHUB_TOKEN }}
37 name: pr 37 name: pr
diff --git a/.github/workflows/rolling.yml b/.github/workflows/rolling.yml
index 386c0df5c..1d93cfe25 100644
--- a/.github/workflows/rolling.yml
+++ b/.github/workflows/rolling.yml
@@ -40,22 +40,8 @@ jobs:
40 strategy: 40 strategy:
41 fail-fast: false 41 fail-fast: false
42 matrix: 42 matrix:
43 msrv: ["1.85"] # We're relying on namespaced-features, which 43 msrv: ["1.91"]
44 # was released in 1.60 44
45 #
46 # We also depend on `fixed' which requires rust
47 # 1.71
48 #
49 # Additionally, we depend on embedded-hal-async
50 # which requires 1.75
51 #
52 # embassy-time requires 1.79 due to
53 # collapse_debuginfo
54 #
55 # embassy upstream switched to rust 1.83
56 #
57 # embedded-services (storage bus) dependency
58 # requires 1.85
59 name: ubuntu / ${{ matrix.msrv }} (${{ matrix.commit }}) 45 name: ubuntu / ${{ matrix.msrv }} (${{ matrix.commit }})
60 steps: 46 steps:
61 - uses: actions/checkout@v5 47 - uses: actions/checkout@v5
diff --git a/Cargo.lock b/Cargo.lock
index 953a71ee0..e9f4d3165 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -148,16 +148,6 @@ dependencies = [
148] 148]
149 149
150[[package]] 150[[package]]
151name = "defmt-rtt"
152version = "1.1.0"
153source = "registry+https://github.com/rust-lang/crates.io-index"
154checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e"
155dependencies = [
156 "critical-section",
157 "defmt",
158]
159
160[[package]]
161name = "document-features" 151name = "document-features"
162version = "0.2.12" 152version = "0.2.12"
163source = "registry+https://github.com/rust-lang/crates.io-index" 153source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -232,14 +222,13 @@ dependencies = [
232] 222]
233 223
234[[package]] 224[[package]]
235name = "embassy-mcxa276" 225name = "embassy-mcxa"
236version = "0.1.0" 226version = "0.1.0"
237dependencies = [ 227dependencies = [
238 "cortex-m", 228 "cortex-m",
239 "cortex-m-rt", 229 "cortex-m-rt",
240 "critical-section", 230 "critical-section",
241 "defmt", 231 "defmt",
242 "defmt-rtt",
243 "embassy-embedded-hal", 232 "embassy-embedded-hal",
244 "embassy-executor", 233 "embassy-executor",
245 "embassy-hal-internal", 234 "embassy-hal-internal",
@@ -255,7 +244,6 @@ dependencies = [
255 "heapless", 244 "heapless",
256 "mcxa-pac", 245 "mcxa-pac",
257 "nb 1.1.0", 246 "nb 1.1.0",
258 "panic-probe",
259 "paste", 247 "paste",
260] 248]
261 249
@@ -447,16 +435,6 @@ dependencies = [
447] 435]
448 436
449[[package]] 437[[package]]
450name = "panic-probe"
451version = "1.0.0"
452source = "registry+https://github.com/rust-lang/crates.io-index"
453checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a"
454dependencies = [
455 "cortex-m",
456 "defmt",
457]
458
459[[package]]
460name = "paste" 438name = "paste"
461version = "1.0.15" 439version = "1.0.15"
462source = "registry+https://github.com/rust-lang/crates.io-index" 440source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 259becfe8..3913104fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,15 +1,12 @@
1[package] 1[package]
2name = "embassy-mcxa276" 2name = "embassy-mcxa"
3version = "0.1.0" 3version = "0.1.0"
4edition = "2021" 4edition = "2021"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6description = "Embassy Hardware Abstraction Layer (HAL) for NXP MCXA276" 6description = "Embassy Hardware Abstraction Layer (HAL) for NXP MCXA series of MCUs"
7keywords = ["embedded", "hal", "nxp", "mcxa276", "embassy"] 7keywords = ["embedded", "hal", "nxp", "mcxa", "embassy"]
8categories = ["embedded", "hardware-support", "no-std"] 8categories = ["embedded", "hardware-support", "no-std"]
9 9
10[lib]
11name = "embassy_mcxa276"
12
13[dependencies] 10[dependencies]
14cortex-m = { version = "0.7", features = ["critical-section-single-core"] } 11cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
15cortex-m-rt = { version = "0.7", features = ["device"] } 12cortex-m-rt = { version = "0.7", features = ["device"] }
@@ -35,11 +32,6 @@ embedded-hal-nb = { version = "1.0" }
35embedded-io-async = { version = "0.6.1" } 32embedded-io-async = { version = "0.6.1" }
36nb = "1.1.0" 33nb = "1.1.0"
37 34
38[dev-dependencies]
39defmt = "1.0"
40defmt-rtt = "1.0"
41panic-probe = { version = "1.0", features = ["print-defmt"] }
42
43[features] 35[features]
44default = [] 36default = []
45 37
@@ -50,47 +42,3 @@ defmt = ["dep:defmt"]
50rt = [] 42rt = []
51 43
52unstable-pac = [] 44unstable-pac = []
53
54[[example]]
55name = "hello"
56
57[[example]]
58name = "blink"
59
60[[example]]
61name = "ostimer_alarm"
62
63[[example]]
64name = "ostimer_async"
65
66[[example]]
67name = "ostimer_counter"
68
69[[example]]
70name = "ostimer_race_test"
71
72[[example]]
73name = "lpuart_polling"
74
75[[example]]
76name = "lpuart_buffered"
77
78[[example]]
79name = "rtc_alarm"
80
81[[example]]
82name = "adc_polling"
83
84[[example]]
85name = "adc_interrupt"
86
87[profile.release]
88debug = 2
89lto = true
90opt-level = "s"
91
92[profile.dev]
93debug = 2
94opt-level = 1
95
96
diff --git a/README.md b/README.md
index 8a93b5f4a..6e7d61c0e 100644
--- a/README.md
+++ b/README.md
@@ -1,362 +1,13 @@
1# Embassy MCXA276 HAL 1# Embassy MCXA256 HAL
2 2
3A Hardware Abstraction Layer (HAL) for the NXP MCXA276 microcontroller 3[![check](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/check.yml/badge.svg)](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/check.yml)
4[![no-std](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/nostd.yml/badge.svg)](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/nostd.yml)
5[![rolling](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/rolling.yml/badge.svg)](https://github.com/OpenDevicePartnership/embassy-mcxa/actions/workflows/rolling.yml)
6
7A Hardware Abstraction Layer (HAL) for the NXP MCXA256 microcontroller
4using the Embassy async framework. This HAL provides safe, idiomatic 8using the Embassy async framework. This HAL provides safe, idiomatic
5Rust interfaces for GPIO, UART, and OSTIMER peripherals. 9Rust interfaces for GPIO, UART, and OSTIMER peripherals.
6 10
7## Prerequisites
8
9### Ubuntu/Debian Setup
10
11```bash
12# Install Rust toolchain
13curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
14source ~/.cargo/env
15
16# Add target for MCXA276 (ARM Cortex-M33)
17rustup target add thumbv8m.main-none-eabihf
18
19# Install required tools
20sudo apt update
21sudo apt install -y gdb-multiarch curl wget
22
23# Install probe-rs for running and debugging
24cargo install probe-rs --features cli
25```
26
27### Windows Setup
28
29- Install Rust via https://rustup.rs (default options are fine)
30- Add the MCXA276 target:
31 ```powershell
32 rustup target add thumbv8m.main-none-eabihf
33 ```
34- Install probe-rs CLI (we will use it directly; no GDB required):
35 ```powershell
36 cargo install probe-rs --features cli
37 ```
38- Install a serial terminal (e.g., Tera Term): https://ttssh2.osdn.jp/
39- USB drivers: Windows 10/11 usually picks up the board as a USB CDC device automatically (COM port)
40
41### Hardware Requirements
42
43- NXP FRDM-MCXA276 development board
44- Debug probe (CMSIS-DAP compatible)
45- USB cable for power and programming
46
47## Examples
48
49This HAL includes several examples demonstrating different peripherals:
50
51### GPIO Examples
52
53#### `blink`
54Blinks an LED connected to GPIO pin. Demonstrates basic GPIO output operations.
55
56### UART Examples
57
58#### `hello`
59Interactive UART2 demo: prints a banner and supports `help`, `echo <text>`, `hex <byte>`.
60
61### OSTIMER Examples
62
63#### `ostimer_alarm`
64
65Demonstrates setting and waiting for OSTIMER alarms.
66
67#### `ostimer_async`
68Shows asynchronous OSTIMER operations with Embassy's async runtime.
69
70#### `ostimer_counter`
71Demonstrates OSTIMER counter functionality.
72
73#### `ostimer_race_test`
74Advanced example testing OSTIMER race conditions and synchronization.
75
76### RTC Example
77
78#### `rtc_alarm`
79Demonstrates how to enable and use the RTC to generate an interrupt after 10seconds.
80
81## Build and Run
82
83### Using probe-rs
84
85All examples require specifying your debug probe. First, find your probe ID:
86
87```bash
88probe-rs list
89```
90
91Then run examples with your probe ID (replace `1fc9:0143:H3AYDQVQMTROB` with your actual probe):
92
93```bash
94# GPIO blink example
95PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "gpio ostimer0" --example blink
96
97
98
99# UART hello example
100PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example hello
101
102# OSTIMER examples
103PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm
104PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_async
105PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_counter
106PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_race_test
107
108# RTC example
109PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 rtc0" --example rtc_alarm
110```
111
112**Note:** All examples run from RAM, not flash memory. They are loaded directly into RAM for faster development iteration.
113
114**Important:** After pressing the RESET button on the board, the first `cargo run` attempt may fail with a connection error. This is expected - simply run the command again and it will work. The run.sh script now properly sets the Vector Table Offset Register (VTOR) to point to the RAM-based vector table, ensuring the correct stack pointer and reset vector are used.
115
116```console
117smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --release --features "gpio ostimer0" --example blink
118 Finished `release` profile [optimized + debuginfo] target(s) in 0.07s
119 Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/release/examples/blink`
120probe-rs gdb server failed to connect to target. Log:
121----- probe-rs gdb log -----
122 Error: Connecting to the chip was unsuccessful.
123
124 Caused by:
125 0: An ARM specific error occurred.
126 1: Error using access port FullyQualifiedApAddress { dp: Default, ap: V1(0) }.
127 2: Failed to read register DRW at address 0xd0c
128 3: An error occurred in the communication with an access port or debug port.
129 4: Target device responded with a FAULT response to the request.
130smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --release --features "gpio ostimer0" --example blink
131 Finished `release` profile [optimized + debuginfo] target(s) in 0.02s
132 Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/release/examples/blink`
133```
134
135### Additional UART Examples
136
137#### `uart_interrupt`
138Interrupt-driven UART2 echo. Type in the serial terminal; each byte is echoed back from the IRQ handler path.
139
140#### `lpuart_polling`
141Blocking TX/RX echo over UART2 using the simple polling driver.
142
143#### `lpuart_buffered`
144Async buffered driver with separate TX/RX tasks; echoes typed characters in chunks.
145
146Pins: UART2 TX=P2_2, RX=P2_3 (ALT3), 115200 8N1.
147
148### ADC Examples
149
150#### `adc_polling`
151Configures ADC1 channel A8 (pin P1_10) and prints conversion values to UART2 periodically.
152
153#### `adc_interrupt`
154Triggers a conversion and signals completion via ADC1 interrupt, printing a notification on UART2.
155
156```console
1570x20002040 in ?? ()
158Supported Commands:
159
160 info - print session information
161 reset - reset target
162 reset halt - reset target and halt afterwards
163
164Loading section .vector_table, size 0x224 lma 0x20000000
165Loading section .text, size 0x97e lma 0x20000224
166Loading section .Reset, size 0x58 lma 0x20000ba4
167Loading section .rodata, size 0x28 lma 0x20000bfc
168Start address 0x20000ba4, load size 3106
169Transfer rate: 13 KB/sec, 776 bytes/write.
170```
171
172then I see the LED blinking. I press CTRL+C to exit. It will show me ^C
173
174```console
175Program received signal SIGINT, Interrupt.
1760x20000880 in embassy_executor::arch::thread::Executor::run<blink::__cortex_m_rt_main::{closure_env#0}> (self=0x200027e8, init=...) at /home/smw016108/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embassy-executor-0.9.1/src/arch/cortex_m.rs:106
177106 asm!("wfe");
178[Inferior 1 (process 1) detached]
179Program loaded and started (no reset)
180smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ \
181
182Then I press RESET again and I want to run another example, like ostimer_alarm. I open the console using sudo picocom -b 115200 /dev/ttyACM0 and I start running the example:
183
184smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm
185 Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s
186 Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm`
187probe-rs gdb server failed to connect to target. Log:
188----- probe-rs gdb log -----
189 Error: Connecting to the chip was unsuccessful.
190
191 Caused by:
192 0: An ARM specific error occurred.
193 1: Error using access port FullyQualifiedApAddress { dp: Default, ap: V1(0) }.
194 2: Failed to read register DRW at address 0xd0c
195 3: An error occurred in the communication with an access port or debug port.
196 4: Target device responded with a FAULT response to the request.
197smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$ PROBE=1fc9:0143:H3AYDQVQMTROB cargo run --features "lpuart2 ostimer0" --example ostimer_alarm
198 Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s
199 Running `/home/smw016108/Downloads/nxp/rust/uart/embassy-mcxa276/./run.sh target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm`
2000x20002040 in core::panicking::panic_const::panic_const_mul_overflow () at library/core/src/panicking.rs:175
201warning: 175 library/core/src/panicking.rs: No such file or directory
202Supported Commands:
203
204 info - print session information
205 reset - reset target
206 reset halt - reset target and halt afterwards
207
208Loading section .vector_table, size 0x224 lma 0x20000000
209Loading section .text, size 0x2226 lma 0x20000224
210Loading section .Reset, size 0x58 lma 0x2000244c
211Loading section .rodata, size 0x6dc lma 0x200024a4
212Start address 0x2000244c, load size 11134
213Transfer rate: 16 KB/sec, 1855 bytes/write.
214```
215
216I can see in the console
217
218```console
219OSTIMER Alarm Example
220Scheduling alarm for 2 seconds...
221Alarm scheduled successfully
222Alarm expired! Callback executed.
223Scheduling another alarm for 3 seconds...
224Alarm scheduled. Waiting 1 second then canceling...
225Alarm canceled
226Alarm was successfully canceled
227Example complete
228```
229
230then I press CTRL+C to stop running
231
232```console
233^C
234Program received signal SIGINT, Interrupt.
2350x20000e64 in embassy_executor::arch::thread::Executor::run<ostimer_alarm::__cortex_m_rt_main::{closure_env#0}> (self=0x200027e8, init=...) at /home/smw016108/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embassy-executor-0.9.1/src/arch/cortex_m.rs:106
236106 asm!("wfe");
237[Inferior 1 (process 1) detached]
238Program loaded and started (no reset)
239smw016108@smw016108:~/Downloads/nxp/rust/uart/embassy-mcxa276$
240```
241
242### Windows: Running examples (RAM, no RTT/defmt)
243
244Important: On Windows, do not use `cargo run` because `.cargo/config.toml` sets a Linux-only runner (`./run.sh`). Instead, use `probe-rs run` directly.
245
2461) Find your probe and COM port
247- List probes:
248
249 ```console
250 probe-rs list
251 ```
252- If multiple probes are attached, set the specific one (replace with your ID):
253
254 ```console
255 $env:PROBE_RS_PROBE = "1366:0101:000600110607"
256 ```
257
258- Check Windows Device Manager → Ports (COM & LPT) for the board’s COM port.
259
2602) Build the example
261
262```console
263cargo build --example hello --features "lpuart2"
264```
265
2663) Run from RAM with probe-rs
267
268```console
269probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/hello
270```
271You will see a short probe-rs warning like "unknown variant, try to set watch point"; it’s harmless.
272
2734) View output in Tera Term
274- Open Tera Term, select the board’s COMx port, 115200 8N1
275- Expected behavior per example:
276 - hello: prints a banner; simple UART output
277 - lpuart_polling / lpuart_buffered / uart_interrupt: echo typed characters
278 - adc_polling: prints ADC values periodically (ADC1 channel A8 on P1_10)
279 - adc_interrupt: prints "*** ADC interrupt TRIGGERED! ***" upon conversion completion
280 - blink: LED on PIO3_18 blinks "SOS" pattern
281 - rtc_alarm: schedules, cancels and reports alarm events on UART
282
283Notes
284- All examples run from RAM (not flashed). Reset clears the program.
285- If the first attempt after a reset fails to connect, just run the command again.
286- UART2 pins: TX=P2_2, RX=P2_3 (ALT3), 115200 8N1.
287
288Quick commands for other examples:
289
290```console
291# Build
292cargo build --example blink --features "gpio ostimer0"
293cargo build --example lpuart_polling --features "lpuart2 ostimer0"
294cargo build --example lpuart_buffered --features "lpuart2 ostimer0"
295cargo build --example uart_interrupt --features "lpuart2 ostimer0"
296cargo build --example rtc_alarm --features "lpuart2 rtc0"
297cargo build --example adc_polling --features "adc1 lpuart2"
298cargo build --example adc_interrupt --features "adc1 lpuart2"
299
300# Run (RAM)
301probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/blink
302probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/lpuart_polling
303probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/lpuart_buffered
304probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/uart_interrupt
305probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/rtc_alarm
306probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/adc_polling
307probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/adc_interrupt
308probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_alarm
309probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_async
310probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_counter
311probe-rs run --chip MCXA276 --protocol swd --speed 1000 target/thumbv8m.main-none-eabihf/debug/examples/ostimer_race_test
312```
313
314How I tested on Windows
315- Windows 11; Rust stable; probe-rs 0.29.x
316- Built each example as above; ran with `probe-rs run` (RAM execution)
317- Observed UART output in Tera Term at 115200 8N1; all examples behaved as expected
318- No RTT/defmt used; purely UART or LED observation
319
320### Build Only
321
322To build without running:
323
324```console
325cargo build --features "gpio ostimer0" --example blink
326cargo build --features "lpuart2 ostimer0" --example hello
327cargo build --features "lpuart2 ostimer0" --example ostimer_alarm
328cargo build --features "lpuart2 rtc0" --example rtc_alarm
329# etc.
330```
331
332## Development Notes
333
334### Critical Fix: MCXA276 Interrupt Vector Table
335
336
337Update (SVD 25.06.00, mcxa-pac a9dd33): No manual PAC edits are required anymore. OS_EVENT and WAKETIMER0 are present and the vector table is correct. The section below is kept for historical context.
338**Problem:** The OSTIMER examples crashed during interrupt handling with a hardfault (SP=0x00000000). Investigation revealed the OS_EVENT interrupt vector was NULL in the vector table, causing the CPU to jump to address 0 when OSTIMER interrupts fired.
339
340**Root Cause:** The `mcxa276-pac/src/lib.rs` file (generated from the SVD file) was missing the `WAKETIMER0` interrupt handler declaration. This caused the `__INTERRUPTS` array to have an off-by-one error, placing OS_EVENT at IRQ 58 instead of the correct IRQ 57 position.
341
342**Solution:** Manually edited `mcxa276-pac/src/lib.rs` to add the missing WAKETIMER0 interrupt:
343
3441. Added `fn WAKETIMER0()` to the `extern "C"` block
3452. Fixed the `__INTERRUPTS: [Vector; 122]` array sequence:
346 - Changed from: `LPTMR0, _reserved, _reserved, OS_EVENT, _reserved, UTICK0, ...`
347 - Changed to: `LPTMR0, _reserved, OS_EVENT, WAKETIMER0, UTICK0, WWDT0, _reserved, ADC0, ...`
3483. Added `WAKETIMER0 = 58` to the `Interrupt` enum
349
350**Verification:** Binary analysis confirmed OS_EVENT is now at the correct position:
351- IRQ 57 = word 73 = offset 0x124 in vector table
352- OS_EVENT handler: 0x20000BB1 (verified with `arm-none-eabi-objdump`)
353
354**Note:** This is likely an issue with the NXP MCXA276.svd file or svd2rust generation. The WAKETIMER0 peripheral exists in the PAC but the interrupt handler was missing. Future regeneration of the PAC from SVD may require reapplying this fix.
355
356### Warning: Avoid `#[inline(always)]` in Performance-Critical Code
357
358Using `#[inline(always)]` can cause the Rust compiler to generate incorrect assembly, leading to register corruption or unexpected behavior. For example, in tight polling loops like those in the OSTIMER driver, this attribute may result in invalid instructions that zero registers (e.g., `movs r1, r0` causing r1=0), triggering hardfaults.
359
360## License 11## License
361 12
362This project is licensed under MIT OR Apache-2.0. 13This project is licensed under MIT OR Apache-2.0.
diff --git a/examples/.cargo/config.toml b/examples/.cargo/config.toml
new file mode 100644
index 000000000..ecb11be64
--- /dev/null
+++ b/examples/.cargo/config.toml
@@ -0,0 +1,17 @@
1[target.thumbv8m.main-none-eabihf]
2runner = 'probe-rs run --chip MCXA276 --preverify --verify'
3
4rustflags = [
5 "-C", "linker=flip-link",
6 "-C", "link-arg=-Tlink.x",
7 "-C", "link-arg=-Tdefmt.x",
8 # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
9 # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
10 "-C", "link-arg=--nmagic",
11]
12
13[build]
14target = "thumbv8m.main-none-eabihf" # Cortex-M33
15
16[env]
17DEFMT_LOG = "trace"
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 000000000..2f7896d1d
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1 @@
target/
diff --git a/examples/Cargo.lock b/examples/Cargo.lock
new file mode 100644
index 000000000..b774aff97
--- /dev/null
+++ b/examples/Cargo.lock
@@ -0,0 +1,625 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 4
4
5[[package]]
6name = "autocfg"
7version = "1.5.0"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
11[[package]]
12name = "bare-metal"
13version = "0.2.5"
14source = "registry+https://github.com/rust-lang/crates.io-index"
15checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
16dependencies = [
17 "rustc_version",
18]
19
20[[package]]
21name = "bitfield"
22version = "0.13.2"
23source = "registry+https://github.com/rust-lang/crates.io-index"
24checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
25
26[[package]]
27name = "bitflags"
28version = "1.3.2"
29source = "registry+https://github.com/rust-lang/crates.io-index"
30checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
31
32[[package]]
33name = "byteorder"
34version = "1.5.0"
35source = "registry+https://github.com/rust-lang/crates.io-index"
36checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
37
38[[package]]
39name = "cfg-if"
40version = "1.0.4"
41source = "registry+https://github.com/rust-lang/crates.io-index"
42checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
43
44[[package]]
45name = "cortex-m"
46version = "0.7.7"
47source = "registry+https://github.com/rust-lang/crates.io-index"
48checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
49dependencies = [
50 "bare-metal",
51 "bitfield",
52 "critical-section",
53 "embedded-hal 0.2.7",
54 "volatile-register",
55]
56
57[[package]]
58name = "cortex-m-rt"
59version = "0.7.5"
60source = "registry+https://github.com/rust-lang/crates.io-index"
61checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6"
62dependencies = [
63 "cortex-m-rt-macros",
64]
65
66[[package]]
67name = "cortex-m-rt-macros"
68version = "0.7.5"
69source = "registry+https://github.com/rust-lang/crates.io-index"
70checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472"
71dependencies = [
72 "proc-macro2",
73 "quote",
74 "syn",
75]
76
77[[package]]
78name = "critical-section"
79version = "1.2.0"
80source = "registry+https://github.com/rust-lang/crates.io-index"
81checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
82
83[[package]]
84name = "darling"
85version = "0.20.11"
86source = "registry+https://github.com/rust-lang/crates.io-index"
87checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
88dependencies = [
89 "darling_core",
90 "darling_macro",
91]
92
93[[package]]
94name = "darling_core"
95version = "0.20.11"
96source = "registry+https://github.com/rust-lang/crates.io-index"
97checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
98dependencies = [
99 "fnv",
100 "ident_case",
101 "proc-macro2",
102 "quote",
103 "strsim",
104 "syn",
105]
106
107[[package]]
108name = "darling_macro"
109version = "0.20.11"
110source = "registry+https://github.com/rust-lang/crates.io-index"
111checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
112dependencies = [
113 "darling_core",
114 "quote",
115 "syn",
116]
117
118[[package]]
119name = "defmt"
120version = "1.0.1"
121source = "registry+https://github.com/rust-lang/crates.io-index"
122checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
123dependencies = [
124 "bitflags",
125 "defmt-macros",
126]
127
128[[package]]
129name = "defmt-macros"
130version = "1.0.1"
131source = "registry+https://github.com/rust-lang/crates.io-index"
132checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
133dependencies = [
134 "defmt-parser",
135 "proc-macro-error2",
136 "proc-macro2",
137 "quote",
138 "syn",
139]
140
141[[package]]
142name = "defmt-parser"
143version = "1.0.0"
144source = "registry+https://github.com/rust-lang/crates.io-index"
145checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
146dependencies = [
147 "thiserror",
148]
149
150[[package]]
151name = "defmt-rtt"
152version = "1.1.0"
153source = "registry+https://github.com/rust-lang/crates.io-index"
154checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e"
155dependencies = [
156 "critical-section",
157 "defmt",
158]
159
160[[package]]
161name = "document-features"
162version = "0.2.12"
163source = "registry+https://github.com/rust-lang/crates.io-index"
164checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
165dependencies = [
166 "litrs",
167]
168
169[[package]]
170name = "embassy-embedded-hal"
171version = "0.5.0"
172source = "registry+https://github.com/rust-lang/crates.io-index"
173checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8"
174dependencies = [
175 "embassy-futures",
176 "embassy-hal-internal",
177 "embassy-sync",
178 "embedded-hal 0.2.7",
179 "embedded-hal 1.0.0",
180 "embedded-hal-async",
181 "embedded-storage",
182 "embedded-storage-async",
183 "nb 1.1.0",
184]
185
186[[package]]
187name = "embassy-executor"
188version = "0.9.1"
189source = "registry+https://github.com/rust-lang/crates.io-index"
190checksum = "06070468370195e0e86f241c8e5004356d696590a678d47d6676795b2e439c6b"
191dependencies = [
192 "cortex-m",
193 "critical-section",
194 "document-features",
195 "embassy-executor-macros",
196 "embassy-executor-timer-queue",
197]
198
199[[package]]
200name = "embassy-executor-macros"
201version = "0.7.0"
202source = "registry+https://github.com/rust-lang/crates.io-index"
203checksum = "dfdddc3a04226828316bf31393b6903ee162238576b1584ee2669af215d55472"
204dependencies = [
205 "darling",
206 "proc-macro2",
207 "quote",
208 "syn",
209]
210
211[[package]]
212name = "embassy-executor-timer-queue"
213version = "0.1.0"
214source = "registry+https://github.com/rust-lang/crates.io-index"
215checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c"
216
217[[package]]
218name = "embassy-futures"
219version = "0.1.2"
220source = "registry+https://github.com/rust-lang/crates.io-index"
221checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01"
222
223[[package]]
224name = "embassy-hal-internal"
225version = "0.3.0"
226source = "registry+https://github.com/rust-lang/crates.io-index"
227checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a"
228dependencies = [
229 "cortex-m",
230 "critical-section",
231 "num-traits",
232]
233
234[[package]]
235name = "embassy-mcxa"
236version = "0.1.0"
237dependencies = [
238 "cortex-m",
239 "cortex-m-rt",
240 "critical-section",
241 "defmt",
242 "embassy-embedded-hal",
243 "embassy-executor",
244 "embassy-hal-internal",
245 "embassy-sync",
246 "embassy-time",
247 "embassy-time-driver",
248 "embedded-hal 0.2.7",
249 "embedded-hal 1.0.0",
250 "embedded-hal-async",
251 "embedded-hal-nb",
252 "embedded-io",
253 "embedded-io-async",
254 "heapless 0.8.0",
255 "mcxa-pac",
256 "nb 1.1.0",
257 "paste",
258]
259
260[[package]]
261name = "embassy-mcxa-examples"
262version = "0.1.0"
263dependencies = [
264 "cortex-m",
265 "cortex-m-rt",
266 "critical-section",
267 "defmt",
268 "defmt-rtt",
269 "embassy-embedded-hal",
270 "embassy-executor",
271 "embassy-mcxa",
272 "embassy-sync",
273 "embassy-time",
274 "embassy-time-driver",
275 "embedded-io-async",
276 "heapless 0.9.2",
277 "panic-probe",
278]
279
280[[package]]
281name = "embassy-sync"
282version = "0.7.2"
283source = "registry+https://github.com/rust-lang/crates.io-index"
284checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b"
285dependencies = [
286 "cfg-if",
287 "critical-section",
288 "embedded-io-async",
289 "futures-core",
290 "futures-sink",
291 "heapless 0.8.0",
292]
293
294[[package]]
295name = "embassy-time"
296version = "0.5.0"
297source = "registry+https://github.com/rust-lang/crates.io-index"
298checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65"
299dependencies = [
300 "cfg-if",
301 "critical-section",
302 "document-features",
303 "embassy-time-driver",
304 "embedded-hal 0.2.7",
305 "embedded-hal 1.0.0",
306 "embedded-hal-async",
307 "futures-core",
308]
309
310[[package]]
311name = "embassy-time-driver"
312version = "0.2.1"
313source = "registry+https://github.com/rust-lang/crates.io-index"
314checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6"
315dependencies = [
316 "document-features",
317]
318
319[[package]]
320name = "embedded-hal"
321version = "0.2.7"
322source = "registry+https://github.com/rust-lang/crates.io-index"
323checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
324dependencies = [
325 "nb 0.1.3",
326 "void",
327]
328
329[[package]]
330name = "embedded-hal"
331version = "1.0.0"
332source = "registry+https://github.com/rust-lang/crates.io-index"
333checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
334
335[[package]]
336name = "embedded-hal-async"
337version = "1.0.0"
338source = "registry+https://github.com/rust-lang/crates.io-index"
339checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
340dependencies = [
341 "embedded-hal 1.0.0",
342]
343
344[[package]]
345name = "embedded-hal-nb"
346version = "1.0.0"
347source = "registry+https://github.com/rust-lang/crates.io-index"
348checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605"
349dependencies = [
350 "embedded-hal 1.0.0",
351 "nb 1.1.0",
352]
353
354[[package]]
355name = "embedded-io"
356version = "0.6.1"
357source = "registry+https://github.com/rust-lang/crates.io-index"
358checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
359
360[[package]]
361name = "embedded-io-async"
362version = "0.6.1"
363source = "registry+https://github.com/rust-lang/crates.io-index"
364checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
365dependencies = [
366 "embedded-io",
367]
368
369[[package]]
370name = "embedded-storage"
371version = "0.3.1"
372source = "registry+https://github.com/rust-lang/crates.io-index"
373checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032"
374
375[[package]]
376name = "embedded-storage-async"
377version = "0.4.1"
378source = "registry+https://github.com/rust-lang/crates.io-index"
379checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc"
380dependencies = [
381 "embedded-storage",
382]
383
384[[package]]
385name = "fnv"
386version = "1.0.7"
387source = "registry+https://github.com/rust-lang/crates.io-index"
388checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
389
390[[package]]
391name = "futures-core"
392version = "0.3.31"
393source = "registry+https://github.com/rust-lang/crates.io-index"
394checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
395
396[[package]]
397name = "futures-sink"
398version = "0.3.31"
399source = "registry+https://github.com/rust-lang/crates.io-index"
400checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
401
402[[package]]
403name = "hash32"
404version = "0.3.1"
405source = "registry+https://github.com/rust-lang/crates.io-index"
406checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
407dependencies = [
408 "byteorder",
409]
410
411[[package]]
412name = "heapless"
413version = "0.8.0"
414source = "registry+https://github.com/rust-lang/crates.io-index"
415checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
416dependencies = [
417 "hash32",
418 "stable_deref_trait",
419]
420
421[[package]]
422name = "heapless"
423version = "0.9.2"
424source = "registry+https://github.com/rust-lang/crates.io-index"
425checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed"
426dependencies = [
427 "hash32",
428 "stable_deref_trait",
429]
430
431[[package]]
432name = "ident_case"
433version = "1.0.1"
434source = "registry+https://github.com/rust-lang/crates.io-index"
435checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
436
437[[package]]
438name = "litrs"
439version = "1.0.0"
440source = "registry+https://github.com/rust-lang/crates.io-index"
441checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
442
443[[package]]
444name = "mcxa-pac"
445version = "0.1.0"
446source = "git+https://github.com/OpenDevicePartnership/mcxa-pac?rev=3ab4c868f75a9240bb8fdce24982d34f2273aabf#3ab4c868f75a9240bb8fdce24982d34f2273aabf"
447dependencies = [
448 "cortex-m",
449 "cortex-m-rt",
450 "vcell",
451]
452
453[[package]]
454name = "nb"
455version = "0.1.3"
456source = "registry+https://github.com/rust-lang/crates.io-index"
457checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
458dependencies = [
459 "nb 1.1.0",
460]
461
462[[package]]
463name = "nb"
464version = "1.1.0"
465source = "registry+https://github.com/rust-lang/crates.io-index"
466checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
467
468[[package]]
469name = "num-traits"
470version = "0.2.19"
471source = "registry+https://github.com/rust-lang/crates.io-index"
472checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
473dependencies = [
474 "autocfg",
475]
476
477[[package]]
478name = "panic-probe"
479version = "1.0.0"
480source = "registry+https://github.com/rust-lang/crates.io-index"
481checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a"
482dependencies = [
483 "cortex-m",
484 "defmt",
485]
486
487[[package]]
488name = "paste"
489version = "1.0.15"
490source = "registry+https://github.com/rust-lang/crates.io-index"
491checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
492
493[[package]]
494name = "proc-macro-error-attr2"
495version = "2.0.0"
496source = "registry+https://github.com/rust-lang/crates.io-index"
497checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
498dependencies = [
499 "proc-macro2",
500 "quote",
501]
502
503[[package]]
504name = "proc-macro-error2"
505version = "2.0.1"
506source = "registry+https://github.com/rust-lang/crates.io-index"
507checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
508dependencies = [
509 "proc-macro-error-attr2",
510 "proc-macro2",
511 "quote",
512 "syn",
513]
514
515[[package]]
516name = "proc-macro2"
517version = "1.0.103"
518source = "registry+https://github.com/rust-lang/crates.io-index"
519checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
520dependencies = [
521 "unicode-ident",
522]
523
524[[package]]
525name = "quote"
526version = "1.0.42"
527source = "registry+https://github.com/rust-lang/crates.io-index"
528checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
529dependencies = [
530 "proc-macro2",
531]
532
533[[package]]
534name = "rustc_version"
535version = "0.2.3"
536source = "registry+https://github.com/rust-lang/crates.io-index"
537checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
538dependencies = [
539 "semver",
540]
541
542[[package]]
543name = "semver"
544version = "0.9.0"
545source = "registry+https://github.com/rust-lang/crates.io-index"
546checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
547dependencies = [
548 "semver-parser",
549]
550
551[[package]]
552name = "semver-parser"
553version = "0.7.0"
554source = "registry+https://github.com/rust-lang/crates.io-index"
555checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
556
557[[package]]
558name = "stable_deref_trait"
559version = "1.2.1"
560source = "registry+https://github.com/rust-lang/crates.io-index"
561checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
562
563[[package]]
564name = "strsim"
565version = "0.11.1"
566source = "registry+https://github.com/rust-lang/crates.io-index"
567checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
568
569[[package]]
570name = "syn"
571version = "2.0.110"
572source = "registry+https://github.com/rust-lang/crates.io-index"
573checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
574dependencies = [
575 "proc-macro2",
576 "quote",
577 "unicode-ident",
578]
579
580[[package]]
581name = "thiserror"
582version = "2.0.17"
583source = "registry+https://github.com/rust-lang/crates.io-index"
584checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
585dependencies = [
586 "thiserror-impl",
587]
588
589[[package]]
590name = "thiserror-impl"
591version = "2.0.17"
592source = "registry+https://github.com/rust-lang/crates.io-index"
593checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
594dependencies = [
595 "proc-macro2",
596 "quote",
597 "syn",
598]
599
600[[package]]
601name = "unicode-ident"
602version = "1.0.22"
603source = "registry+https://github.com/rust-lang/crates.io-index"
604checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
605
606[[package]]
607name = "vcell"
608version = "0.1.3"
609source = "registry+https://github.com/rust-lang/crates.io-index"
610checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
611
612[[package]]
613name = "void"
614version = "1.0.2"
615source = "registry+https://github.com/rust-lang/crates.io-index"
616checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
617
618[[package]]
619name = "volatile-register"
620version = "0.2.2"
621source = "registry+https://github.com/rust-lang/crates.io-index"
622checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
623dependencies = [
624 "vcell",
625]
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
new file mode 100644
index 000000000..6b100de42
--- /dev/null
+++ b/examples/Cargo.toml
@@ -0,0 +1,21 @@
1[package]
2name = "embassy-mcxa-examples"
3version = "0.1.0"
4edition = "2021"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
9cortex-m-rt = { version = "0.7", features = ["device"] }
10critical-section = "1.2.0"
11defmt = "1.0"
12defmt-rtt = "1.0"
13embassy-embedded-hal = "0.5.0"
14embassy-executor = { version = "0.9.0", features = ["arch-cortex-m", "executor-interrupt", "executor-thread"], default-features = false }
15embassy-mcxa = { path = "../", features = ["defmt", "rt", "unstable-pac"] }
16embassy-sync = "0.7.2"
17embassy-time = "0.5.0"
18embassy-time-driver = "0.2.1"
19embedded-io-async = "0.6.1"
20heapless = "0.9.2"
21panic-probe = { version = "1.0", features = ["print-defmt"] }
diff --git a/build.rs b/examples/build.rs
index 645843590..f076bba9f 100644
--- a/build.rs
+++ b/examples/build.rs
@@ -9,10 +9,10 @@ fn main() {
9 // Generate memory.x - put "FLASH" at start of RAM, RAM after "FLASH" 9 // Generate memory.x - put "FLASH" at start of RAM, RAM after "FLASH"
10 // cortex-m-rt expects FLASH for code, RAM for data/bss/stack 10 // cortex-m-rt expects FLASH for code, RAM for data/bss/stack
11 // Both are in RAM, but separated to satisfy cortex-m-rt's expectations 11 // Both are in RAM, but separated to satisfy cortex-m-rt's expectations
12 // MCXA276 has 128KB RAM total 12 // MCXA256 has 128KB RAM total
13 File::create(out.join("memory.x")) 13 File::create(out.join("memory.x"))
14 .unwrap() 14 .unwrap()
15 .write_all(b"/* MCXA276 RAM-execution: FLASH region holds code, RAM region for data/stack */\nMEMORY { FLASH : ORIGIN = 0x20000000, LENGTH = 64K\n RAM : ORIGIN = 0x20010000, LENGTH = 64K }\n") 15 .write_all(include_bytes!("memory.x"))
16 .unwrap(); 16 .unwrap();
17 17
18 println!("cargo:rustc-link-search={}", out.display()); 18 println!("cargo:rustc-link-search={}", out.display());
diff --git a/examples/memory.x b/examples/memory.x
new file mode 100644
index 000000000..f4263a412
--- /dev/null
+++ b/examples/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x20000000, LENGTH = 64K
4 RAM : ORIGIN = 0x20010000, LENGTH = 64K
5}
diff --git a/examples/adc_interrupt.rs b/examples/src/bin/adc_interrupt.rs
index 536152539..be08ebf8c 100644
--- a/examples/adc_interrupt.rs
+++ b/examples/src/bin/adc_interrupt.rs
@@ -2,19 +2,16 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276::clocks::periph_helpers::{AdcClockSel, Div4};
6use embassy_mcxa276::clocks::PoweredClock;
7use embassy_mcxa276::lpuart::{Config, Lpuart};
8use hal::adc::{LpadcConfig, TriggerPriorityPolicy}; 5use hal::adc::{LpadcConfig, TriggerPriorityPolicy};
9use mcxa_pac::adc1::cfg::{Pwrsel, Refsel}; 6use hal::clocks::periph_helpers::{AdcClockSel, Div4};
10use mcxa_pac::adc1::cmdl1::{Adch, Mode}; 7use hal::clocks::PoweredClock;
11use mcxa_pac::adc1::ctrl::CalAvgs; 8use hal::lpuart::{Config, Lpuart};
12use mcxa_pac::adc1::tctrl::Tcmd; 9use hal::pac::adc1::cfg::{Pwrsel, Refsel};
13use {embassy_mcxa276 as hal}; 10use hal::pac::adc1::cmdl1::{Adch, Mode};
14mod common; 11use hal::pac::adc1::ctrl::CalAvgs;
15 12use hal::pac::adc1::tctrl::Tcmd;
16use hal::{bind_interrupts, InterruptExt}; 13use hal::{bind_interrupts, InterruptExt};
17use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
18 15
19bind_interrupts!(struct Irqs { 16bind_interrupts!(struct Irqs {
20 ADC1 => hal::adc::AdcHandler; 17 ADC1 => hal::adc::AdcHandler;
@@ -38,7 +35,7 @@ async fn main(_spawner: Spawner) {
38 35
39 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 36 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
40 unsafe { 37 unsafe {
41 common::init_uart2(hal::pac()); 38 embassy_mcxa_examples::init_uart2(hal::pac());
42 } 39 }
43 let mut uart = Lpuart::new_blocking( 40 let mut uart = Lpuart::new_blocking(
44 p.LPUART2, // Peripheral 41 p.LPUART2, // Peripheral
@@ -47,9 +44,10 @@ async fn main(_spawner: Spawner) {
47 config, 44 config,
48 ) 45 )
49 .unwrap(); 46 .unwrap();
47 uart.write_str_blocking("\r\n=== ADC interrupt Example ===\r\n");
50 48
51 unsafe { 49 unsafe {
52 common::init_adc(hal::pac()); 50 embassy_mcxa_examples::init_adc(hal::pac());
53 } 51 }
54 52
55 let adc_config = LpadcConfig { 53 let adc_config = LpadcConfig {
diff --git a/examples/adc_polling.rs b/examples/src/bin/adc_polling.rs
index 2fe4153db..723f1e044 100644
--- a/examples/adc_polling.rs
+++ b/examples/src/bin/adc_polling.rs
@@ -1,23 +1,20 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner;
5use embassy_mcxa276::clocks::periph_helpers::{AdcClockSel, Div4};
6use embassy_mcxa276::clocks::PoweredClock;
7use embassy_mcxa276::lpuart::{Config, Lpuart};
8use embassy_mcxa276 as hal;
9use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy};
10use mcxa_pac::adc1::cfg::{Pwrsel, Refsel};
11use mcxa_pac::adc1::cmdl1::{Adch, Mode};
12use mcxa_pac::adc1::ctrl::CalAvgs;
13use mcxa_pac::adc1::tctrl::Tcmd;
14
15mod common;
16
17use core::fmt::Write; 4use core::fmt::Write;
18 5
6use embassy_executor::Spawner;
7use embassy_mcxa_examples::{init_adc, init_uart2};
8use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy};
9use hal::clocks::periph_helpers::{AdcClockSel, Div4};
10use hal::clocks::PoweredClock;
11use hal::lpuart::{Config, Lpuart};
12use hal::pac::adc1::cfg::{Pwrsel, Refsel};
13use hal::pac::adc1::cmdl1::{Adch, Mode};
14use hal::pac::adc1::ctrl::CalAvgs;
15use hal::pac::adc1::tctrl::Tcmd;
19use heapless::String; 16use heapless::String;
20use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
21 18
22const G_LPADC_RESULT_SHIFT: u32 = 0; 19const G_LPADC_RESULT_SHIFT: u32 = 0;
23 20
@@ -26,7 +23,7 @@ async fn main(_spawner: Spawner) {
26 let p = hal::init(hal::config::Config::default()); 23 let p = hal::init(hal::config::Config::default());
27 24
28 unsafe { 25 unsafe {
29 common::init_uart2(hal::pac()); 26 init_uart2(hal::pac());
30 } 27 }
31 28
32 // Create UART configuration 29 // Create UART configuration
@@ -39,7 +36,7 @@ async fn main(_spawner: Spawner) {
39 36
40 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 37 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
41 unsafe { 38 unsafe {
42 common::init_uart2(hal::pac()); 39 init_uart2(hal::pac());
43 } 40 }
44 let mut uart = Lpuart::new_blocking( 41 let mut uart = Lpuart::new_blocking(
45 p.LPUART2, // Peripheral 42 p.LPUART2, // Peripheral
@@ -49,10 +46,10 @@ async fn main(_spawner: Spawner) {
49 ) 46 )
50 .unwrap(); 47 .unwrap();
51 48
52 uart.blocking_write(b"\r\n=== ADC polling Example ===\r\n").unwrap(); 49 uart.write_str_blocking("\r\n=== ADC polling Example ===\r\n");
53 50
54 unsafe { 51 unsafe {
55 common::init_adc(hal::pac()); 52 init_adc(hal::pac());
56 } 53 }
57 54
58 let adc_config = LpadcConfig { 55 let adc_config = LpadcConfig {
diff --git a/examples/blink.rs b/examples/src/bin/blink.rs
index 0f489abb9..ee59ac591 100644
--- a/examples/blink.rs
+++ b/examples/src/bin/blink.rs
@@ -2,15 +2,13 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276 as hal; 5use embassy_mcxa as hal;
6use embassy_mcxa::bind_interrupts;
7use embassy_mcxa_examples::init_led;
6use embassy_time::{Duration, Timer}; 8use embassy_time::{Duration, Timer};
7use hal::gpio::pins::PIO3_18; 9use hal::gpio::pins::PIO3_18;
8use hal::gpio::{Level, Output}; 10use hal::gpio::{Level, Output};
9 11
10mod common;
11
12use embassy_mcxa276::bind_interrupts;
13
14// Bind only OS_EVENT for timer interrupts 12// Bind only OS_EVENT for timer interrupts
15bind_interrupts!(struct Irqs { 13bind_interrupts!(struct Irqs {
16 OS_EVENT => hal::ostimer::time_driver::OsEventHandler; 14 OS_EVENT => hal::ostimer::time_driver::OsEventHandler;
@@ -24,9 +22,8 @@ static KEEP_OS_EVENT: unsafe extern "C" fn() = OS_EVENT;
24async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
25 let _p = hal::init(hal::config::Config::default()); 23 let _p = hal::init(hal::config::Config::default());
26 24
27 // Board-style init: enable LED GPIO/PORT clocks used by blink
28 unsafe { 25 unsafe {
29 common::init_led(hal::pac()); 26 init_led(hal::pac());
30 } 27 }
31 28
32 // Initialize embassy-time global driver backed by OSTIMER0 29 // Initialize embassy-time global driver backed by OSTIMER0
diff --git a/examples/hello.rs b/examples/src/bin/hello.rs
index dbb53fdcf..ff7afa01d 100644
--- a/examples/hello.rs
+++ b/examples/src/bin/hello.rs
@@ -2,11 +2,8 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276::{self as hal, lpuart::{Blocking, Config, Lpuart}}; 5use hal::lpuart::{Blocking, Config, Lpuart};
6 6use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
7mod common;
8
9use {defmt_rtt as _, panic_probe as _};
10 7
11/// Simple helper to write a byte as hex to UART 8/// Simple helper to write a byte as hex to UART
12fn write_hex_byte(uart: &mut Lpuart<'_, Blocking>, byte: u8) { 9fn write_hex_byte(uart: &mut Lpuart<'_, Blocking>, byte: u8) {
@@ -31,7 +28,7 @@ async fn main(_spawner: Spawner) {
31 28
32 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 29 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
33 unsafe { 30 unsafe {
34 common::init_uart2(hal::pac()); 31 embassy_mcxa_examples::init_uart2(hal::pac());
35 } 32 }
36 let mut uart = Lpuart::new_blocking( 33 let mut uart = Lpuart::new_blocking(
37 p.LPUART2, // Peripheral 34 p.LPUART2, // Peripheral
diff --git a/examples/lpuart_buffered.rs b/examples/src/bin/lpuart_buffered.rs
index 9e297ca67..e96ab7b81 100644
--- a/examples/lpuart_buffered.rs
+++ b/examples/src/bin/lpuart_buffered.rs
@@ -2,14 +2,13 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276 as hal; 5use embassy_mcxa as hal;
6use embassy_mcxa276::interrupt::typelevel::Handler; 6use embassy_mcxa::interrupt::typelevel::Handler;
7use embassy_mcxa276::lpuart::buffered::BufferedLpuart; 7use embassy_mcxa::lpuart::buffered::BufferedLpuart;
8use embassy_mcxa276::{bind_interrupts, lpuart}; 8use embassy_mcxa::{bind_interrupts, lpuart};
9use embassy_mcxa_examples::init_uart2;
9use embedded_io_async::{Read, Write}; 10use embedded_io_async::{Read, Write};
10 11
11mod common;
12
13// Bind OS_EVENT for timers plus LPUART2 IRQ for the buffered driver 12// Bind OS_EVENT for timers plus LPUART2 IRQ for the buffered driver
14bind_interrupts!(struct Irqs { 13bind_interrupts!(struct Irqs {
15 LPUART2 => lpuart::buffered::BufferedInterruptHandler::<hal::peripherals::LPUART2>; 14 LPUART2 => lpuart::buffered::BufferedInterruptHandler::<hal::peripherals::LPUART2>;
@@ -25,14 +24,14 @@ async fn main(_spawner: Spawner) {
25 let p = hal::init(hal::config::Config::default()); 24 let p = hal::init(hal::config::Config::default());
26 25
27 unsafe { 26 unsafe {
28 hal::interrupt::install_irq_handler(mcxa_pac::Interrupt::LPUART2, lpuart2_handler); 27 hal::interrupt::install_irq_handler(hal::pac::Interrupt::LPUART2, lpuart2_handler);
29 } 28 }
30 29
31 // Configure NVIC for LPUART2 30 // Configure NVIC for LPUART2
32 hal::interrupt::LPUART2.configure_for_uart(hal::interrupt::Priority::P3); 31 hal::interrupt::LPUART2.configure_for_uart(hal::interrupt::Priority::P3);
33 32
34 unsafe { 33 unsafe {
35 common::init_uart2(hal::pac()); 34 init_uart2(hal::pac());
36 } 35 }
37 36
38 // UART configuration (enable both TX and RX) 37 // UART configuration (enable both TX and RX)
diff --git a/examples/lpuart_polling.rs b/examples/src/bin/lpuart_polling.rs
index c9630dca5..bdcfa0776 100644
--- a/examples/lpuart_polling.rs
+++ b/examples/src/bin/lpuart_polling.rs
@@ -2,12 +2,11 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use {defmt_rtt as _, embassy_mcxa276 as hal, panic_probe as _}; 5use embassy_mcxa_examples::init_uart2;
6use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
6 7
7use crate::hal::lpuart::{Config, Lpuart}; 8use crate::hal::lpuart::{Config, Lpuart};
8 9
9mod common;
10
11#[embassy_executor::main] 10#[embassy_executor::main]
12async fn main(_spawner: Spawner) { 11async fn main(_spawner: Spawner) {
13 let p = hal::init(hal::config::Config::default()); 12 let p = hal::init(hal::config::Config::default());
@@ -16,7 +15,7 @@ async fn main(_spawner: Spawner) {
16 15
17 // Board-level init for UART2 clocks and pins. 16 // Board-level init for UART2 clocks and pins.
18 unsafe { 17 unsafe {
19 common::init_uart2(hal::pac()); 18 init_uart2(hal::pac());
20 } 19 }
21 20
22 // Create UART configuration 21 // Create UART configuration
diff --git a/examples/ostimer_alarm.rs b/examples/src/bin/ostimer_alarm.rs
index f3a84d312..9e858b60b 100644
--- a/examples/ostimer_alarm.rs
+++ b/examples/src/bin/ostimer_alarm.rs
@@ -4,16 +4,12 @@
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, Ordering};
5 5
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_mcxa276 as hal; 7use embassy_mcxa::bind_interrupts;
8 8use embassy_mcxa::clocks::periph_helpers::OstimerClockSel;
9mod common; 9use embassy_mcxa::clocks::PoweredClock;
10 10use embassy_mcxa::lpuart::{Config, Lpuart};
11use embassy_mcxa276::{ 11use embassy_mcxa_examples::init_uart2;
12 bind_interrupts, 12use {cortex_m, defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
13 clocks::{periph_helpers::OstimerClockSel, PoweredClock},
14 lpuart::{Config, Lpuart},
15};
16use {defmt_rtt as _, panic_probe as _};
17 13
18// Bind only OS_EVENT, and retain the symbol explicitly so it can't be GC'ed. 14// Bind only OS_EVENT, and retain the symbol explicitly so it can't be GC'ed.
19bind_interrupts!(struct Irqs { 15bind_interrupts!(struct Irqs {
@@ -46,7 +42,7 @@ async fn main(_spawner: Spawner) {
46 42
47 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 43 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
48 unsafe { 44 unsafe {
49 common::init_uart2(hal::pac()); 45 init_uart2(hal::pac());
50 } 46 }
51 let mut uart = Lpuart::new_blocking( 47 let mut uart = Lpuart::new_blocking(
52 p.LPUART2, // Peripheral 48 p.LPUART2, // Peripheral
diff --git a/examples/ostimer_async.rs b/examples/src/bin/ostimer_async.rs
index 2642a633d..4e692a744 100644
--- a/examples/ostimer_async.rs
+++ b/examples/src/bin/ostimer_async.rs
@@ -2,13 +2,10 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276::{self as hal, lpuart::{Config, Lpuart}}; 5use embassy_mcxa::bind_interrupts;
6 6use embassy_mcxa_examples::init_uart2;
7mod common;
8
9use embassy_mcxa276::bind_interrupts;
10use embassy_time::{Duration, Timer}; 7use embassy_time::{Duration, Timer};
11use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
12 9
13// Bind only OS_EVENT, and retain the symbol explicitly so it can’t be GC’ed. 10// Bind only OS_EVENT, and retain the symbol explicitly so it can’t be GC’ed.
14bind_interrupts!(struct Irqs { 11bind_interrupts!(struct Irqs {
@@ -24,7 +21,7 @@ async fn main(_spawner: Spawner) {
24 let p = hal::init(hal::config::Config::default()); 21 let p = hal::init(hal::config::Config::default());
25 22
26 // Create UART configuration 23 // Create UART configuration
27 let config = Config { 24 let config = hal::lpuart::Config {
28 baudrate_bps: 115_200, 25 baudrate_bps: 115_200,
29 enable_tx: true, 26 enable_tx: true,
30 enable_rx: true, 27 enable_rx: true,
@@ -33,9 +30,9 @@ async fn main(_spawner: Spawner) {
33 30
34 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 31 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
35 unsafe { 32 unsafe {
36 common::init_uart2(hal::pac()); 33 init_uart2(hal::pac());
37 } 34 }
38 let mut uart = Lpuart::new_blocking( 35 let mut uart = hal::lpuart::Lpuart::new_blocking(
39 p.LPUART2, // Peripheral 36 p.LPUART2, // Peripheral
40 p.PIO2_2, // TX pin 37 p.PIO2_2, // TX pin
41 p.PIO2_3, // RX pin 38 p.PIO2_3, // RX pin
diff --git a/examples/ostimer_counter.rs b/examples/src/bin/ostimer_counter.rs
index 590c5a14b..47543160b 100644
--- a/examples/ostimer_counter.rs
+++ b/examples/src/bin/ostimer_counter.rs
@@ -7,15 +7,12 @@
7#![no_main] 7#![no_main]
8 8
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_mcxa276::{ 10use embassy_mcxa::clocks::periph_helpers::OstimerClockSel;
11 clocks::{periph_helpers::OstimerClockSel, PoweredClock}, 11use embassy_mcxa::clocks::PoweredClock;
12 lpuart::{Blocking, Config, Lpuart}, 12use embassy_mcxa::lpuart::{Blocking, Config, Lpuart};
13};
14use embassy_time::{Duration, Timer}; 13use embassy_time::{Duration, Timer};
15use hal::bind_interrupts; 14use hal::bind_interrupts;
16use {defmt_rtt as _, embassy_mcxa276 as hal, panic_probe as _}; 15use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
17
18mod common;
19 16
20bind_interrupts!(struct Irqs { 17bind_interrupts!(struct Irqs {
21 OS_EVENT => hal::ostimer::time_driver::OsEventHandler; 18 OS_EVENT => hal::ostimer::time_driver::OsEventHandler;
@@ -35,7 +32,7 @@ async fn main(_spawner: Spawner) {
35 32
36 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 33 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
37 unsafe { 34 unsafe {
38 common::init_uart2(hal::pac()); 35 embassy_mcxa_examples::init_uart2(hal::pac());
39 } 36 }
40 let mut uart = Lpuart::new_blocking( 37 let mut uart = Lpuart::new_blocking(
41 p.LPUART2, // Peripheral 38 p.LPUART2, // Peripheral
diff --git a/examples/ostimer_race_test.rs b/examples/src/bin/ostimer_race_test.rs
index 131d10f64..c2ecff969 100644
--- a/examples/ostimer_race_test.rs
+++ b/examples/src/bin/ostimer_race_test.rs
@@ -12,15 +12,12 @@
12use core::sync::atomic::{AtomicU32, Ordering}; 12use core::sync::atomic::{AtomicU32, Ordering};
13 13
14use embassy_executor::Spawner; 14use embassy_executor::Spawner;
15use embassy_mcxa276::{ 15use embassy_mcxa::clocks::periph_helpers::OstimerClockSel;
16 clocks::{periph_helpers::OstimerClockSel, PoweredClock}, 16use embassy_mcxa::clocks::PoweredClock;
17 lpuart::{Blocking, Config, Lpuart}, 17use embassy_mcxa::lpuart::{Blocking, Config, Lpuart};
18};
19use embassy_time::{Duration, Timer}; 18use embassy_time::{Duration, Timer};
20use hal::bind_interrupts; 19use hal::bind_interrupts;
21use {defmt_rtt as _, embassy_mcxa276 as hal, panic_probe as _}; 20use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
22
23mod common;
24 21
25bind_interrupts!(struct Irqs { 22bind_interrupts!(struct Irqs {
26 OS_EVENT => hal::ostimer::time_driver::OsEventHandler; 23 OS_EVENT => hal::ostimer::time_driver::OsEventHandler;
@@ -85,7 +82,7 @@ async fn main(_spawner: Spawner) {
85 82
86 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 83 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
87 unsafe { 84 unsafe {
88 common::init_uart2(hal::pac()); 85 embassy_mcxa_examples::init_uart2(hal::pac());
89 } 86 }
90 let mut uart = Lpuart::new_blocking( 87 let mut uart = Lpuart::new_blocking(
91 p.LPUART2, // Peripheral 88 p.LPUART2, // Peripheral
@@ -281,7 +278,7 @@ async fn test_concurrent_operations(
281async fn test_reset_during_operation( 278async fn test_reset_during_operation(
282 ostimer: &hal::ostimer::Ostimer<'_, hal::ostimer::Ostimer0>, 279 ostimer: &hal::ostimer::Ostimer<'_, hal::ostimer::Ostimer0>,
283 uart: &mut Lpuart<'_, Blocking>, 280 uart: &mut Lpuart<'_, Blocking>,
284 peripherals: &mcxa_pac::Peripherals, 281 peripherals: &hal::pac::Peripherals,
285) { 282) {
286 let initial_counter = ostimer.now(); 283 let initial_counter = ostimer.now();
287 284
diff --git a/examples/rtc_alarm.rs b/examples/src/bin/rtc_alarm.rs
index 1cda37054..e2eaa6ae2 100644
--- a/examples/rtc_alarm.rs
+++ b/examples/src/bin/rtc_alarm.rs
@@ -2,16 +2,13 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa276::lpuart::{Config, Lpuart};
6use hal::rtc::{RtcDateTime, RtcInterruptEnable}; 5use hal::rtc::{RtcDateTime, RtcInterruptEnable};
7use hal::InterruptExt; 6use hal::InterruptExt;
8use {embassy_mcxa276 as hal}; 7use {cortex_m, embassy_mcxa as hal};
9
10mod common;
11 8
12type MyRtc = hal::rtc::Rtc<'static, hal::rtc::Rtc0>; 9type MyRtc = hal::rtc::Rtc<'static, hal::rtc::Rtc0>;
13 10
14use embassy_mcxa276::bind_interrupts; 11use embassy_mcxa::bind_interrupts;
15use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
16 13
17bind_interrupts!(struct Irqs { 14bind_interrupts!(struct Irqs {
@@ -27,7 +24,7 @@ async fn main(_spawner: Spawner) {
27 let p = hal::init(hal::config::Config::default()); 24 let p = hal::init(hal::config::Config::default());
28 25
29 // Create UART configuration 26 // Create UART configuration
30 let config = Config { 27 let config = hal::lpuart::Config {
31 baudrate_bps: 115_200, 28 baudrate_bps: 115_200,
32 enable_tx: true, 29 enable_tx: true,
33 enable_rx: true, 30 enable_rx: true,
@@ -36,9 +33,9 @@ async fn main(_spawner: Spawner) {
36 33
37 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX 34 // Create UART instance using LPUART2 with PIO2_2 as TX and PIO2_3 as RX
38 unsafe { 35 unsafe {
39 common::init_uart2(hal::pac()); 36 embassy_mcxa_examples::init_uart2(hal::pac());
40 } 37 }
41 let mut uart = Lpuart::new_blocking( 38 let mut uart = hal::lpuart::Lpuart::new_blocking(
42 p.LPUART2, // Peripheral 39 p.LPUART2, // Peripheral
43 p.PIO2_2, // TX pin 40 p.PIO2_2, // TX pin
44 p.PIO2_3, // RX pin 41 p.PIO2_3, // RX pin
@@ -94,6 +91,4 @@ async fn main(_spawner: Spawner) {
94 } 91 }
95 92
96 uart.write_str_blocking("Example complete - Test PASSED!\r\n"); 93 uart.write_str_blocking("Example complete - Test PASSED!\r\n");
97
98 loop {}
99} 94}
diff --git a/examples/common/mod.rs b/examples/src/lib.rs
index 7b197a590..a45ab708d 100644
--- a/examples/common/mod.rs
+++ b/examples/src/lib.rs
@@ -1,13 +1,15 @@
1#![no_std]
2
1//! Shared board-specific helpers for the FRDM-MCXA276 examples. 3//! Shared board-specific helpers for the FRDM-MCXA276 examples.
2//! These live with the examples so the HAL stays generic. 4//! These live with the examples so the HAL stays generic.
3 5
4use hal::{clocks, pins}; 6use hal::{clocks, pins};
5use {embassy_mcxa276 as hal, panic_probe as _}; 7use {embassy_mcxa as hal, panic_probe as _};
6 8
7/// Initialize clocks and pin muxing for UART2 debug console. 9/// Initialize clocks and pin muxing for UART2 debug console.
8/// Safe to call multiple times; writes are idempotent for our use. 10/// Safe to call multiple times; writes are idempotent for our use.
9#[allow(dead_code)] 11#[allow(dead_code)]
10pub unsafe fn init_uart2(_p: &mcxa_pac::Peripherals) { 12pub unsafe fn init_uart2(_p: &hal::pac::Peripherals) {
11 // NOTE: Lpuart has been updated to properly enable + reset its own clocks. 13 // NOTE: Lpuart has been updated to properly enable + reset its own clocks.
12 // GPIO has not. 14 // GPIO has not.
13 _ = clocks::enable_and_reset::<hal::peripherals::PORT2>(&clocks::NoConfig); 15 _ = clocks::enable_and_reset::<hal::peripherals::PORT2>(&clocks::NoConfig);
@@ -16,14 +18,14 @@ pub unsafe fn init_uart2(_p: &mcxa_pac::Peripherals) {
16 18
17/// Initialize clocks for the LED GPIO/PORT used by the blink example. 19/// Initialize clocks for the LED GPIO/PORT used by the blink example.
18#[allow(dead_code)] 20#[allow(dead_code)]
19pub unsafe fn init_led(_p: &mcxa_pac::Peripherals) { 21pub unsafe fn init_led(_p: &hal::pac::Peripherals) {
20 _ = clocks::enable_and_reset::<hal::peripherals::PORT3>(&clocks::NoConfig); 22 _ = clocks::enable_and_reset::<hal::peripherals::PORT3>(&clocks::NoConfig);
21 _ = clocks::enable_and_reset::<hal::peripherals::GPIO3>(&clocks::NoConfig); 23 _ = clocks::enable_and_reset::<hal::peripherals::GPIO3>(&clocks::NoConfig);
22} 24}
23 25
24/// Initialize clocks and pin muxing for ADC. 26/// Initialize clocks and pin muxing for ADC.
25#[allow(dead_code)] 27#[allow(dead_code)]
26pub unsafe fn init_adc(_p: &mcxa_pac::Peripherals) { 28pub unsafe fn init_adc(_p: &hal::pac::Peripherals) {
27 // NOTE: Lpuart has been updated to properly enable + reset its own clocks. 29 // NOTE: Lpuart has been updated to properly enable + reset its own clocks.
28 // GPIO has not. 30 // GPIO has not.
29 _ = clocks::enable_and_reset::<hal::peripherals::PORT1>(&clocks::NoConfig); 31 _ = clocks::enable_and_reset::<hal::peripherals::PORT1>(&clocks::NoConfig);
diff --git a/memory.x b/memory.x
deleted file mode 100644
index b47534f18..000000000
--- a/memory.x
+++ /dev/null
@@ -1,10 +0,0 @@
1/* Memory layout for MCXA276 - RAM execution with cortex-m-rt */
2MEMORY
3{
4 /* FLASH and RAM overlap for RAM-execution experiments. */
5 FLASH : ORIGIN = 0x20000000, LENGTH = 128K
6 /* RAM overlaps FLASH */
7 RAM : ORIGIN = 0x20000000, LENGTH = 128K
8}
9
10/* Leave symbol and section boundary definitions to cortex-m-rt's link.x. */
diff --git a/src/lib.rs b/src/lib.rs
index ec2cb31e7..1bf54a98b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -59,29 +59,29 @@ pub fn init(cfg: crate::config::Config) -> Peripherals {
59 peripherals 59 peripherals
60} 60}
61 61
62/// Optional hook called by cortex-m-rt before RAM init. 62// /// Optional hook called by cortex-m-rt before RAM init.
63/// We proactively mask and clear all NVIC IRQs to avoid wedges from stale state 63// /// We proactively mask and clear all NVIC IRQs to avoid wedges from stale state
64/// left by soft resets/debug sessions. 64// /// left by soft resets/debug sessions.
65/// 65// ///
66/// NOTE: Manual VTOR setup is required for RAM execution. The cortex-m-rt 'set-vtor' 66// /// NOTE: Manual VTOR setup is required for RAM execution. The cortex-m-rt 'set-vtor'
67/// feature is incompatible with our setup because it expects __vector_table to be 67// /// feature is incompatible with our setup because it expects __vector_table to be
68/// defined differently than how our RAM-based linker script arranges it. 68// /// defined differently than how our RAM-based linker script arranges it.
69#[no_mangle] 69// #[no_mangle]
70pub unsafe extern "C" fn __pre_init() { 70// pub unsafe extern "C" fn __pre_init() {
71 // Set the VTOR to point to the interrupt vector table in RAM 71// // Set the VTOR to point to the interrupt vector table in RAM
72 // This is required since code runs from RAM on this MCU 72// // This is required since code runs from RAM on this MCU
73 crate::interrupt::vtor_set_ram_vector_base(0x2000_0000 as *const u32); 73// crate::interrupt::vtor_set_ram_vector_base(0x2000_0000 as *const u32);
74 74
75 // Mask and clear pending for all NVIC lines (0..127) to avoid stale state across runs. 75// // Mask and clear pending for all NVIC lines (0..127) to avoid stale state across runs.
76 let nvic = &*cortex_m::peripheral::NVIC::PTR; 76// let nvic = &*cortex_m::peripheral::NVIC::PTR;
77 for i in 0..4 { 77// for i in 0..4 {
78 // 4 words x 32 = 128 IRQs 78// // 4 words x 32 = 128 IRQs
79 nvic.icer[i].write(0xFFFF_FFFF); 79// nvic.icer[i].write(0xFFFF_FFFF);
80 nvic.icpr[i].write(0xFFFF_FFFF); 80// nvic.icpr[i].write(0xFFFF_FFFF);
81 } 81// }
82 // Do NOT touch peripheral registers here: clocks may be off and accesses can fault. 82// // Do NOT touch peripheral registers here: clocks may be off and accesses can fault.
83 crate::interrupt::clear_default_handler_snapshot(); 83// crate::interrupt::clear_default_handler_snapshot();
84} 84// }
85 85
86/// Internal helper to dispatch a type-level interrupt handler. 86/// Internal helper to dispatch a type-level interrupt handler.
87#[inline(always)] 87#[inline(always)]
diff --git a/src/ostimer.rs b/src/ostimer.rs
index ebdf7d45d..cd5451b53 100644
--- a/src/ostimer.rs
+++ b/src/ostimer.rs
@@ -534,7 +534,10 @@ pub mod time_driver {
534 bin_to_gray, now_ticks_read, Regs, ALARM_ACTIVE, ALARM_CALLBACK, ALARM_FLAG, ALARM_TARGET_TIME, 534 bin_to_gray, now_ticks_read, Regs, ALARM_ACTIVE, ALARM_CALLBACK, ALARM_FLAG, ALARM_TARGET_TIME,
535 EVTIMER_HI_MASK, EVTIMER_HI_SHIFT, LOW_32_BIT_MASK, 535 EVTIMER_HI_MASK, EVTIMER_HI_SHIFT, LOW_32_BIT_MASK,
536 }; 536 };
537 use crate::{clocks::{enable_and_reset, periph_helpers::{OsTimerConfig, OstimerClockSel}, PoweredClock}, pac, peripherals::OSTIMER0}; 537 use crate::clocks::periph_helpers::{OsTimerConfig, OstimerClockSel};
538 use crate::clocks::{enable_and_reset, PoweredClock};
539 use crate::pac;
540 use crate::peripherals::OSTIMER0;
538 pub struct Driver; 541 pub struct Driver;
539 static TIMER_WAKER: AtomicWaker = AtomicWaker::new(); 542 static TIMER_WAKER: AtomicWaker = AtomicWaker::new();
540 543
diff --git a/src/rtc.rs b/src/rtc.rs
index f526e82ac..b750a97ea 100644
--- a/src/rtc.rs
+++ b/src/rtc.rs
@@ -163,9 +163,7 @@ impl<'a, I: Instance> Rtc<'a, I> {
163 163
164 // The RTC is NOT gated by the MRCC, but we DO need to make sure the 16k clock 164 // The RTC is NOT gated by the MRCC, but we DO need to make sure the 16k clock
165 // on the vsys domain is active 165 // on the vsys domain is active
166 let clocks = with_clocks(|c| { 166 let clocks = with_clocks(|c| c.clk_16k_vsys.clone());
167 c.clk_16k_vsys.clone()
168 });
169 match clocks { 167 match clocks {
170 None => panic!("Clocks have not been initialized"), 168 None => panic!("Clocks have not been initialized"),
171 Some(None) => panic!("Clocks initialized, but clk_16k_vsys not active"), 169 Some(None) => panic!("Clocks initialized, but clk_16k_vsys not active"),