diff --git a/hal_test/.cargo/config.toml b/hal_test/.cargo/config.toml new file mode 100644 index 0000000..793e2c8 --- /dev/null +++ b/hal_test/.cargo/config.toml @@ -0,0 +1,22 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = ["probe-rs", "run", "--chip", "STM32U575ZI", "--log-format=oneline"] + +rustflags = [ + "-C", "linker=flip-link", + "-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tdefmt.x", + "-C", "link-arg=--nmagic", +] + +[build] +target = "thumbv8m.main-none-eabihf" + +[target.thumbv8m.main-none-eabihf] +runner = "probe-rs run --chip STM32U575ZI" + +[alias] +rb = "run --bin" +rrb = "run --release --bin" + +[env] +DEFMT_LOG = "info" diff --git a/hal_test/.gitignore b/hal_test/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/hal_test/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/hal_test/Cargo.toml b/hal_test/Cargo.toml new file mode 100644 index 0000000..2962bab --- /dev/null +++ b/hal_test/Cargo.toml @@ -0,0 +1,42 @@ +[package] +# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate` +authors = ["Priec "] +name = "stm32u5-blinky" +edition = "2024" +version = "0.1.0" + + +[dependencies] +cortex-m = { version = "0.7", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7" +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } +embassy-stm32 = { version = "0.4.0", features = ["stm32u575zi", "time-driver-tim1", "defmt", "low-power", "memory-x"] } +embassy-time = "0.5.0" +semihosting = "0.1.20" +embedded-hal = "1.0.0" + +[dev-dependencies] +defmt-test = "0.3" + +# cargo build/run +[profile.dev] +# default is opt-level = '0', but that makes very +# verbose machine code +opt-level = 's' +# trade compile speed for slightly better optimisations +codegen-units = 1 + +# cargo build/run --release +[profile.release] +# default is opt-level = '3', but that makes quite +# verbose machine code +opt-level = 's' +# trade compile speed for slightly better optimisations +codegen-units = 1 +# Use Link Time Optimisations to further inline things across +# crates +lto = 'fat' +# Leave the debug symbols in (default is no debug info) +debug = 2 diff --git a/hal_test/LICENSE-APACHE b/hal_test/LICENSE-APACHE new file mode 100644 index 0000000..11069ed --- /dev/null +++ b/hal_test/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/hal_test/LICENSE-MIT b/hal_test/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/hal_test/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/hal_test/README.md b/hal_test/README.md new file mode 100644 index 0000000..05d63c4 --- /dev/null +++ b/hal_test/README.md @@ -0,0 +1,232 @@ +# `app-template` + +> Quickly set up a [`probe-rs`] + [`defmt`] + [`flip-link`] embedded project + +[`probe-rs`]: https://crates.io/crates/probe-rs +[`defmt`]: https://github.com/knurling-rs/defmt +[`flip-link`]: https://github.com/knurling-rs/flip-link + +## Dependencies + +### 1. `flip-link`: + +```bash +cargo install flip-link +``` + +### 2. `probe-rs`: + +Install probe-rs by following the instructions at . + +### 3. [`cargo-generate`]: + +```bash +cargo install cargo-generate +``` + +[`cargo-generate`]: https://crates.io/crates/cargo-generate + +> *Note:* You can also just clone this repository instead of using `cargo-generate`, but this involves additional manual adjustments. + +## Setup + +### 1. Initialize the project template + +```bash +cargo generate \ + --git https://github.com/knurling-rs/app-template \ + --branch main \ + --name my-app +``` + +If you look into your new `my-app` folder, you'll find that there are a few `TODO`s in the files marking the properties you need to set. + +Let's walk through them together now. + +### 2. Set `probe-rs` chip + +Pick a chip from ` probe-rs chip list` and enter it into `.cargo/config.toml`. + +If, for example, you have a nRF52840 Development Kit as used in one of [our exercises], replace `{{chip}}` with `nRF52840_xxAA`. + +[our workshops]: https://rust-exercises.ferrous-systems.com + +```diff + # .cargo/config.toml +-runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format=oneline"] ++runner = ["probe-rs", "run", "--chip", "nRF52840_xxAA", "--log-format=oneline"] +``` + +### 3. Adjust the compilation target + +In `.cargo/config.toml`, pick the right compilation target for your board. + +```diff + # .cargo/config.toml + [build] +-target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +-# target = "thumbv7m-none-eabi" # Cortex-M3 +-# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +-# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) ++target = "thumbv7em-none-eabihf" # Cortex-M4F (with FPU) +``` + +Add the target with `rustup`. + +```bash +rustup target add thumbv7em-none-eabihf +``` + +### 4. Add a HAL as a dependency + +In `Cargo.toml`, list the Hardware Abstraction Layer (HAL) for your board as a dependency. + +For the nRF52840 you'll want to use the [`nrf52840-hal`]. + +[`nrf52840-hal`]: https://crates.io/crates/nrf52840-hal + +```diff + # Cargo.toml + [dependencies] +-# some-hal = "1.2.3" ++nrf52840-hal = "0.14.0" +``` + +⚠️ Note for RP2040 users ⚠️ + +You will need to not just specify the `rp-hal` HAL, but a BSP (board support crate) which includes a second stage bootloader. Please find a list of available BSPs [here](https://github.com/rp-rs/rp-hal-boards#packages). + +### 5. Import your HAL + +Now that you have selected a HAL, fix the HAL import in `src/lib.rs` + +```diff + // my-app/src/lib.rs +-// use some_hal as _; // memory layout ++use nrf52840_hal as _; // memory layout +``` + +### (6. Get a linker script) + +Some HAL crates require that you manually copy over a file called `memory.x` from the HAL to the root of your project. For nrf52840-hal, this is done automatically so no action is needed. For other HAL crates, see their documentation on where to find an example file. + +The `memory.x` file should look something like: + +```text +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 1024K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} +``` + +The `memory.x` file is included in the `cortex-m-rt` linker script `link.x`, and so `link.x` is the one you should tell `rustc` to use (see the `.cargo/config.toml` file where we do that). + +### 7. Run! + +You are now all set to `cargo-run` your first `defmt`-powered application! +There are some examples in the `src/bin` directory. + +Start by `cargo run`-ning `my-app/src/bin/hello.rs`: + +```console +$ # `rb` is an alias for `run --bin` +$ cargo rb hello + Finished `dev` profile [optimized + debuginfo] target(s) in 0.01s + Running `probe-rs run --chip nrf52840_xxaa --log-format=oneline target/thumbv6m-none-eabi/debug/hello` + Erasing ✔ 100% [####################] 8.00 KiB @ 15.79 KiB/s (took 1s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.19 KiB/s (took 1s) Finished in 1.11s +Hello, world! + +$ echo $? +0 +``` + +If you're running out of memory (`flip-link` bails with an overflow error), you can decrease the size of the device memory buffer by setting the `DEFMT_RTT_BUFFER_SIZE` environment variable. The default value is 1024 bytes, and powers of two should be used for optimal performance: + +```console +$ DEFMT_RTT_BUFFER_SIZE=64 cargo rb hello +``` + +### (8. Set `rust-analyzer.linkedProjects`) + +If you are using [rust-analyzer] with VS Code for IDE-like features you can add following configuration to your `.vscode/settings.json` to make it work transparently across workspaces. Find the details of this option in the [RA docs]. + +```json +{ + "rust-analyzer.linkedProjects": [ + "Cargo.toml", + "firmware/Cargo.toml", + ] +} +``` + +[RA docs]: https://rust-analyzer.github.io/manual.html#configuration +[rust-analyzer]: https://rust-analyzer.github.io/ + +## Running tests + +The template comes configured for running unit tests and integration tests on the target. + +Unit tests reside in the library crate and can test private API; the initial set of unit tests are in `src/lib.rs`. +`cargo test --lib` will run those unit tests. + +```console +$ cargo test --lib + Compiling example v0.1.0 (./knurling-rs/example) + Finished `test` profile [optimized + debuginfo] target(s) in 0.15s + Running unittests src/lib.rs (target/thumbv6m-none-eabi/debug/deps/example-2b0d0e25d141bf57) + Erasing ✔ 100% [####################] 8.00 KiB @ 15.99 KiB/s (took 1s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.33 KiB/s (took 1s) Finished in 1.10s +(1/1) running `it_works`... +all tests passed! +``` + +Integration tests reside in the `tests` directory; the initial set of integration tests are in `tests/integration.rs`. +`cargo test --test integration` will run those integration tests. +Note that the argument of the `--test` flag must match the name of the test file in the `tests` directory. + +```console +$ cargo test --test integration + Compiling example v0.1.0 (./knurling-rs/example) + Finished `test` profile [optimized + debuginfo] target(s) in 0.10s + Running tests/integration.rs (target/thumbv6m-none-eabi/debug/deps/integration-aaaff41151f6a722) + Erasing ✔ 100% [####################] 8.00 KiB @ 16.03 KiB/s (took 0s) + Programming ✔ 100% [####################] 8.00 KiB @ 13.19 KiB/s (took 1s) Finished in 1.11s +(1/1) running `it_works`... +all tests passed! +``` + +Note that to add a new test file to the `tests` directory you also need to add a new `[[test]]` section to `Cargo.toml`. + +To run all the tests via `cargo test` the tests need to be explicitly disabled for all the existing binary targets. +See `Cargo.toml` for details on how to do this. + +## Support + +`app-template` is part of the [Knurling] project, [Ferrous Systems]' effort at +improving tooling used to develop for embedded systems. + +If you think that our work is useful, consider sponsoring it via [GitHub +Sponsors]. + +## License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +licensed as above, without any additional terms or conditions. + +[Knurling]: https://knurling.ferrous-systems.com +[Ferrous Systems]: https://ferrous-systems.com/ +[GitHub Sponsors]: https://github.com/sponsors/knurling-rs diff --git a/hal_test/memory.x b/hal_test/memory.x new file mode 100644 index 0000000..89f96e1 --- /dev/null +++ b/hal_test/memory.x @@ -0,0 +1,13 @@ +/* memory.x - STM32U575ZITxQ memory layout */ + +/* Flash: 2 MB starting at 0x08000000 */ +/* SRAM1 + SRAM2 + SRAM3 total 786 KB starting at 0x20000000 */ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 786K +} + +/* provide stack start symbol (end of RAM) */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal_test/src/bin/main.rs b/hal_test/src/bin/main.rs new file mode 100644 index 0000000..f76a673 --- /dev/null +++ b/hal_test/src/bin/main.rs @@ -0,0 +1,30 @@ +// src/bin/main.rs + +#![no_std] +#![no_main] + +use defmt_rtt as _; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::Config; +use embassy_time::Delay; +use embedded_hal::delay::DelayNs; +use panic_probe as _; + +#[cortex_m_rt::entry] +fn main() -> ! { + defmt::info!("Starting blinky on STM32U575ZI-Q..."); + + // Initialize peripherals with the default clock tree for STM32U5. + let p = embassy_stm32::init(Config::default()); + + // On‑board LED (PB7 on NUCLEO‑U575ZI‑Q) + let mut led = Output::new(p.PB7, Level::Low, Speed::Low); + let mut delay = Delay; + + loop { + led.set_high(); + delay.delay_ms(500); // needs embedded_hal::delay::DelayNs in scope + led.set_low(); + delay.delay_ms(500); + } +} diff --git a/hal_test/src/lib.rs b/hal_test/src/lib.rs new file mode 100644 index 0000000..deac2a0 --- /dev/null +++ b/hal_test/src/lib.rs @@ -0,0 +1,46 @@ +#![no_main] +#![no_std] + +use defmt_rtt as _; // global logger + +// TODO(5) adjust HAL import +// use some_hal as _; // memory layout + +use panic_probe as _; + +// same panicking *behavior* as `panic-probe` but doesn't print a panic message +// this prevents the panic message being printed *twice* when `defmt::panic` is invoked +#[defmt::panic_handler] +fn panic() -> ! { + cortex_m::asm::udf() +} + +/// Terminates the application and makes a semihosting-capable debug tool exit +/// with status code 0. +pub fn exit() -> ! { + semihosting::process::exit(0); +} + +/// Hardfault handler. +/// +/// Terminates the application and makes a semihosting-capable debug tool exit +/// with an error. This seems better than the default, which is to spin in a +/// loop. +#[cortex_m_rt::exception] +unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! { + semihosting::process::exit(1); +} + +// defmt-test 0.3.0 has the limitation that this `#[tests]` attribute can only be used +// once within a crate. the module can be in any file but there can only be at most +// one `#[tests]` module in this library crate +#[cfg(test)] +#[defmt_test::tests] +mod unit_tests { + use defmt::assert; + + #[test] + fn it_works() { + assert!(true) + } +} diff --git a/hal_test/tests/integration.rs b/hal_test/tests/integration.rs new file mode 100644 index 0000000..1f33de6 --- /dev/null +++ b/hal_test/tests/integration.rs @@ -0,0 +1,16 @@ +#![no_std] +#![no_main] + +use stm32u5_blinky as _; // memory layout + panic handler + +// See https://crates.io/crates/defmt-test/0.3.0 for more documentation (e.g. about the 'state' +// feature) +#[defmt_test::tests] +mod tests { + use defmt::assert; + + #[test] + fn it_works() { + assert!(true) + } +} diff --git a/tim2/src/bin/main.rs b/tim2/src/bin/main.rs index 8b24ad9..bbd35c1 100644 --- a/tim2/src/bin/main.rs +++ b/tim2/src/bin/main.rs @@ -4,7 +4,7 @@ use cortex_m_rt::entry; use panic_halt as _; use stm32u5::stm32u575 as pac; -use pac::interrupt; // Import the interrupt enum! +use pac::interrupt; // Import the interrupt enum // Timer frequency constants const PRESCALER: u16 = 0; @@ -13,17 +13,13 @@ const PULSE1_VALUE: u32 = 50000; // For 800 Hz toggle #[entry] fn main() -> ! { let dp = pac::Peripherals::take().unwrap(); - - // Enable TIM2 clock dp.RCC.apb1enr1().modify(|_, w| w.tim2en().set_bit()); // Enable GPIOA clock for TIM2_CH4 (PA3) dp.RCC.ahb2enr1().modify(|_, w| w.gpioaen().set_bit()); // Configure PA3 as AF1 (TIM2_CH4) - // Fixed: moder3 -> mode3 dp.GPIOA.moder().modify(|_, w| w.mode3().alternate()); - // Fixed: afsel3 -> afrl3 dp.GPIOA.afrl().modify(|_, w| w.afrel3().af1()); // Configure TIM2 @@ -62,20 +58,12 @@ fn main() -> ! { fn TIM2() { unsafe { let tim2 = &(*pac::TIM2::ptr()); - - // Check if CH4 compare interrupt if tim2.sr().read().cc4if().bit_is_set() { - // Clear interrupt flag tim2.sr().modify(|_, w| w.cc4if().clear_bit()); - - // Update next compare value + + // Use wrapping arithmetic let current = tim2.ccr4().read().bits(); - let arr = tim2.arr().read().bits(); - let next = if current + PULSE1_VALUE < arr { - current + PULSE1_VALUE - } else { - (current + PULSE1_VALUE) - arr - }; + let next = current.wrapping_add(PULSE1_VALUE); tim2.ccr4().write(|w| w.bits(next)); } }