From 9a9e01dc01e7231a8f0825d328158c83a2bf1e0f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Feb 2025 10:52:04 +0100 Subject: [PATCH] first PAC experiments --- Cargo.lock | 2 +- Cargo.toml | 16 +- LICENSE-APACHE | 201 +++++ LICENSE-MIT | 21 + NOTICE | 1 + zynq-examples/Cargo.toml | 15 + {src => zynq-examples/src}/main.rs | 0 zynq7000-rt/Cargo.toml | 14 + zynq7000-rt/README.md | 15 + zynq7000-rt/src/bin/table-gen.rs | 3 +- zynq7000-rt/src/lib.rs | 1 + zynq7000-rt/src/mmu.rs | 1 + zynq7000/Cargo.toml | 25 + zynq7000/build.rs | 17 + zynq7000/device.x | 4 + zynq7000/example.svd | 778 ++++++++++++++++++ zynq7000/gen-helper.sh | 42 + zynq7000/src/generic.rs | 730 +++++++++++++++++ zynq7000/src/generic/raw.rs | 95 +++ zynq7000/src/lib.rs | 237 ++++++ zynq7000/src/timer0.rs | 110 +++ zynq7000/src/timer0/count.rs | 28 + zynq7000/src/timer0/cr.rs | 1225 ++++++++++++++++++++++++++++ zynq7000/src/timer0/int.rs | 173 ++++ zynq7000/src/timer0/match_.rs | 28 + zynq7000/src/timer0/prescale_rd.rs | 19 + zynq7000/src/timer0/prescale_wr.rs | 24 + zynq7000/src/timer0/reload.rs | 29 + zynq7000/src/timer0/sr.rs | 365 +++++++++ 29 files changed, 4206 insertions(+), 13 deletions(-) create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 NOTICE create mode 100644 zynq-examples/Cargo.toml rename {src => zynq-examples/src}/main.rs (100%) create mode 100644 zynq7000-rt/README.md create mode 100644 zynq7000/Cargo.toml create mode 100644 zynq7000/build.rs create mode 100644 zynq7000/device.x create mode 100644 zynq7000/example.svd create mode 100755 zynq7000/gen-helper.sh create mode 100644 zynq7000/src/generic.rs create mode 100644 zynq7000/src/generic/raw.rs create mode 100644 zynq7000/src/lib.rs create mode 100644 zynq7000/src/timer0.rs create mode 100644 zynq7000/src/timer0/count.rs create mode 100644 zynq7000/src/timer0/cr.rs create mode 100644 zynq7000/src/timer0/int.rs create mode 100644 zynq7000/src/timer0/match_.rs create mode 100644 zynq7000/src/timer0/prescale_rd.rs create mode 100644 zynq7000/src/timer0/prescale_wr.rs create mode 100644 zynq7000/src/timer0/reload.rs create mode 100644 zynq7000/src/timer0/sr.rs diff --git a/Cargo.lock b/Cargo.lock index 656ed59..186c36c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] -name = "zedboard-blinky-rs" +name = "zynq-examples" version = "0.1.0" dependencies = [ "cortex-r-a", diff --git a/Cargo.toml b/Cargo.toml index b03c04d..7e8d7fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,7 @@ [workspace] -members = ["zynq7000-rt"] - -[package] -name = "zedboard-blinky-rs" -version = "0.1.0" -edition = "2024" - -[dependencies] -cortex-r-a = { path = "../cortex-r-a/cortex-r-a" } -zynq7000-rt = { path = "zynq7000-rt" } +resolver = "3" +members = [ + # "zynq7000", + "zynq7000-rt", + "zynq-examples" +] diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/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/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..8311204 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Robin A. Mueller + +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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..c5f7ef2 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +This software contains code developed at the University of Stuttgart. diff --git a/zynq-examples/Cargo.toml b/zynq-examples/Cargo.toml new file mode 100644 index 0000000..c384900 --- /dev/null +++ b/zynq-examples/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "zynq-examples" +version = "0.1.0" +authors = ["Robin Mueller "] +edition = "2024" +description = "Examples for the Zynq7000 family of SoCs" +homepage = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +license = "MIT OR Apache-2.0" +keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] +categories = ["embedded", "no-std", "hardware-support"] + +[dependencies] +cortex-r-a = { path = "../../cortex-r-a/cortex-r-a" } +zynq7000-rt = { path = "../zynq7000-rt" } diff --git a/src/main.rs b/zynq-examples/src/main.rs similarity index 100% rename from src/main.rs rename to zynq-examples/src/main.rs diff --git a/zynq7000-rt/Cargo.toml b/zynq7000-rt/Cargo.toml index ec2bd4b..d423d5e 100644 --- a/zynq7000-rt/Cargo.toml +++ b/zynq7000-rt/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "zynq7000-rt" version = "0.1.0" +authors = ["Robin Mueller "] edition = "2024" +description = "Run-time support for the Zynq7000 family of SoCs for running bare-metal applications" +homepage = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +license = "MIT OR Apache-2.0" +keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] +categories = ["embedded", "no-std", "hardware-support"] [dependencies] cortex-a-rt = { path = "../../cortex-r-a/cortex-a-rt", optional = true, features = ["vfp-dp"] } @@ -9,4 +16,11 @@ cortex-r-a = { path = "../../cortex-r-a/cortex-r-a" } [features] default = ["rt"] +tools = [] rt = ["dep:cortex-a-rt"] + +[[bin]] +name = "table-gen" +path = "src/bin/table-gen.rs" +# Prevents default build +required-features = ["tools"] diff --git a/zynq7000-rt/README.md b/zynq7000-rt/README.md new file mode 100644 index 0000000..8d1f1f2 --- /dev/null +++ b/zynq7000-rt/README.md @@ -0,0 +1,15 @@ +Zynq7000 Run-Time Support +======== + +Startup code and minimal runtime for the AMD Zynq7000 SoC. + +## Re-Generating the MMU table + +The MMU table is a static flat map of 4096 entries for each 1 MB in the memory map. +It was generated using the `table-gen` binary tool. + +You can re-run the tool using + +```sh +cargo +stable --target run --bin table-gen --no-default-features --features tools +``` diff --git a/zynq7000-rt/src/bin/table-gen.rs b/zynq7000-rt/src/bin/table-gen.rs index 8d13eb0..643a577 100644 --- a/zynq7000-rt/src/bin/table-gen.rs +++ b/zynq7000-rt/src/bin/table-gen.rs @@ -1,9 +1,8 @@ use std::fs::File; use std::io::Write; use std::process::Command; - -use zynq7000_rt::mmu::ONE_MB; pub use zynq7000_rt::mmu::segments::*; +use zynq7000_rt::mmu::ONE_MB; fn main() { let file_path = "src/mmu_table.rs"; diff --git a/zynq7000-rt/src/lib.rs b/zynq7000-rt/src/lib.rs index 222f91a..9975309 100644 --- a/zynq7000-rt/src/lib.rs +++ b/zynq7000-rt/src/lib.rs @@ -5,6 +5,7 @@ #![no_std] pub mod mmu; +#[cfg(feature = "rt")] mod mmu_table; #[cfg(feature = "rt")] pub mod rt; diff --git a/zynq7000-rt/src/mmu.rs b/zynq7000-rt/src/mmu.rs index b8d1ce5..492db51 100644 --- a/zynq7000-rt/src/mmu.rs +++ b/zynq7000-rt/src/mmu.rs @@ -165,6 +165,7 @@ pub mod section_attrs { pub const NUM_L1_PAGE_TABLE_ENTRIES: usize = 4096; #[repr(C, align(16384))] +#[cfg(feature = "rt")] pub struct L1Table(pub(crate) [u32; NUM_L1_PAGE_TABLE_ENTRIES]); /// Load the MMU translation table base address into the MMU. diff --git a/zynq7000/Cargo.toml b/zynq7000/Cargo.toml new file mode 100644 index 0000000..c9603b6 --- /dev/null +++ b/zynq7000/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "zynq7000" +version = "0.1.0" +authors = ["Robin Mueller "] +edition = "2024" +description = "PAC for the Zynq7000 family of SoCs" +homepage = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +repository = "https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs" +license = "MIT OR Apache-2.0" +keywords = ["no-std", "arm", "cortex-a", "amd", "zynq7000"] +categories = ["embedded", "no-std", "hardware-support"] + +[dependencies] +# cortex-ra +vcell = "0.1.3" +defmt = { version = "0.3", optional = true } +critical-section = { version = "1", optional = true } + +[features] +# Adds Debug implementation +debug = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--generate-link-to-definition"] diff --git a/zynq7000/build.rs b/zynq7000/build.rs new file mode 100644 index 0000000..d0781ac --- /dev/null +++ b/zynq7000/build.rs @@ -0,0 +1,17 @@ +#![doc = r" Builder file for Peripheral access crate generated by svd2rust tool"] +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +fn main() { + if env::var_os("CARGO_FEATURE_RT").is_some() { + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("device.x")) + .unwrap() + .write_all(include_bytes!("device.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + println!("cargo:rerun-if-changed=device.x"); + } + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/zynq7000/device.x b/zynq7000/device.x new file mode 100644 index 0000000..0bab52a --- /dev/null +++ b/zynq7000/device.x @@ -0,0 +1,4 @@ +PROVIDE(TIMER0 = DefaultHandler); +PROVIDE(TIMER1 = DefaultHandler); +PROVIDE(TIMER2 = DefaultHandler); + diff --git a/zynq7000/example.svd b/zynq7000/example.svd new file mode 100644 index 0000000..4d415ae --- /dev/null +++ b/zynq7000/example.svd @@ -0,0 +1,778 @@ + + + + + + + + AMD + AMD + Zynq7000 + ARMCA9 + 1.0 + Community provided SVD file for the AMD Zynq7000 SoC + + + + CM3 + r1p0 + little + true + false + 3 + false + + 8 + 32 + + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + TIMER0 + 1.0 + 32 Timer / Counter, counting up or down from different sources + TIMER + 0x40010000 + 32 + read-write + + + 0 + 0x100 + registers + + + + TIMER0 + Timer 0 interrupt + 0 + + + + + + CR + Control Register + 0x00 + 32 + read-write + 0x00000000 + 0x1337F7F + + + + + EN + Enable + [0:0] + read-write + + + Disable + Timer is disabled and does not operate + 0 + + + Enable + Timer is enabled and can operate + 1 + + + + + + + RST + Reset Timer + [1:1] + write-only + + + No_Action + Write as ZERO if necessary + 0 + + + Reset_Timer + Reset the Timer + 1 + + + + + + + CNT + Counting direction + [3:2] + read-write + + + Count_UP + Timer Counts UO and wraps, if no STOP condition is set + 0 + + + Count_DOWN + Timer Counts DOWN and wraps, if no STOP condition is set + 1 + + + Toggle + Timer Counts up to MAX, then DOWN to ZERO, if no STOP condition is set + 2 + + + + + + + MODE + Operation Mode + [6:4] + read-write + + + Continous + Timer runs continously + 0 + + + Single_ZERO_MAX + Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT) and stops + 1 + + + Single_MATCH + Timer counts to the Value of MATCH Register and stops + 2 + + + Reload_ZERO_MAX + Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT), loads the RELOAD Value and continues + 3 + + + Reload_MATCH + Timer counts to the Value of MATCH Register, loads the RELOAD Value and continues + 4 + + + + + + + PSC + Use Prescaler + [7:7] + read-write + + + Disabled + Prescaler is not used + 0 + + + Enabled + Prescaler is used as divider + 1 + + + + + + + CNTSRC + Timer / Counter Source Divider + [11:8] + read-write + + + CAP_SRC + Capture Source is used directly + 0 + + + CAP_SRC_div2 + Capture Source is divided by 2 + 1 + + + CAP_SRC_div4 + Capture Source is divided by 4 + 2 + + + CAP_SRC_div8 + Capture Source is divided by 8 + 3 + + + CAP_SRC_div16 + Capture Source is divided by 16 + 4 + + + CAP_SRC_div32 + Capture Source is divided by 32 + 5 + + + CAP_SRC_div64 + Capture Source is divided by 64 + 6 + + + CAP_SRC_div128 + Capture Source is divided by 128 + 7 + + + CAP_SRC_div256 + Capture Source is divided by 256 + 8 + + + + + + + CAPSRC + Timer / Counter Capture Source + [15:12] + read-write + + + CClk + Core Clock + 0 + + + GPIOA_0 + GPIO A, PIN 0 + 1 + + + GPIOA_1 + GPIO A, PIN 1 + 2 + + + GPIOA_2 + GPIO A, PIN 2 + 3 + + + GPIOA_3 + GPIO A, PIN 3 + 4 + + + GPIOA_4 + GPIO A, PIN 4 + 5 + + + GPIOA_5 + GPIO A, PIN 5 + 6 + + + GPIOA_6 + GPIO A, PIN 6 + 7 + + + GPIOA_7 + GPIO A, PIN 7 + 8 + + + GPIOB_0 + GPIO B, PIN 0 + 9 + + + GPIOB_1 + GPIO B, PIN 1 + 10 + + + GPIOB_2 + GPIO B, PIN 2 + 11 + + + GPIOB_3 + GPIO B, PIN 3 + 12 + + + GPIOC_0 + GPIO C, PIN 0 + 13 + + + GPIOC_5 + GPIO C, PIN 1 + 14 + + + GPIOC_6 + GPIO C, PIN 2 + 15 + + + + + + + CAPEDGE + Capture Edge, select which Edge should result in a counter increment or decrement + [17:16] + read-write + + + RISING + Only rising edges result in a counter increment or decrement + 0 + + + FALLING + Only falling edges result in a counter increment or decrement + 1 + + + BOTH + Rising and falling edges result in a counter increment or decrement + 2 + + + + + + + TRGEXT + Triggers an other Peripheral + [21:20] + read-write + + + NONE + No Trigger is emitted + 0 + + + DMA1 + DMA Controller 1 is triggered, dependant on MODE + 1 + + + DMA2 + DMA Controller 2 is triggered, dependant on MODE + 2 + + + UART + UART is triggered, dependant on MODE + 3 + + + + + + + RELOAD + Select RELOAD Register n to reload Timer on condition + [25:24] + read-write + + + RELOAD0 + Selects Reload Register number 0 + 0 + + + RELOAD1 + Selects Reload Register number 1 + 1 + + + RELOAD2 + Selects Reload Register number 2 + 2 + + + RELOAD3 + Selects Reload Register number 3 + 3 + + + + + + + IDR + Selects, if Reload Register number is incremented, decremented or not modified + [27:26] + read-write + + + KEEP + Reload Register number does not change automatically + 0 + + + INCREMENT + Reload Register number is incremented on each match + 1 + + + DECREMENT + Reload Register number is decremented on each match + 2 + + + + + + + S + Starts and Stops the Timer / Counter + [31:31] + read-write + + + STOP + Timer / Counter is stopped + 0 + + + START + Timer / Counter is started + 1 + + + + + + + + + SR + Status Register + 0x04 + 16 + read-write + 0x00000000 + 0xD701 + + + + + RUN + Shows if Timer is running or not + [0:0] + read-only + + + Stopped + Timer is not running + 0 + + + Running + Timer is running + 1 + + + + + + + MATCH + Shows if the MATCH was hit + [8:8] + read-write + + + No_Match + The MATCH condition was not hit + 0 + + + Match_Hit + The MATCH condition was hit + 1 + + + + + + + UN + Shows if an underflow occured. This flag is sticky + [9:9] + read-write + + + No_Underflow + No underflow occured since last clear + 0 + + + Underflow + A minimum of one underflow occured since last clear + 1 + + + + + + + OV + Shows if an overflow occured. This flag is sticky + [10:10] + read-write + + + No_Overflow + No overflow occured since last clear + 0 + + + Overflow_occured + A minimum of one overflow occured since last clear + 1 + + + + + + + RST + Shows if Timer is in RESET state + [12:12] + read-only + + + Ready + Timer is not in RESET state and can operate + 0 + + + In_Reset + Timer is in RESET state and can not operate + 1 + + + + + + + RELOAD + Shows the currently active RELOAD Register + [15:14] + read-only + + + RELOAD0 + Reload Register number 0 is active + 0 + + + RELOAD1 + Reload Register number 1 is active + 1 + + + RELOAD2 + Reload Register number 2 is active + 2 + + + RELOAD3 + Reload Register number 3 is active + 3 + + + + + + + + + INT + Interrupt Register + 0x10 + 16 + read-write + 0x00000000 + 0x0771 + + + + + EN + Interrupt Enable + [0:0] + read-write + + + Disabled + Timer does not generate Interrupts + 0 + + + Enable + Timer triggers the TIMERn Interrupt + 1 + + + + + + + MODE + Interrupt Mode, selects on which condition the Timer should generate an Interrupt + [6:4] + read-write + + + Match + Timer generates an Interrupt when the MATCH condition is hit + 0 + + + Underflow + Timer generates an Interrupt when it underflows + 1 + + + Overflow + Timer generates an Interrupt when it overflows + 2 + + + + + + + + + COUNT + The Counter Register reflects the actual Value of the Timer/Counter + 0x20 + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + MATCH + The Match Register stores the compare Value for the MATCH condition + 0x24 + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + PRESCALE_RD + The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value + 0x28 + 32 + read-only + 0x00000000 + 0xFFFFFFFF + + + + + PRESCALE_WR + The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value + 0x28 + 32 + write-only + 0x00000000 + 0xFFFFFFFF + + + + + + 4 + 4 + RELOAD[%s] + The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met. + 0x50 + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + + + TIMER1 + 0x40010100 + + TIMER1 + Timer 1 interrupt + 4 + + + + + + TIMER2 + 0x40010200 + + TIMER2 + Timer 2 interrupt + 6 + + + + diff --git a/zynq7000/gen-helper.sh b/zynq7000/gen-helper.sh new file mode 100755 index 0000000..c8bd783 --- /dev/null +++ b/zynq7000/gen-helper.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Use installed tool by default +svd2rust_bin="svd2rust" +# Automates the steps specified in https://docs.rs/svd2rust/0.19.0/svd2rust/ +if [ -f svd2rust ]; then + # If the local directory contains svd2rust, use that version instead + svd2rust_bin="./svd2rust" +elif [ -f ../svd2rust ]; then + # Keeps the repository clean + svd2rust_bin="../svd2rust" +fi +if [ -x "$(${svd2rust_bin} --version)" ]; then + echo "No svd2rust found locally or installed." \ + "Install it with cargo install svd2rust" + exit +fi + +if ! command -v form &> /dev/null +then + echo "form tool was not found" + exit 1 +fi + +if ! command -v svdtools &> /dev/null +then + echo "svdtools was not found" + exit 1 +fi + +# See https://github.com/rust-embedded/svd2rust/issues/830 for required re-export. +${svd2rust_bin} --reexport-interrupt --impl-defmt defmt --impl-debug-feature debug -i example.svd + +result=$? +if [ $result -ne 0 ]; then + echo "svd2rust failed with code $result" + exit +fi + +rm -rf src +form -i lib.rs -o src/ && rm lib.rs +cargo fmt diff --git a/zynq7000/src/generic.rs b/zynq7000/src/generic.rs new file mode 100644 index 0000000..59eec56 --- /dev/null +++ b/zynq7000/src/generic.rs @@ -0,0 +1,730 @@ +use core::marker; +#[doc = " Raw register type (`u8`, `u16`, `u32`, ...)"] +pub trait RawReg: + Copy + + Default + + From + + core::ops::BitOr + + core::ops::BitAnd + + core::ops::BitOrAssign + + core::ops::BitAndAssign + + core::ops::Not + + core::ops::Shl +{ + #[doc = " Mask for bits of width `WI`"] + fn mask() -> Self; + #[doc = " Mask for bits of width 1"] + fn one() -> Self; +} +macro_rules! raw_reg { + ($ U : ty , $ size : literal , $ mask : ident) => { + impl RawReg for $U { + #[inline(always)] + fn mask() -> Self { + $mask::() + } + #[inline(always)] + fn one() -> Self { + 1 + } + } + const fn $mask() -> $U { + <$U>::MAX >> ($size - WI) + } + impl FieldSpec for $U { + type Ux = $U; + } + }; +} +raw_reg!(u8, 8, mask_u8); +raw_reg!(u16, 16, mask_u16); +raw_reg!(u32, 32, mask_u32); +raw_reg!(u64, 64, mask_u64); +#[doc = " Raw register type"] +pub trait RegisterSpec { + #[doc = " Raw register type (`u8`, `u16`, `u32`, ...)."] + type Ux: RawReg; +} +#[doc = " Raw field type"] +pub trait FieldSpec: Sized { + #[doc = " Raw field type (`u8`, `u16`, `u32`, ...)."] + type Ux: Copy + core::fmt::Debug + PartialEq + From; +} +#[doc = " Marker for fields with fixed values"] +pub trait IsEnum: FieldSpec {} +#[doc = " Trait implemented by readable registers to enable the `read` method."] +#[doc = ""] +#[doc = " Registers marked with `Writable` can be also be `modify`'ed."] +pub trait Readable: RegisterSpec {} +#[doc = " Trait implemented by writeable registers."] +#[doc = ""] +#[doc = " This enables the `write`, `write_with_zero` and `reset` methods."] +#[doc = ""] +#[doc = " Registers marked with `Readable` can be also be `modify`'ed."] +pub trait Writable: RegisterSpec { + #[doc = " Is it safe to write any bits to register"] + type Safety; + #[doc = " Specifies the register bits that are not changed if you pass `1` and are changed if you pass `0`"] + const ZERO_TO_MODIFY_FIELDS_BITMAP: Self::Ux; + #[doc = " Specifies the register bits that are not changed if you pass `0` and are changed if you pass `1`"] + const ONE_TO_MODIFY_FIELDS_BITMAP: Self::Ux; +} +#[doc = " Reset value of the register."] +#[doc = ""] +#[doc = " This value is the initial value for the `write` method. It can also be directly written to the"] +#[doc = " register by using the `reset` method."] +pub trait Resettable: RegisterSpec { + #[doc = " Reset value of the register."] + const RESET_VALUE: Self::Ux; + #[doc = " Reset value of the register."] + #[inline(always)] + fn reset_value() -> Self::Ux { + Self::RESET_VALUE + } +} +#[doc(hidden)] +pub mod raw; +#[doc = " Register reader."] +#[doc = ""] +#[doc = " Result of the `read` methods of registers. Also used as a closure argument in the `modify`"] +#[doc = " method."] +pub type R = raw::R; +impl R { + #[doc = " Reads raw bits from register."] + #[inline(always)] + pub const fn bits(&self) -> REG::Ux { + self.bits + } +} +impl PartialEq for R +where + REG::Ux: PartialEq, + FI: Copy, + REG::Ux: From, +{ + #[inline(always)] + fn eq(&self, other: &FI) -> bool { + self.bits.eq(®::Ux::from(*other)) + } +} +#[doc = " Register writer."] +#[doc = ""] +#[doc = " Used as an argument to the closures in the `write` and `modify` methods of the register."] +pub type W = raw::W; +impl W { + #[doc = " Writes raw bits to the register."] + #[doc = ""] + #[doc = " # Safety"] + #[doc = ""] + #[doc = " Passing incorrect value can cause undefined behaviour. See reference manual"] + #[inline(always)] + pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self { + self.bits = bits; + self + } +} +impl W +where + REG: Writable, +{ + #[doc = " Writes raw bits to the register."] + #[inline(always)] + pub fn set(&mut self, bits: REG::Ux) -> &mut Self { + self.bits = bits; + self + } +} +#[doc = " Field reader."] +#[doc = ""] +#[doc = " Result of the `read` methods of fields."] +pub type FieldReader = raw::FieldReader; +#[doc = " Bit-wise field reader"] +pub type BitReader = raw::BitReader; +impl FieldReader { + #[doc = " Reads raw bits from field."] + #[inline(always)] + pub const fn bits(&self) -> FI::Ux { + self.bits + } +} +impl core::fmt::Debug for FieldReader { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.bits, f) + } +} +impl PartialEq for FieldReader +where + FI: FieldSpec + Copy, +{ + #[inline(always)] + fn eq(&self, other: &FI) -> bool { + self.bits.eq(&FI::Ux::from(*other)) + } +} +impl PartialEq for BitReader +where + FI: Copy, + bool: From, +{ + #[inline(always)] + fn eq(&self, other: &FI) -> bool { + self.bits.eq(&bool::from(*other)) + } +} +impl BitReader { + #[doc = " Value of the field as raw bits."] + #[inline(always)] + pub const fn bit(&self) -> bool { + self.bits + } + #[doc = " Returns `true` if the bit is clear (0)."] + #[inline(always)] + pub const fn bit_is_clear(&self) -> bool { + !self.bit() + } + #[doc = " Returns `true` if the bit is set (1)."] + #[inline(always)] + pub const fn bit_is_set(&self) -> bool { + self.bit() + } +} +impl core::fmt::Debug for BitReader { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.bits, f) + } +} +#[doc = " Marker for register/field writers which can take any value of specified width"] +pub struct Safe; +#[doc = " You should check that value is allowed to pass to register/field writer marked with this"] +pub struct Unsafe; +#[doc = " Marker for field writers are safe to write in specified inclusive range"] +pub struct Range; +#[doc = " Marker for field writers are safe to write in specified inclusive range"] +pub struct RangeFrom; +#[doc = " Marker for field writers are safe to write in specified inclusive range"] +pub struct RangeTo; +#[doc = " Write field Proxy"] +pub type FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> = + raw::FieldWriter<'a, REG, WI, FI, Safety>; +impl FieldWriter<'_, REG, WI, FI, Safety> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, +{ + #[doc = " Field width"] + pub const WIDTH: u8 = WI; + #[doc = " Field width"] + #[inline(always)] + pub const fn width(&self) -> u8 { + WI + } + #[doc = " Field offset"] + #[inline(always)] + pub const fn offset(&self) -> u8 { + self.o + } +} +impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, + REG::Ux: From, +{ + #[doc = " Writes raw bits to the field"] + #[doc = ""] + #[doc = " # Safety"] + #[doc = ""] + #[doc = " Passing incorrect value can cause undefined behaviour. See reference manual"] + #[inline(always)] + pub unsafe fn bits(self, value: FI::Ux) -> &'a mut W { + self.w.bits &= !(REG::Ux::mask::() << self.o); + self.w.bits |= (REG::Ux::from(value) & REG::Ux::mask::()) << self.o; + self.w + } +} +impl<'a, REG, const WI: u8, FI> FieldWriter<'a, REG, WI, FI, Safe> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, + REG::Ux: From, +{ + #[doc = " Writes raw bits to the field"] + #[inline(always)] + pub fn set(self, value: FI::Ux) -> &'a mut W { + unsafe { self.bits(value) } + } +} +impl<'a, REG, const WI: u8, FI, const MIN: u64, const MAX: u64> + FieldWriter<'a, REG, WI, FI, Range> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, + REG::Ux: From, + u64: From, +{ + #[doc = " Writes raw bits to the field"] + #[inline(always)] + pub fn set(self, value: FI::Ux) -> &'a mut W { + { + let value = u64::from(value); + assert!(value >= MIN && value <= MAX); + } + unsafe { self.bits(value) } + } +} +impl<'a, REG, const WI: u8, FI, const MIN: u64> FieldWriter<'a, REG, WI, FI, RangeFrom> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, + REG::Ux: From, + u64: From, +{ + #[doc = " Writes raw bits to the field"] + #[inline(always)] + pub fn set(self, value: FI::Ux) -> &'a mut W { + { + let value = u64::from(value); + assert!(value >= MIN); + } + unsafe { self.bits(value) } + } +} +impl<'a, REG, const WI: u8, FI, const MAX: u64> FieldWriter<'a, REG, WI, FI, RangeTo> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, + REG::Ux: From, + u64: From, +{ + #[doc = " Writes raw bits to the field"] + #[inline(always)] + pub fn set(self, value: FI::Ux) -> &'a mut W { + { + let value = u64::from(value); + assert!(value <= MAX); + } + unsafe { self.bits(value) } + } +} +impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety> +where + REG: Writable + RegisterSpec, + FI: IsEnum, + REG::Ux: From, +{ + #[doc = " Writes `variant` to the field"] + #[inline(always)] + pub fn variant(self, variant: FI) -> &'a mut W { + unsafe { self.bits(FI::Ux::from(variant)) } + } +} +macro_rules! bit_proxy { + ($ writer : ident , $ mwv : ident) => { + #[doc(hidden)] + pub struct $mwv; + #[doc = " Bit-wise write field proxy"] + pub type $writer<'a, REG, FI = bool> = raw::BitWriter<'a, REG, FI, $mwv>; + impl<'a, REG, FI> $writer<'a, REG, FI> + where + REG: Writable + RegisterSpec, + bool: From, + { + #[doc = " Field width"] + pub const WIDTH: u8 = 1; + #[doc = " Field width"] + #[inline(always)] + pub const fn width(&self) -> u8 { + Self::WIDTH + } + #[doc = " Field offset"] + #[inline(always)] + pub const fn offset(&self) -> u8 { + self.o + } + #[doc = " Writes bit to the field"] + #[inline(always)] + pub fn bit(self, value: bool) -> &'a mut W { + self.w.bits &= !(REG::Ux::one() << self.o); + self.w.bits |= (REG::Ux::from(value) & REG::Ux::one()) << self.o; + self.w + } + #[doc = " Writes `variant` to the field"] + #[inline(always)] + pub fn variant(self, variant: FI) -> &'a mut W { + self.bit(bool::from(variant)) + } + } + }; +} +bit_proxy!(BitWriter, BitM); +bit_proxy!(BitWriter1S, Bit1S); +bit_proxy!(BitWriter0C, Bit0C); +bit_proxy!(BitWriter1C, Bit1C); +bit_proxy!(BitWriter0S, Bit0S); +bit_proxy!(BitWriter1T, Bit1T); +bit_proxy!(BitWriter0T, Bit0T); +impl<'a, REG, FI> BitWriter<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = " Sets the field bit"] + #[inline(always)] + pub fn set_bit(self) -> &'a mut W { + self.w.bits |= REG::Ux::one() << self.o; + self.w + } + #[doc = " Clears the field bit"] + #[inline(always)] + pub fn clear_bit(self) -> &'a mut W { + self.w.bits &= !(REG::Ux::one() << self.o); + self.w + } +} +impl<'a, REG, FI> BitWriter1S<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = " Sets the field bit"] + #[inline(always)] + pub fn set_bit(self) -> &'a mut W { + self.w.bits |= REG::Ux::one() << self.o; + self.w + } +} +impl<'a, REG, FI> BitWriter0C<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = " Clears the field bit"] + #[inline(always)] + pub fn clear_bit(self) -> &'a mut W { + self.w.bits &= !(REG::Ux::one() << self.o); + self.w + } +} +impl<'a, REG, FI> BitWriter1C<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = "Clears the field bit by passing one"] + #[inline(always)] + pub fn clear_bit_by_one(self) -> &'a mut W { + self.w.bits |= REG::Ux::one() << self.o; + self.w + } +} +impl<'a, REG, FI> BitWriter0S<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = "Sets the field bit by passing zero"] + #[inline(always)] + pub fn set_bit_by_zero(self) -> &'a mut W { + self.w.bits &= !(REG::Ux::one() << self.o); + self.w + } +} +impl<'a, REG, FI> BitWriter1T<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = "Toggle the field bit by passing one"] + #[inline(always)] + pub fn toggle_bit(self) -> &'a mut W { + self.w.bits |= REG::Ux::one() << self.o; + self.w + } +} +impl<'a, REG, FI> BitWriter0T<'a, REG, FI> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = "Toggle the field bit by passing zero"] + #[inline(always)] + pub fn toggle_bit(self) -> &'a mut W { + self.w.bits &= !(REG::Ux::one() << self.o); + self.w + } +} +#[doc = " This structure provides volatile access to registers."] +#[repr(transparent)] +pub struct Reg { + register: vcell::VolatileCell, + _marker: marker::PhantomData, +} +unsafe impl Send for Reg where REG::Ux: Send {} +impl Reg { + #[doc = " Returns the underlying memory address of register."] + #[doc = ""] + #[doc = " ```ignore"] + #[doc = " let reg_ptr = periph.reg.as_ptr();"] + #[doc = " ```"] + #[inline(always)] + pub fn as_ptr(&self) -> *mut REG::Ux { + self.register.as_ptr() + } +} +impl Reg { + #[doc = " Reads the contents of a `Readable` register."] + #[doc = ""] + #[doc = " You can read the raw contents of a register by using `bits`:"] + #[doc = " ```ignore"] + #[doc = " let bits = periph.reg.read().bits();"] + #[doc = " ```"] + #[doc = " or get the content of a particular field of a register:"] + #[doc = " ```ignore"] + #[doc = " let reader = periph.reg.read();"] + #[doc = " let bits = reader.field1().bits();"] + #[doc = " let flag = reader.field2().bit_is_set();"] + #[doc = " ```"] + #[inline(always)] + pub fn read(&self) -> R { + R { + bits: self.register.get(), + _reg: marker::PhantomData, + } + } +} +impl Reg { + #[doc = " Writes the reset value to `Writable` register."] + #[doc = ""] + #[doc = " Resets the register to its initial state."] + #[inline(always)] + pub fn reset(&self) { + self.register.set(REG::RESET_VALUE) + } + #[doc = " Writes bits to a `Writable` register."] + #[doc = ""] + #[doc = " You can write raw bits into a register:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write(|w| unsafe { w.bits(rawbits) });"] + #[doc = " ```"] + #[doc = " or write only the fields you need:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write(|w| w"] + #[doc = " .field1().bits(newfield1bits)"] + #[doc = " .field2().set_bit()"] + #[doc = " .field3().variant(VARIANT)"] + #[doc = " );"] + #[doc = " ```"] + #[doc = " or an alternative way of saying the same:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write(|w| {"] + #[doc = " w.field1().bits(newfield1bits);"] + #[doc = " w.field2().set_bit();"] + #[doc = " w.field3().variant(VARIANT)"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " In the latter case, other fields will be set to their reset value."] + #[inline(always)] + pub fn write(&self, f: F) -> REG::Ux + where + F: FnOnce(&mut W) -> &mut W, + { + let value = f(&mut W { + bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP + | REG::ZERO_TO_MODIFY_FIELDS_BITMAP, + _reg: marker::PhantomData, + }) + .bits; + self.register.set(value); + value + } + #[doc = " Writes bits to a `Writable` register and produce a value."] + #[doc = ""] + #[doc = " You can write raw bits into a register:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write_and(|w| unsafe { w.bits(rawbits); });"] + #[doc = " ```"] + #[doc = " or write only the fields you need:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write_and(|w| {"] + #[doc = " w.field1().bits(newfield1bits)"] + #[doc = " .field2().set_bit()"] + #[doc = " .field3().variant(VARIANT);"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " or an alternative way of saying the same:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.write_and(|w| {"] + #[doc = " w.field1().bits(newfield1bits);"] + #[doc = " w.field2().set_bit();"] + #[doc = " w.field3().variant(VARIANT);"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " In the latter case, other fields will be set to their reset value."] + #[doc = ""] + #[doc = " Values can be returned from the closure:"] + #[doc = " ```ignore"] + #[doc = " let state = periph.reg.write_and(|w| State::set(w.field1()));"] + #[doc = " ```"] + #[inline(always)] + pub fn from_write(&self, f: F) -> T + where + F: FnOnce(&mut W) -> T, + { + let mut writer = W { + bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP + | REG::ZERO_TO_MODIFY_FIELDS_BITMAP, + _reg: marker::PhantomData, + }; + let result = f(&mut writer); + self.register.set(writer.bits); + result + } +} +impl Reg { + #[doc = " Writes 0 to a `Writable` register."] + #[doc = ""] + #[doc = " Similar to `write`, but unused bits will contain 0."] + #[doc = ""] + #[doc = " # Safety"] + #[doc = ""] + #[doc = " Unsafe to use with registers which don't allow to write 0."] + #[inline(always)] + pub unsafe fn write_with_zero(&self, f: F) -> REG::Ux + where + F: FnOnce(&mut W) -> &mut W, + { + let value = f(&mut W { + bits: REG::Ux::default(), + _reg: marker::PhantomData, + }) + .bits; + self.register.set(value); + value + } + #[doc = " Writes 0 to a `Writable` register and produces a value."] + #[doc = ""] + #[doc = " Similar to `write`, but unused bits will contain 0."] + #[doc = ""] + #[doc = " # Safety"] + #[doc = ""] + #[doc = " Unsafe to use with registers which don't allow to write 0."] + #[inline(always)] + pub unsafe fn from_write_with_zero(&self, f: F) -> T + where + F: FnOnce(&mut W) -> T, + { + let mut writer = W { + bits: REG::Ux::default(), + _reg: marker::PhantomData, + }; + let result = f(&mut writer); + self.register.set(writer.bits); + result + } +} +impl Reg { + #[doc = " Modifies the contents of the register by reading and then writing it."] + #[doc = ""] + #[doc = " E.g. to do a read-modify-write sequence to change parts of a register:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.modify(|r, w| unsafe { w.bits("] + #[doc = " r.bits() | 3"] + #[doc = " ) });"] + #[doc = " ```"] + #[doc = " or"] + #[doc = " ```ignore"] + #[doc = " periph.reg.modify(|_, w| w"] + #[doc = " .field1().bits(newfield1bits)"] + #[doc = " .field2().set_bit()"] + #[doc = " .field3().variant(VARIANT)"] + #[doc = " );"] + #[doc = " ```"] + #[doc = " or an alternative way of saying the same:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.modify(|_, w| {"] + #[doc = " w.field1().bits(newfield1bits);"] + #[doc = " w.field2().set_bit();"] + #[doc = " w.field3().variant(VARIANT)"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " Other fields will have the value they had before the call to `modify`."] + #[inline(always)] + pub fn modify(&self, f: F) -> REG::Ux + where + for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W, + { + let bits = self.register.get(); + let value = f( + &R { + bits, + _reg: marker::PhantomData, + }, + &mut W { + bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP, + _reg: marker::PhantomData, + }, + ) + .bits; + self.register.set(value); + value + } + #[doc = " Modifies the contents of the register by reading and then writing it"] + #[doc = " and produces a value."] + #[doc = ""] + #[doc = " E.g. to do a read-modify-write sequence to change parts of a register:"] + #[doc = " ```ignore"] + #[doc = " let bits = periph.reg.modify(|r, w| {"] + #[doc = " let new_bits = r.bits() | 3;"] + #[doc = " unsafe {"] + #[doc = " w.bits(new_bits);"] + #[doc = " }"] + #[doc = ""] + #[doc = " new_bits"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " or"] + #[doc = " ```ignore"] + #[doc = " periph.reg.modify(|_, w| {"] + #[doc = " w.field1().bits(newfield1bits)"] + #[doc = " .field2().set_bit()"] + #[doc = " .field3().variant(VARIANT);"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " or an alternative way of saying the same:"] + #[doc = " ```ignore"] + #[doc = " periph.reg.modify(|_, w| {"] + #[doc = " w.field1().bits(newfield1bits);"] + #[doc = " w.field2().set_bit();"] + #[doc = " w.field3().variant(VARIANT);"] + #[doc = " });"] + #[doc = " ```"] + #[doc = " Other fields will have the value they had before the call to `modify`."] + #[inline(always)] + pub fn from_modify(&self, f: F) -> T + where + for<'w> F: FnOnce(&R, &'w mut W) -> T, + { + let bits = self.register.get(); + let mut writer = W { + bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP | REG::ZERO_TO_MODIFY_FIELDS_BITMAP, + _reg: marker::PhantomData, + }; + let result = f( + &R { + bits, + _reg: marker::PhantomData, + }, + &mut writer, + ); + self.register.set(writer.bits); + result + } +} +impl core::fmt::Debug for crate::generic::Reg +where + R: core::fmt::Debug, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.read(), f) + } +} diff --git a/zynq7000/src/generic/raw.rs b/zynq7000/src/generic/raw.rs new file mode 100644 index 0000000..6a53dfe --- /dev/null +++ b/zynq7000/src/generic/raw.rs @@ -0,0 +1,95 @@ +use super::{BitM, FieldSpec, RegisterSpec, Unsafe, Writable, marker}; +pub struct R { + pub(crate) bits: REG::Ux, + pub(super) _reg: marker::PhantomData, +} +pub struct W { + #[doc = "Writable bits"] + pub(crate) bits: REG::Ux, + pub(super) _reg: marker::PhantomData, +} +pub struct FieldReader +where + FI: FieldSpec, +{ + pub(crate) bits: FI::Ux, + _reg: marker::PhantomData, +} +impl FieldReader { + #[doc = " Creates a new instance of the reader."] + #[allow(unused)] + #[inline(always)] + pub(crate) const fn new(bits: FI::Ux) -> Self { + Self { + bits, + _reg: marker::PhantomData, + } + } +} +pub struct BitReader { + pub(crate) bits: bool, + _reg: marker::PhantomData, +} +impl BitReader { + #[doc = " Creates a new instance of the reader."] + #[allow(unused)] + #[inline(always)] + pub(crate) const fn new(bits: bool) -> Self { + Self { + bits, + _reg: marker::PhantomData, + } + } +} +#[must_use = "after creating `FieldWriter` you need to call field value setting method"] +pub struct FieldWriter<'a, REG, const WI: u8, FI = u8, Safety = Unsafe> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, +{ + pub(crate) w: &'a mut W, + pub(crate) o: u8, + _field: marker::PhantomData<(FI, Safety)>, +} +impl<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, REG, WI, FI, Safety> +where + REG: Writable + RegisterSpec, + FI: FieldSpec, +{ + #[doc = " Creates a new instance of the writer"] + #[allow(unused)] + #[inline(always)] + pub(crate) fn new(w: &'a mut W, o: u8) -> Self { + Self { + w, + o, + _field: marker::PhantomData, + } + } +} +#[must_use = "after creating `BitWriter` you need to call bit setting method"] +pub struct BitWriter<'a, REG, FI = bool, M = BitM> +where + REG: Writable + RegisterSpec, + bool: From, +{ + pub(crate) w: &'a mut W, + pub(crate) o: u8, + _field: marker::PhantomData<(FI, M)>, +} +impl<'a, REG, FI, M> BitWriter<'a, REG, FI, M> +where + REG: Writable + RegisterSpec, + bool: From, +{ + #[doc = " Creates a new instance of the writer"] + #[allow(unused)] + #[inline(always)] + pub(crate) fn new(w: &'a mut W, o: u8) -> Self { + Self { + w, + o, + _field: marker::PhantomData, + } + } +} diff --git a/zynq7000/src/lib.rs b/zynq7000/src/lib.rs new file mode 100644 index 0000000..9b5b0e5 --- /dev/null +++ b/zynq7000/src/lib.rs @@ -0,0 +1,237 @@ +#![doc = "Peripheral access API for ARM_EXAMPLE microcontrollers (generated using svd2rust v0.35.0 (e10f920 2025-02-12))\n\nYou can find an overview of the generated API [here].\n\nAPI features to be included in the [next] +svd2rust release can be generated by cloning the svd2rust [repository], checking out the above commit, and running `cargo doc --open`.\n\n[here]: https://docs.rs/svd2rust/0.35.0/svd2rust/#peripheral-api\n[next]: https://github.com/rust-embedded/svd2rust/blob/master/CHANGELOG.md#unreleased\n[repository]: https://github.com/rust-embedded/svd2rust"] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![no_std] +use core::marker::PhantomData; +use core::ops::Deref; +#[doc = r"Number available in the NVIC for configuring priority"] +pub const NVIC_PRIO_BITS: u8 = 3; +#[cfg(feature = "rt")] +pub use self::Interrupt as interrupt; +#[cfg(feature = "rt")] +pub use cortex_m_rt::interrupt; +#[allow(unused_imports)] +use generic::*; +#[doc = r"Common register and bit access and modify traits"] +pub mod generic; +#[cfg(feature = "rt")] +extern "C" { + fn TIMER0(); + fn TIMER1(); + fn TIMER2(); +} +#[doc(hidden)] +#[repr(C)] +pub union Vector { + _handler: unsafe extern "C" fn(), + _reserved: u32, +} +#[cfg(feature = "rt")] +#[doc(hidden)] +#[link_section = ".vector_table.interrupts"] +#[no_mangle] +pub static __INTERRUPTS: [Vector; 7] = [ + Vector { _handler: TIMER0 }, + Vector { _reserved: 0 }, + Vector { _reserved: 0 }, + Vector { _reserved: 0 }, + Vector { _handler: TIMER1 }, + Vector { _reserved: 0 }, + Vector { _handler: TIMER2 }, +]; +#[doc = r"Enumeration of all the interrupts."] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u16)] +pub enum Interrupt { + #[doc = "0 - Timer 0 interrupt"] + TIMER0 = 0, + #[doc = "4 - Timer 1 interrupt"] + TIMER1 = 4, + #[doc = "6 - Timer 2 interrupt"] + TIMER2 = 6, +} +unsafe impl cortex_m::interrupt::InterruptNumber for Interrupt { + #[inline(always)] + fn number(self) -> u16 { + self as u16 + } +} +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub struct Timer0 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Timer0 {} +impl Timer0 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const timer0::RegisterBlock = 0x4001_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const timer0::RegisterBlock { + Self::PTR + } + #[doc = r" Steal an instance of this peripheral"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r""] + #[doc = r" Ensure that the new instance of the peripheral cannot be used in a way"] + #[doc = r" that may race with any existing instances, for example by only"] + #[doc = r" accessing read-only or write-only registers, or by consuming the"] + #[doc = r" original peripheral and using critical sections to coordinate"] + #[doc = r" access between multiple new instances."] + #[doc = r""] + #[doc = r" Additionally, other software such as HALs may rely on only one"] + #[doc = r" peripheral instance existing to ensure memory safety; ensure"] + #[doc = r" no stolen instances are passed to such software."] + pub unsafe fn steal() -> Self { + Self { + _marker: PhantomData, + } + } +} +impl Deref for Timer0 { + type Target = timer0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Timer0 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Timer0").finish() + } +} +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub mod timer0; +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub struct Timer1 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Timer1 {} +impl Timer1 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const timer0::RegisterBlock = 0x4001_0100 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const timer0::RegisterBlock { + Self::PTR + } + #[doc = r" Steal an instance of this peripheral"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r""] + #[doc = r" Ensure that the new instance of the peripheral cannot be used in a way"] + #[doc = r" that may race with any existing instances, for example by only"] + #[doc = r" accessing read-only or write-only registers, or by consuming the"] + #[doc = r" original peripheral and using critical sections to coordinate"] + #[doc = r" access between multiple new instances."] + #[doc = r""] + #[doc = r" Additionally, other software such as HALs may rely on only one"] + #[doc = r" peripheral instance existing to ensure memory safety; ensure"] + #[doc = r" no stolen instances are passed to such software."] + pub unsafe fn steal() -> Self { + Self { + _marker: PhantomData, + } + } +} +impl Deref for Timer1 { + type Target = timer0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Timer1 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Timer1").finish() + } +} +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub use self::timer0 as timer1; +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub struct Timer2 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Timer2 {} +impl Timer2 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const timer0::RegisterBlock = 0x4001_0200 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const timer0::RegisterBlock { + Self::PTR + } + #[doc = r" Steal an instance of this peripheral"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r""] + #[doc = r" Ensure that the new instance of the peripheral cannot be used in a way"] + #[doc = r" that may race with any existing instances, for example by only"] + #[doc = r" accessing read-only or write-only registers, or by consuming the"] + #[doc = r" original peripheral and using critical sections to coordinate"] + #[doc = r" access between multiple new instances."] + #[doc = r""] + #[doc = r" Additionally, other software such as HALs may rely on only one"] + #[doc = r" peripheral instance existing to ensure memory safety; ensure"] + #[doc = r" no stolen instances are passed to such software."] + pub unsafe fn steal() -> Self { + Self { + _marker: PhantomData, + } + } +} +impl Deref for Timer2 { + type Target = timer0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Timer2 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Timer2").finish() + } +} +#[doc = "32 Timer / Counter, counting up or down from different sources"] +pub use self::timer0 as timer2; +#[no_mangle] +static mut DEVICE_PERIPHERALS: bool = false; +#[doc = r" All the peripherals."] +#[allow(non_snake_case)] +pub struct Peripherals { + #[doc = "TIMER0"] + pub timer0: Timer0, + #[doc = "TIMER1"] + pub timer1: Timer1, + #[doc = "TIMER2"] + pub timer2: Timer2, +} +impl Peripherals { + #[doc = r" Returns all the peripherals *once*."] + #[cfg(feature = "critical-section")] + #[inline] + pub fn take() -> Option { + critical_section::with(|_| { + if unsafe { DEVICE_PERIPHERALS } { + return None; + } + Some(unsafe { Peripherals::steal() }) + }) + } + #[doc = r" Unchecked version of `Peripherals::take`."] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r""] + #[doc = r" Each of the returned peripherals must be used at most once."] + #[inline] + pub unsafe fn steal() -> Self { + DEVICE_PERIPHERALS = true; + Peripherals { + timer0: Timer0::steal(), + timer1: Timer1::steal(), + timer2: Timer2::steal(), + } + } +} diff --git a/zynq7000/src/timer0.rs b/zynq7000/src/timer0.rs new file mode 100644 index 0000000..548fbd5 --- /dev/null +++ b/zynq7000/src/timer0.rs @@ -0,0 +1,110 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + cr: Cr, + sr: Sr, + _reserved2: [u8; 0x0a], + int: Int, + _reserved3: [u8; 0x0e], + count: Count, + match_: Match, + _reserved_5_prescale: [u8; 0x04], + _reserved6: [u8; 0x24], + reload: [Reload; 4], +} +impl RegisterBlock { + #[doc = "0x00 - Control Register"] + #[inline(always)] + pub const fn cr(&self) -> &Cr { + &self.cr + } + #[doc = "0x04 - Status Register"] + #[inline(always)] + pub const fn sr(&self) -> &Sr { + &self.sr + } + #[doc = "0x10 - Interrupt Register"] + #[inline(always)] + pub const fn int(&self) -> &Int { + &self.int + } + #[doc = "0x20 - The Counter Register reflects the actual Value of the Timer/Counter"] + #[inline(always)] + pub const fn count(&self) -> &Count { + &self.count + } + #[doc = "0x24 - The Match Register stores the compare Value for the MATCH condition"] + #[inline(always)] + pub const fn match_(&self) -> &Match { + &self.match_ + } + #[doc = "0x28 - The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value"] + #[inline(always)] + pub const fn prescale_wr(&self) -> &PrescaleWr { + unsafe { &*core::ptr::from_ref(self).cast::().add(40).cast() } + } + #[doc = "0x28 - The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value"] + #[inline(always)] + pub const fn prescale_rd(&self) -> &PrescaleRd { + unsafe { &*core::ptr::from_ref(self).cast::().add(40).cast() } + } + #[doc = "0x50..0x60 - The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met."] + #[inline(always)] + pub const fn reload(&self, n: usize) -> &Reload { + &self.reload[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x50..0x60 - The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met."] + #[inline(always)] + pub fn reload_iter(&self) -> impl Iterator { + self.reload.iter() + } +} +#[doc = "CR (rw) register accessor: Control Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cr::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cr::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@cr`] +module"] +#[doc(alias = "CR")] +pub type Cr = crate::Reg; +#[doc = "Control Register"] +pub mod cr; +#[doc = "SR (rw) register accessor: Status Register\n\nYou can [`read`](crate::Reg::read) this register and get [`sr::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`sr::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@sr`] +module"] +#[doc(alias = "SR")] +pub type Sr = crate::Reg; +#[doc = "Status Register"] +pub mod sr; +#[doc = "INT (rw) register accessor: Interrupt Register\n\nYou can [`read`](crate::Reg::read) this register and get [`int::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`int::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@int`] +module"] +#[doc(alias = "INT")] +pub type Int = crate::Reg; +#[doc = "Interrupt Register"] +pub mod int; +#[doc = "COUNT (rw) register accessor: The Counter Register reflects the actual Value of the Timer/Counter\n\nYou can [`read`](crate::Reg::read) this register and get [`count::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`count::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@count`] +module"] +#[doc(alias = "COUNT")] +pub type Count = crate::Reg; +#[doc = "The Counter Register reflects the actual Value of the Timer/Counter"] +pub mod count; +#[doc = "MATCH (rw) register accessor: The Match Register stores the compare Value for the MATCH condition\n\nYou can [`read`](crate::Reg::read) this register and get [`match_::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`match_::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@match_`] +module"] +#[doc(alias = "MATCH")] +pub type Match = crate::Reg; +#[doc = "The Match Register stores the compare Value for the MATCH condition"] +pub mod match_; +#[doc = "PRESCALE_RD (r) register accessor: The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value\n\nYou can [`read`](crate::Reg::read) this register and get [`prescale_rd::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@prescale_rd`] +module"] +#[doc(alias = "PRESCALE_RD")] +pub type PrescaleRd = crate::Reg; +#[doc = "The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value"] +pub mod prescale_rd; +#[doc = "PRESCALE_WR (w) register accessor: The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value\n\nYou can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`prescale_wr::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@prescale_wr`] +module"] +#[doc(alias = "PRESCALE_WR")] +pub type PrescaleWr = crate::Reg; +#[doc = "The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value"] +pub mod prescale_wr; +#[doc = "RELOAD (rw) register accessor: The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met.\n\nYou can [`read`](crate::Reg::read) this register and get [`reload::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`reload::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@reload`] +module"] +#[doc(alias = "RELOAD")] +pub type Reload = crate::Reg; +#[doc = "The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met."] +pub mod reload; diff --git a/zynq7000/src/timer0/count.rs b/zynq7000/src/timer0/count.rs new file mode 100644 index 0000000..bfac5e8 --- /dev/null +++ b/zynq7000/src/timer0/count.rs @@ -0,0 +1,28 @@ +#[doc = "Register `COUNT` reader"] +pub type R = crate::R; +#[doc = "Register `COUNT` writer"] +pub type W = crate::W; +#[cfg(feature = "debug")] +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "The Counter Register reflects the actual Value of the Timer/Counter\n\nYou can [`read`](crate::Reg::read) this register and get [`count::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`count::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CountSpec; +impl crate::RegisterSpec for CountSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`count::R`](R) reader structure"] +impl crate::Readable for CountSpec {} +#[doc = "`write(|w| ..)` method takes [`count::W`](W) writer structure"] +impl crate::Writable for CountSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets COUNT to value 0"] +impl crate::Resettable for CountSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/cr.rs b/zynq7000/src/timer0/cr.rs new file mode 100644 index 0000000..03f7b15 --- /dev/null +++ b/zynq7000/src/timer0/cr.rs @@ -0,0 +1,1225 @@ +#[doc = "Register `CR` reader"] +pub type R = crate::R; +#[doc = "Register `CR` writer"] +pub type W = crate::W; +#[doc = "Enable\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum En { + #[doc = "0: Timer is disabled and does not operate"] + Disable = 0, + #[doc = "1: Timer is enabled and can operate"] + Enable = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: En) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `EN` reader - Enable"] +pub type EnR = crate::BitReader; +impl EnR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> En { + match self.bits { + false => En::Disable, + true => En::Enable, + } + } + #[doc = "Timer is disabled and does not operate"] + #[inline(always)] + pub fn is_disable(&self) -> bool { + *self == En::Disable + } + #[doc = "Timer is enabled and can operate"] + #[inline(always)] + pub fn is_enable(&self) -> bool { + *self == En::Enable + } +} +#[doc = "Field `EN` writer - Enable"] +pub type EnW<'a, REG> = crate::BitWriter<'a, REG, En>; +impl<'a, REG> EnW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "Timer is disabled and does not operate"] + #[inline(always)] + pub fn disable(self) -> &'a mut crate::W { + self.variant(En::Disable) + } + #[doc = "Timer is enabled and can operate"] + #[inline(always)] + pub fn enable(self) -> &'a mut crate::W { + self.variant(En::Enable) + } +} +#[doc = "Reset Timer\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Rst { + #[doc = "0: Write as ZERO if necessary"] + NoAction = 0, + #[doc = "1: Reset the Timer"] + ResetTimer = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Rst) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `RST` writer - Reset Timer"] +pub type RstW<'a, REG> = crate::BitWriter<'a, REG, Rst>; +impl<'a, REG> RstW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "Write as ZERO if necessary"] + #[inline(always)] + pub fn no_action(self) -> &'a mut crate::W { + self.variant(Rst::NoAction) + } + #[doc = "Reset the Timer"] + #[inline(always)] + pub fn reset_timer(self) -> &'a mut crate::W { + self.variant(Rst::ResetTimer) + } +} +#[doc = "Counting direction\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Cnt { + #[doc = "0: Timer Counts UO and wraps, if no STOP condition is set"] + CountUp = 0, + #[doc = "1: Timer Counts DOWN and wraps, if no STOP condition is set"] + CountDown = 1, + #[doc = "2: Timer Counts up to MAX, then DOWN to ZERO, if no STOP condition is set"] + Toggle = 2, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Cnt) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Cnt { + type Ux = u8; +} +impl crate::IsEnum for Cnt {} +#[doc = "Field `CNT` reader - Counting direction"] +pub type CntR = crate::FieldReader; +impl CntR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Cnt::CountUp), + 1 => Some(Cnt::CountDown), + 2 => Some(Cnt::Toggle), + _ => None, + } + } + #[doc = "Timer Counts UO and wraps, if no STOP condition is set"] + #[inline(always)] + pub fn is_count_up(&self) -> bool { + *self == Cnt::CountUp + } + #[doc = "Timer Counts DOWN and wraps, if no STOP condition is set"] + #[inline(always)] + pub fn is_count_down(&self) -> bool { + *self == Cnt::CountDown + } + #[doc = "Timer Counts up to MAX, then DOWN to ZERO, if no STOP condition is set"] + #[inline(always)] + pub fn is_toggle(&self) -> bool { + *self == Cnt::Toggle + } +} +#[doc = "Field `CNT` writer - Counting direction"] +pub type CntW<'a, REG> = crate::FieldWriter<'a, REG, 2, Cnt>; +impl<'a, REG> CntW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Timer Counts UO and wraps, if no STOP condition is set"] + #[inline(always)] + pub fn count_up(self) -> &'a mut crate::W { + self.variant(Cnt::CountUp) + } + #[doc = "Timer Counts DOWN and wraps, if no STOP condition is set"] + #[inline(always)] + pub fn count_down(self) -> &'a mut crate::W { + self.variant(Cnt::CountDown) + } + #[doc = "Timer Counts up to MAX, then DOWN to ZERO, if no STOP condition is set"] + #[inline(always)] + pub fn toggle(self) -> &'a mut crate::W { + self.variant(Cnt::Toggle) + } +} +#[doc = "Operation Mode\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Mode { + #[doc = "0: Timer runs continously"] + Continous = 0, + #[doc = "1: Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT) and stops"] + SingleZeroMax = 1, + #[doc = "2: Timer counts to the Value of MATCH Register and stops"] + SingleMatch = 2, + #[doc = "3: Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT), loads the RELOAD Value and continues"] + ReloadZeroMax = 3, + #[doc = "4: Timer counts to the Value of MATCH Register, loads the RELOAD Value and continues"] + ReloadMatch = 4, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Mode) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Mode { + type Ux = u8; +} +impl crate::IsEnum for Mode {} +#[doc = "Field `MODE` reader - Operation Mode"] +pub type ModeR = crate::FieldReader; +impl ModeR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Mode::Continous), + 1 => Some(Mode::SingleZeroMax), + 2 => Some(Mode::SingleMatch), + 3 => Some(Mode::ReloadZeroMax), + 4 => Some(Mode::ReloadMatch), + _ => None, + } + } + #[doc = "Timer runs continously"] + #[inline(always)] + pub fn is_continous(&self) -> bool { + *self == Mode::Continous + } + #[doc = "Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT) and stops"] + #[inline(always)] + pub fn is_single_zero_max(&self) -> bool { + *self == Mode::SingleZeroMax + } + #[doc = "Timer counts to the Value of MATCH Register and stops"] + #[inline(always)] + pub fn is_single_match(&self) -> bool { + *self == Mode::SingleMatch + } + #[doc = "Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT), loads the RELOAD Value and continues"] + #[inline(always)] + pub fn is_reload_zero_max(&self) -> bool { + *self == Mode::ReloadZeroMax + } + #[doc = "Timer counts to the Value of MATCH Register, loads the RELOAD Value and continues"] + #[inline(always)] + pub fn is_reload_match(&self) -> bool { + *self == Mode::ReloadMatch + } +} +#[doc = "Field `MODE` writer - Operation Mode"] +pub type ModeW<'a, REG> = crate::FieldWriter<'a, REG, 3, Mode>; +impl<'a, REG> ModeW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Timer runs continously"] + #[inline(always)] + pub fn continous(self) -> &'a mut crate::W { + self.variant(Mode::Continous) + } + #[doc = "Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT) and stops"] + #[inline(always)] + pub fn single_zero_max(self) -> &'a mut crate::W { + self.variant(Mode::SingleZeroMax) + } + #[doc = "Timer counts to the Value of MATCH Register and stops"] + #[inline(always)] + pub fn single_match(self) -> &'a mut crate::W { + self.variant(Mode::SingleMatch) + } + #[doc = "Timer counts to 0x00 or 0xFFFFFFFF (depending on CNT), loads the RELOAD Value and continues"] + #[inline(always)] + pub fn reload_zero_max(self) -> &'a mut crate::W { + self.variant(Mode::ReloadZeroMax) + } + #[doc = "Timer counts to the Value of MATCH Register, loads the RELOAD Value and continues"] + #[inline(always)] + pub fn reload_match(self) -> &'a mut crate::W { + self.variant(Mode::ReloadMatch) + } +} +#[doc = "Use Prescaler\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Psc { + #[doc = "0: Prescaler is not used"] + Disabled = 0, + #[doc = "1: Prescaler is used as divider"] + Enabled = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Psc) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `PSC` reader - Use Prescaler"] +pub type PscR = crate::BitReader; +impl PscR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Psc { + match self.bits { + false => Psc::Disabled, + true => Psc::Enabled, + } + } + #[doc = "Prescaler is not used"] + #[inline(always)] + pub fn is_disabled(&self) -> bool { + *self == Psc::Disabled + } + #[doc = "Prescaler is used as divider"] + #[inline(always)] + pub fn is_enabled(&self) -> bool { + *self == Psc::Enabled + } +} +#[doc = "Field `PSC` writer - Use Prescaler"] +pub type PscW<'a, REG> = crate::BitWriter<'a, REG, Psc>; +impl<'a, REG> PscW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "Prescaler is not used"] + #[inline(always)] + pub fn disabled(self) -> &'a mut crate::W { + self.variant(Psc::Disabled) + } + #[doc = "Prescaler is used as divider"] + #[inline(always)] + pub fn enabled(self) -> &'a mut crate::W { + self.variant(Psc::Enabled) + } +} +#[doc = "Timer / Counter Source Divider\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Cntsrc { + #[doc = "0: Capture Source is used directly"] + CapSrc = 0, + #[doc = "1: Capture Source is divided by 2"] + CapSrcDiv2 = 1, + #[doc = "2: Capture Source is divided by 4"] + CapSrcDiv4 = 2, + #[doc = "3: Capture Source is divided by 8"] + CapSrcDiv8 = 3, + #[doc = "4: Capture Source is divided by 16"] + CapSrcDiv16 = 4, + #[doc = "5: Capture Source is divided by 32"] + CapSrcDiv32 = 5, + #[doc = "6: Capture Source is divided by 64"] + CapSrcDiv64 = 6, + #[doc = "7: Capture Source is divided by 128"] + CapSrcDiv128 = 7, + #[doc = "8: Capture Source is divided by 256"] + CapSrcDiv256 = 8, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Cntsrc) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Cntsrc { + type Ux = u8; +} +impl crate::IsEnum for Cntsrc {} +#[doc = "Field `CNTSRC` reader - Timer / Counter Source Divider"] +pub type CntsrcR = crate::FieldReader; +impl CntsrcR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Cntsrc::CapSrc), + 1 => Some(Cntsrc::CapSrcDiv2), + 2 => Some(Cntsrc::CapSrcDiv4), + 3 => Some(Cntsrc::CapSrcDiv8), + 4 => Some(Cntsrc::CapSrcDiv16), + 5 => Some(Cntsrc::CapSrcDiv32), + 6 => Some(Cntsrc::CapSrcDiv64), + 7 => Some(Cntsrc::CapSrcDiv128), + 8 => Some(Cntsrc::CapSrcDiv256), + _ => None, + } + } + #[doc = "Capture Source is used directly"] + #[inline(always)] + pub fn is_cap_src(&self) -> bool { + *self == Cntsrc::CapSrc + } + #[doc = "Capture Source is divided by 2"] + #[inline(always)] + pub fn is_cap_src_div2(&self) -> bool { + *self == Cntsrc::CapSrcDiv2 + } + #[doc = "Capture Source is divided by 4"] + #[inline(always)] + pub fn is_cap_src_div4(&self) -> bool { + *self == Cntsrc::CapSrcDiv4 + } + #[doc = "Capture Source is divided by 8"] + #[inline(always)] + pub fn is_cap_src_div8(&self) -> bool { + *self == Cntsrc::CapSrcDiv8 + } + #[doc = "Capture Source is divided by 16"] + #[inline(always)] + pub fn is_cap_src_div16(&self) -> bool { + *self == Cntsrc::CapSrcDiv16 + } + #[doc = "Capture Source is divided by 32"] + #[inline(always)] + pub fn is_cap_src_div32(&self) -> bool { + *self == Cntsrc::CapSrcDiv32 + } + #[doc = "Capture Source is divided by 64"] + #[inline(always)] + pub fn is_cap_src_div64(&self) -> bool { + *self == Cntsrc::CapSrcDiv64 + } + #[doc = "Capture Source is divided by 128"] + #[inline(always)] + pub fn is_cap_src_div128(&self) -> bool { + *self == Cntsrc::CapSrcDiv128 + } + #[doc = "Capture Source is divided by 256"] + #[inline(always)] + pub fn is_cap_src_div256(&self) -> bool { + *self == Cntsrc::CapSrcDiv256 + } +} +#[doc = "Field `CNTSRC` writer - Timer / Counter Source Divider"] +pub type CntsrcW<'a, REG> = crate::FieldWriter<'a, REG, 4, Cntsrc>; +impl<'a, REG> CntsrcW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Capture Source is used directly"] + #[inline(always)] + pub fn cap_src(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrc) + } + #[doc = "Capture Source is divided by 2"] + #[inline(always)] + pub fn cap_src_div2(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv2) + } + #[doc = "Capture Source is divided by 4"] + #[inline(always)] + pub fn cap_src_div4(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv4) + } + #[doc = "Capture Source is divided by 8"] + #[inline(always)] + pub fn cap_src_div8(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv8) + } + #[doc = "Capture Source is divided by 16"] + #[inline(always)] + pub fn cap_src_div16(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv16) + } + #[doc = "Capture Source is divided by 32"] + #[inline(always)] + pub fn cap_src_div32(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv32) + } + #[doc = "Capture Source is divided by 64"] + #[inline(always)] + pub fn cap_src_div64(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv64) + } + #[doc = "Capture Source is divided by 128"] + #[inline(always)] + pub fn cap_src_div128(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv128) + } + #[doc = "Capture Source is divided by 256"] + #[inline(always)] + pub fn cap_src_div256(self) -> &'a mut crate::W { + self.variant(Cntsrc::CapSrcDiv256) + } +} +#[doc = "Timer / Counter Capture Source\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Capsrc { + #[doc = "0: Core Clock"] + Cclk = 0, + #[doc = "1: GPIO A, PIN 0"] + Gpioa0 = 1, + #[doc = "2: GPIO A, PIN 1"] + Gpioa1 = 2, + #[doc = "3: GPIO A, PIN 2"] + Gpioa2 = 3, + #[doc = "4: GPIO A, PIN 3"] + Gpioa3 = 4, + #[doc = "5: GPIO A, PIN 4"] + Gpioa4 = 5, + #[doc = "6: GPIO A, PIN 5"] + Gpioa5 = 6, + #[doc = "7: GPIO A, PIN 6"] + Gpioa6 = 7, + #[doc = "8: GPIO A, PIN 7"] + Gpioa7 = 8, + #[doc = "9: GPIO B, PIN 0"] + Gpiob0 = 9, + #[doc = "10: GPIO B, PIN 1"] + Gpiob1 = 10, + #[doc = "11: GPIO B, PIN 2"] + Gpiob2 = 11, + #[doc = "12: GPIO B, PIN 3"] + Gpiob3 = 12, + #[doc = "13: GPIO C, PIN 0"] + Gpioc0 = 13, + #[doc = "14: GPIO C, PIN 1"] + Gpioc5 = 14, + #[doc = "15: GPIO C, PIN 2"] + Gpioc6 = 15, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Capsrc) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Capsrc { + type Ux = u8; +} +impl crate::IsEnum for Capsrc {} +#[doc = "Field `CAPSRC` reader - Timer / Counter Capture Source"] +pub type CapsrcR = crate::FieldReader; +impl CapsrcR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Capsrc { + match self.bits { + 0 => Capsrc::Cclk, + 1 => Capsrc::Gpioa0, + 2 => Capsrc::Gpioa1, + 3 => Capsrc::Gpioa2, + 4 => Capsrc::Gpioa3, + 5 => Capsrc::Gpioa4, + 6 => Capsrc::Gpioa5, + 7 => Capsrc::Gpioa6, + 8 => Capsrc::Gpioa7, + 9 => Capsrc::Gpiob0, + 10 => Capsrc::Gpiob1, + 11 => Capsrc::Gpiob2, + 12 => Capsrc::Gpiob3, + 13 => Capsrc::Gpioc0, + 14 => Capsrc::Gpioc5, + 15 => Capsrc::Gpioc6, + _ => unreachable!(), + } + } + #[doc = "Core Clock"] + #[inline(always)] + pub fn is_cclk(&self) -> bool { + *self == Capsrc::Cclk + } + #[doc = "GPIO A, PIN 0"] + #[inline(always)] + pub fn is_gpioa_0(&self) -> bool { + *self == Capsrc::Gpioa0 + } + #[doc = "GPIO A, PIN 1"] + #[inline(always)] + pub fn is_gpioa_1(&self) -> bool { + *self == Capsrc::Gpioa1 + } + #[doc = "GPIO A, PIN 2"] + #[inline(always)] + pub fn is_gpioa_2(&self) -> bool { + *self == Capsrc::Gpioa2 + } + #[doc = "GPIO A, PIN 3"] + #[inline(always)] + pub fn is_gpioa_3(&self) -> bool { + *self == Capsrc::Gpioa3 + } + #[doc = "GPIO A, PIN 4"] + #[inline(always)] + pub fn is_gpioa_4(&self) -> bool { + *self == Capsrc::Gpioa4 + } + #[doc = "GPIO A, PIN 5"] + #[inline(always)] + pub fn is_gpioa_5(&self) -> bool { + *self == Capsrc::Gpioa5 + } + #[doc = "GPIO A, PIN 6"] + #[inline(always)] + pub fn is_gpioa_6(&self) -> bool { + *self == Capsrc::Gpioa6 + } + #[doc = "GPIO A, PIN 7"] + #[inline(always)] + pub fn is_gpioa_7(&self) -> bool { + *self == Capsrc::Gpioa7 + } + #[doc = "GPIO B, PIN 0"] + #[inline(always)] + pub fn is_gpiob_0(&self) -> bool { + *self == Capsrc::Gpiob0 + } + #[doc = "GPIO B, PIN 1"] + #[inline(always)] + pub fn is_gpiob_1(&self) -> bool { + *self == Capsrc::Gpiob1 + } + #[doc = "GPIO B, PIN 2"] + #[inline(always)] + pub fn is_gpiob_2(&self) -> bool { + *self == Capsrc::Gpiob2 + } + #[doc = "GPIO B, PIN 3"] + #[inline(always)] + pub fn is_gpiob_3(&self) -> bool { + *self == Capsrc::Gpiob3 + } + #[doc = "GPIO C, PIN 0"] + #[inline(always)] + pub fn is_gpioc_0(&self) -> bool { + *self == Capsrc::Gpioc0 + } + #[doc = "GPIO C, PIN 1"] + #[inline(always)] + pub fn is_gpioc_5(&self) -> bool { + *self == Capsrc::Gpioc5 + } + #[doc = "GPIO C, PIN 2"] + #[inline(always)] + pub fn is_gpioc_6(&self) -> bool { + *self == Capsrc::Gpioc6 + } +} +#[doc = "Field `CAPSRC` writer - Timer / Counter Capture Source"] +pub type CapsrcW<'a, REG> = crate::FieldWriter<'a, REG, 4, Capsrc, crate::Safe>; +impl<'a, REG> CapsrcW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Core Clock"] + #[inline(always)] + pub fn cclk(self) -> &'a mut crate::W { + self.variant(Capsrc::Cclk) + } + #[doc = "GPIO A, PIN 0"] + #[inline(always)] + pub fn gpioa_0(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa0) + } + #[doc = "GPIO A, PIN 1"] + #[inline(always)] + pub fn gpioa_1(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa1) + } + #[doc = "GPIO A, PIN 2"] + #[inline(always)] + pub fn gpioa_2(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa2) + } + #[doc = "GPIO A, PIN 3"] + #[inline(always)] + pub fn gpioa_3(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa3) + } + #[doc = "GPIO A, PIN 4"] + #[inline(always)] + pub fn gpioa_4(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa4) + } + #[doc = "GPIO A, PIN 5"] + #[inline(always)] + pub fn gpioa_5(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa5) + } + #[doc = "GPIO A, PIN 6"] + #[inline(always)] + pub fn gpioa_6(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa6) + } + #[doc = "GPIO A, PIN 7"] + #[inline(always)] + pub fn gpioa_7(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioa7) + } + #[doc = "GPIO B, PIN 0"] + #[inline(always)] + pub fn gpiob_0(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpiob0) + } + #[doc = "GPIO B, PIN 1"] + #[inline(always)] + pub fn gpiob_1(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpiob1) + } + #[doc = "GPIO B, PIN 2"] + #[inline(always)] + pub fn gpiob_2(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpiob2) + } + #[doc = "GPIO B, PIN 3"] + #[inline(always)] + pub fn gpiob_3(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpiob3) + } + #[doc = "GPIO C, PIN 0"] + #[inline(always)] + pub fn gpioc_0(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioc0) + } + #[doc = "GPIO C, PIN 1"] + #[inline(always)] + pub fn gpioc_5(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioc5) + } + #[doc = "GPIO C, PIN 2"] + #[inline(always)] + pub fn gpioc_6(self) -> &'a mut crate::W { + self.variant(Capsrc::Gpioc6) + } +} +#[doc = "Capture Edge, select which Edge should result in a counter increment or decrement\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Capedge { + #[doc = "0: Only rising edges result in a counter increment or decrement"] + Rising = 0, + #[doc = "1: Only falling edges result in a counter increment or decrement"] + Falling = 1, + #[doc = "2: Rising and falling edges result in a counter increment or decrement"] + Both = 2, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Capedge) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Capedge { + type Ux = u8; +} +impl crate::IsEnum for Capedge {} +#[doc = "Field `CAPEDGE` reader - Capture Edge, select which Edge should result in a counter increment or decrement"] +pub type CapedgeR = crate::FieldReader; +impl CapedgeR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Capedge::Rising), + 1 => Some(Capedge::Falling), + 2 => Some(Capedge::Both), + _ => None, + } + } + #[doc = "Only rising edges result in a counter increment or decrement"] + #[inline(always)] + pub fn is_rising(&self) -> bool { + *self == Capedge::Rising + } + #[doc = "Only falling edges result in a counter increment or decrement"] + #[inline(always)] + pub fn is_falling(&self) -> bool { + *self == Capedge::Falling + } + #[doc = "Rising and falling edges result in a counter increment or decrement"] + #[inline(always)] + pub fn is_both(&self) -> bool { + *self == Capedge::Both + } +} +#[doc = "Field `CAPEDGE` writer - Capture Edge, select which Edge should result in a counter increment or decrement"] +pub type CapedgeW<'a, REG> = crate::FieldWriter<'a, REG, 2, Capedge>; +impl<'a, REG> CapedgeW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Only rising edges result in a counter increment or decrement"] + #[inline(always)] + pub fn rising(self) -> &'a mut crate::W { + self.variant(Capedge::Rising) + } + #[doc = "Only falling edges result in a counter increment or decrement"] + #[inline(always)] + pub fn falling(self) -> &'a mut crate::W { + self.variant(Capedge::Falling) + } + #[doc = "Rising and falling edges result in a counter increment or decrement"] + #[inline(always)] + pub fn both(self) -> &'a mut crate::W { + self.variant(Capedge::Both) + } +} +#[doc = "Triggers an other Peripheral\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Trgext { + #[doc = "0: No Trigger is emitted"] + None = 0, + #[doc = "1: DMA Controller 1 is triggered, dependant on MODE"] + Dma1 = 1, + #[doc = "2: DMA Controller 2 is triggered, dependant on MODE"] + Dma2 = 2, + #[doc = "3: UART is triggered, dependant on MODE"] + Uart = 3, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Trgext) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Trgext { + type Ux = u8; +} +impl crate::IsEnum for Trgext {} +#[doc = "Field `TRGEXT` reader - Triggers an other Peripheral"] +pub type TrgextR = crate::FieldReader; +impl TrgextR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Trgext { + match self.bits { + 0 => Trgext::None, + 1 => Trgext::Dma1, + 2 => Trgext::Dma2, + 3 => Trgext::Uart, + _ => unreachable!(), + } + } + #[doc = "No Trigger is emitted"] + #[inline(always)] + pub fn is_none(&self) -> bool { + *self == Trgext::None + } + #[doc = "DMA Controller 1 is triggered, dependant on MODE"] + #[inline(always)] + pub fn is_dma1(&self) -> bool { + *self == Trgext::Dma1 + } + #[doc = "DMA Controller 2 is triggered, dependant on MODE"] + #[inline(always)] + pub fn is_dma2(&self) -> bool { + *self == Trgext::Dma2 + } + #[doc = "UART is triggered, dependant on MODE"] + #[inline(always)] + pub fn is_uart(&self) -> bool { + *self == Trgext::Uart + } +} +#[doc = "Field `TRGEXT` writer - Triggers an other Peripheral"] +pub type TrgextW<'a, REG> = crate::FieldWriter<'a, REG, 2, Trgext, crate::Safe>; +impl<'a, REG> TrgextW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "No Trigger is emitted"] + #[inline(always)] + pub fn none(self) -> &'a mut crate::W { + self.variant(Trgext::None) + } + #[doc = "DMA Controller 1 is triggered, dependant on MODE"] + #[inline(always)] + pub fn dma1(self) -> &'a mut crate::W { + self.variant(Trgext::Dma1) + } + #[doc = "DMA Controller 2 is triggered, dependant on MODE"] + #[inline(always)] + pub fn dma2(self) -> &'a mut crate::W { + self.variant(Trgext::Dma2) + } + #[doc = "UART is triggered, dependant on MODE"] + #[inline(always)] + pub fn uart(self) -> &'a mut crate::W { + self.variant(Trgext::Uart) + } +} +#[doc = "Select RELOAD Register n to reload Timer on condition\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Reload { + #[doc = "0: Selects Reload Register number 0"] + Reload0 = 0, + #[doc = "1: Selects Reload Register number 1"] + Reload1 = 1, + #[doc = "2: Selects Reload Register number 2"] + Reload2 = 2, + #[doc = "3: Selects Reload Register number 3"] + Reload3 = 3, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Reload) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Reload { + type Ux = u8; +} +impl crate::IsEnum for Reload {} +#[doc = "Field `RELOAD` reader - Select RELOAD Register n to reload Timer on condition"] +pub type ReloadR = crate::FieldReader; +impl ReloadR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Reload { + match self.bits { + 0 => Reload::Reload0, + 1 => Reload::Reload1, + 2 => Reload::Reload2, + 3 => Reload::Reload3, + _ => unreachable!(), + } + } + #[doc = "Selects Reload Register number 0"] + #[inline(always)] + pub fn is_reload0(&self) -> bool { + *self == Reload::Reload0 + } + #[doc = "Selects Reload Register number 1"] + #[inline(always)] + pub fn is_reload1(&self) -> bool { + *self == Reload::Reload1 + } + #[doc = "Selects Reload Register number 2"] + #[inline(always)] + pub fn is_reload2(&self) -> bool { + *self == Reload::Reload2 + } + #[doc = "Selects Reload Register number 3"] + #[inline(always)] + pub fn is_reload3(&self) -> bool { + *self == Reload::Reload3 + } +} +#[doc = "Field `RELOAD` writer - Select RELOAD Register n to reload Timer on condition"] +pub type ReloadW<'a, REG> = crate::FieldWriter<'a, REG, 2, Reload, crate::Safe>; +impl<'a, REG> ReloadW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Selects Reload Register number 0"] + #[inline(always)] + pub fn reload0(self) -> &'a mut crate::W { + self.variant(Reload::Reload0) + } + #[doc = "Selects Reload Register number 1"] + #[inline(always)] + pub fn reload1(self) -> &'a mut crate::W { + self.variant(Reload::Reload1) + } + #[doc = "Selects Reload Register number 2"] + #[inline(always)] + pub fn reload2(self) -> &'a mut crate::W { + self.variant(Reload::Reload2) + } + #[doc = "Selects Reload Register number 3"] + #[inline(always)] + pub fn reload3(self) -> &'a mut crate::W { + self.variant(Reload::Reload3) + } +} +#[doc = "Selects, if Reload Register number is incremented, decremented or not modified\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Idr { + #[doc = "0: Reload Register number does not change automatically"] + Keep = 0, + #[doc = "1: Reload Register number is incremented on each match"] + Increment = 1, + #[doc = "2: Reload Register number is decremented on each match"] + Decrement = 2, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Idr) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Idr { + type Ux = u8; +} +impl crate::IsEnum for Idr {} +#[doc = "Field `IDR` reader - Selects, if Reload Register number is incremented, decremented or not modified"] +pub type IdrR = crate::FieldReader; +impl IdrR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Idr::Keep), + 1 => Some(Idr::Increment), + 2 => Some(Idr::Decrement), + _ => None, + } + } + #[doc = "Reload Register number does not change automatically"] + #[inline(always)] + pub fn is_keep(&self) -> bool { + *self == Idr::Keep + } + #[doc = "Reload Register number is incremented on each match"] + #[inline(always)] + pub fn is_increment(&self) -> bool { + *self == Idr::Increment + } + #[doc = "Reload Register number is decremented on each match"] + #[inline(always)] + pub fn is_decrement(&self) -> bool { + *self == Idr::Decrement + } +} +#[doc = "Field `IDR` writer - Selects, if Reload Register number is incremented, decremented or not modified"] +pub type IdrW<'a, REG> = crate::FieldWriter<'a, REG, 2, Idr>; +impl<'a, REG> IdrW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Reload Register number does not change automatically"] + #[inline(always)] + pub fn keep(self) -> &'a mut crate::W { + self.variant(Idr::Keep) + } + #[doc = "Reload Register number is incremented on each match"] + #[inline(always)] + pub fn increment(self) -> &'a mut crate::W { + self.variant(Idr::Increment) + } + #[doc = "Reload Register number is decremented on each match"] + #[inline(always)] + pub fn decrement(self) -> &'a mut crate::W { + self.variant(Idr::Decrement) + } +} +#[doc = "Starts and Stops the Timer / Counter\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum S { + #[doc = "0: Timer / Counter is stopped"] + Stop = 0, + #[doc = "1: Timer / Counter is started"] + Start = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: S) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `S` reader - Starts and Stops the Timer / Counter"] +pub type SR = crate::BitReader; +impl SR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> S { + match self.bits { + false => S::Stop, + true => S::Start, + } + } + #[doc = "Timer / Counter is stopped"] + #[inline(always)] + pub fn is_stop(&self) -> bool { + *self == S::Stop + } + #[doc = "Timer / Counter is started"] + #[inline(always)] + pub fn is_start(&self) -> bool { + *self == S::Start + } +} +#[doc = "Field `S` writer - Starts and Stops the Timer / Counter"] +pub type SW<'a, REG> = crate::BitWriter<'a, REG, S>; +impl<'a, REG> SW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "Timer / Counter is stopped"] + #[inline(always)] + pub fn stop(self) -> &'a mut crate::W { + self.variant(S::Stop) + } + #[doc = "Timer / Counter is started"] + #[inline(always)] + pub fn start(self) -> &'a mut crate::W { + self.variant(S::Start) + } +} +impl R { + #[doc = "Bit 0 - Enable"] + #[inline(always)] + pub fn en(&self) -> EnR { + EnR::new((self.bits & 1) != 0) + } + #[doc = "Bits 2:3 - Counting direction"] + #[inline(always)] + pub fn cnt(&self) -> CntR { + CntR::new(((self.bits >> 2) & 3) as u8) + } + #[doc = "Bits 4:6 - Operation Mode"] + #[inline(always)] + pub fn mode(&self) -> ModeR { + ModeR::new(((self.bits >> 4) & 7) as u8) + } + #[doc = "Bit 7 - Use Prescaler"] + #[inline(always)] + pub fn psc(&self) -> PscR { + PscR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bits 8:11 - Timer / Counter Source Divider"] + #[inline(always)] + pub fn cntsrc(&self) -> CntsrcR { + CntsrcR::new(((self.bits >> 8) & 0x0f) as u8) + } + #[doc = "Bits 12:15 - Timer / Counter Capture Source"] + #[inline(always)] + pub fn capsrc(&self) -> CapsrcR { + CapsrcR::new(((self.bits >> 12) & 0x0f) as u8) + } + #[doc = "Bits 16:17 - Capture Edge, select which Edge should result in a counter increment or decrement"] + #[inline(always)] + pub fn capedge(&self) -> CapedgeR { + CapedgeR::new(((self.bits >> 16) & 3) as u8) + } + #[doc = "Bits 20:21 - Triggers an other Peripheral"] + #[inline(always)] + pub fn trgext(&self) -> TrgextR { + TrgextR::new(((self.bits >> 20) & 3) as u8) + } + #[doc = "Bits 24:25 - Select RELOAD Register n to reload Timer on condition"] + #[inline(always)] + pub fn reload(&self) -> ReloadR { + ReloadR::new(((self.bits >> 24) & 3) as u8) + } + #[doc = "Bits 26:27 - Selects, if Reload Register number is incremented, decremented or not modified"] + #[inline(always)] + pub fn idr(&self) -> IdrR { + IdrR::new(((self.bits >> 26) & 3) as u8) + } + #[doc = "Bit 31 - Starts and Stops the Timer / Counter"] + #[inline(always)] + pub fn s(&self) -> SR { + SR::new(((self.bits >> 31) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Enable"] + #[inline(always)] + pub fn en(&mut self) -> EnW { + EnW::new(self, 0) + } + #[doc = "Bit 1 - Reset Timer"] + #[inline(always)] + pub fn rst(&mut self) -> RstW { + RstW::new(self, 1) + } + #[doc = "Bits 2:3 - Counting direction"] + #[inline(always)] + pub fn cnt(&mut self) -> CntW { + CntW::new(self, 2) + } + #[doc = "Bits 4:6 - Operation Mode"] + #[inline(always)] + pub fn mode(&mut self) -> ModeW { + ModeW::new(self, 4) + } + #[doc = "Bit 7 - Use Prescaler"] + #[inline(always)] + pub fn psc(&mut self) -> PscW { + PscW::new(self, 7) + } + #[doc = "Bits 8:11 - Timer / Counter Source Divider"] + #[inline(always)] + pub fn cntsrc(&mut self) -> CntsrcW { + CntsrcW::new(self, 8) + } + #[doc = "Bits 12:15 - Timer / Counter Capture Source"] + #[inline(always)] + pub fn capsrc(&mut self) -> CapsrcW { + CapsrcW::new(self, 12) + } + #[doc = "Bits 16:17 - Capture Edge, select which Edge should result in a counter increment or decrement"] + #[inline(always)] + pub fn capedge(&mut self) -> CapedgeW { + CapedgeW::new(self, 16) + } + #[doc = "Bits 20:21 - Triggers an other Peripheral"] + #[inline(always)] + pub fn trgext(&mut self) -> TrgextW { + TrgextW::new(self, 20) + } + #[doc = "Bits 24:25 - Select RELOAD Register n to reload Timer on condition"] + #[inline(always)] + pub fn reload(&mut self) -> ReloadW { + ReloadW::new(self, 24) + } + #[doc = "Bits 26:27 - Selects, if Reload Register number is incremented, decremented or not modified"] + #[inline(always)] + pub fn idr(&mut self) -> IdrW { + IdrW::new(self, 26) + } + #[doc = "Bit 31 - Starts and Stops the Timer / Counter"] + #[inline(always)] + pub fn s(&mut self) -> SW { + SW::new(self, 31) + } +} +#[doc = "Control Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CrSpec; +impl crate::RegisterSpec for CrSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`cr::R`](R) reader structure"] +impl crate::Readable for CrSpec {} +#[doc = "`write(|w| ..)` method takes [`cr::W`](W) writer structure"] +impl crate::Writable for CrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CR to value 0"] +impl crate::Resettable for CrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/int.rs b/zynq7000/src/timer0/int.rs new file mode 100644 index 0000000..8310e3a --- /dev/null +++ b/zynq7000/src/timer0/int.rs @@ -0,0 +1,173 @@ +#[doc = "Register `INT` reader"] +pub type R = crate::R; +#[doc = "Register `INT` writer"] +pub type W = crate::W; +#[doc = "Interrupt Enable\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum En { + #[doc = "0: Timer does not generate Interrupts"] + Disabled = 0, + #[doc = "1: Timer triggers the TIMERn Interrupt"] + Enable = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: En) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `EN` reader - Interrupt Enable"] +pub type EnR = crate::BitReader; +impl EnR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> En { + match self.bits { + false => En::Disabled, + true => En::Enable, + } + } + #[doc = "Timer does not generate Interrupts"] + #[inline(always)] + pub fn is_disabled(&self) -> bool { + *self == En::Disabled + } + #[doc = "Timer triggers the TIMERn Interrupt"] + #[inline(always)] + pub fn is_enable(&self) -> bool { + *self == En::Enable + } +} +#[doc = "Field `EN` writer - Interrupt Enable"] +pub type EnW<'a, REG> = crate::BitWriter<'a, REG, En>; +impl<'a, REG> EnW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "Timer does not generate Interrupts"] + #[inline(always)] + pub fn disabled(self) -> &'a mut crate::W { + self.variant(En::Disabled) + } + #[doc = "Timer triggers the TIMERn Interrupt"] + #[inline(always)] + pub fn enable(self) -> &'a mut crate::W { + self.variant(En::Enable) + } +} +#[doc = "Interrupt Mode, selects on which condition the Timer should generate an Interrupt\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Mode { + #[doc = "0: Timer generates an Interrupt when the MATCH condition is hit"] + Match = 0, + #[doc = "1: Timer generates an Interrupt when it underflows"] + Underflow = 1, + #[doc = "2: Timer generates an Interrupt when it overflows"] + Overflow = 2, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Mode) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Mode { + type Ux = u8; +} +impl crate::IsEnum for Mode {} +#[doc = "Field `MODE` reader - Interrupt Mode, selects on which condition the Timer should generate an Interrupt"] +pub type ModeR = crate::FieldReader; +impl ModeR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Mode::Match), + 1 => Some(Mode::Underflow), + 2 => Some(Mode::Overflow), + _ => None, + } + } + #[doc = "Timer generates an Interrupt when the MATCH condition is hit"] + #[inline(always)] + pub fn is_match(&self) -> bool { + *self == Mode::Match + } + #[doc = "Timer generates an Interrupt when it underflows"] + #[inline(always)] + pub fn is_underflow(&self) -> bool { + *self == Mode::Underflow + } + #[doc = "Timer generates an Interrupt when it overflows"] + #[inline(always)] + pub fn is_overflow(&self) -> bool { + *self == Mode::Overflow + } +} +#[doc = "Field `MODE` writer - Interrupt Mode, selects on which condition the Timer should generate an Interrupt"] +pub type ModeW<'a, REG> = crate::FieldWriter<'a, REG, 3, Mode>; +impl<'a, REG> ModeW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Timer generates an Interrupt when the MATCH condition is hit"] + #[inline(always)] + pub fn match_(self) -> &'a mut crate::W { + self.variant(Mode::Match) + } + #[doc = "Timer generates an Interrupt when it underflows"] + #[inline(always)] + pub fn underflow(self) -> &'a mut crate::W { + self.variant(Mode::Underflow) + } + #[doc = "Timer generates an Interrupt when it overflows"] + #[inline(always)] + pub fn overflow(self) -> &'a mut crate::W { + self.variant(Mode::Overflow) + } +} +impl R { + #[doc = "Bit 0 - Interrupt Enable"] + #[inline(always)] + pub fn en(&self) -> EnR { + EnR::new((self.bits & 1) != 0) + } + #[doc = "Bits 4:6 - Interrupt Mode, selects on which condition the Timer should generate an Interrupt"] + #[inline(always)] + pub fn mode(&self) -> ModeR { + ModeR::new(((self.bits >> 4) & 7) as u8) + } +} +impl W { + #[doc = "Bit 0 - Interrupt Enable"] + #[inline(always)] + pub fn en(&mut self) -> EnW { + EnW::new(self, 0) + } + #[doc = "Bits 4:6 - Interrupt Mode, selects on which condition the Timer should generate an Interrupt"] + #[inline(always)] + pub fn mode(&mut self) -> ModeW { + ModeW::new(self, 4) + } +} +#[doc = "Interrupt Register\n\nYou can [`read`](crate::Reg::read) this register and get [`int::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`int::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IntSpec; +impl crate::RegisterSpec for IntSpec { + type Ux = u16; +} +#[doc = "`read()` method returns [`int::R`](R) reader structure"] +impl crate::Readable for IntSpec {} +#[doc = "`write(|w| ..)` method takes [`int::W`](W) writer structure"] +impl crate::Writable for IntSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u16 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u16 = 0; +} +#[doc = "`reset()` method sets INT to value 0"] +impl crate::Resettable for IntSpec { + const RESET_VALUE: u16 = 0; +} diff --git a/zynq7000/src/timer0/match_.rs b/zynq7000/src/timer0/match_.rs new file mode 100644 index 0000000..5229f94 --- /dev/null +++ b/zynq7000/src/timer0/match_.rs @@ -0,0 +1,28 @@ +#[doc = "Register `MATCH` reader"] +pub type R = crate::R; +#[doc = "Register `MATCH` writer"] +pub type W = crate::W; +#[cfg(feature = "debug")] +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "The Match Register stores the compare Value for the MATCH condition\n\nYou can [`read`](crate::Reg::read) this register and get [`match_::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`match_::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct MatchSpec; +impl crate::RegisterSpec for MatchSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`match_::R`](R) reader structure"] +impl crate::Readable for MatchSpec {} +#[doc = "`write(|w| ..)` method takes [`match_::W`](W) writer structure"] +impl crate::Writable for MatchSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets MATCH to value 0"] +impl crate::Resettable for MatchSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/prescale_rd.rs b/zynq7000/src/timer0/prescale_rd.rs new file mode 100644 index 0000000..ac52cf4 --- /dev/null +++ b/zynq7000/src/timer0/prescale_rd.rs @@ -0,0 +1,19 @@ +#[doc = "Register `PRESCALE_RD` reader"] +pub type R = crate::R; +#[cfg(feature = "debug")] +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value\n\nYou can [`read`](crate::Reg::read) this register and get [`prescale_rd::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PrescaleRdSpec; +impl crate::RegisterSpec for PrescaleRdSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`prescale_rd::R`](R) reader structure"] +impl crate::Readable for PrescaleRdSpec {} +#[doc = "`reset()` method sets PRESCALE_RD to value 0"] +impl crate::Resettable for PrescaleRdSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/prescale_wr.rs b/zynq7000/src/timer0/prescale_wr.rs new file mode 100644 index 0000000..1c284ff --- /dev/null +++ b/zynq7000/src/timer0/prescale_wr.rs @@ -0,0 +1,24 @@ +#[doc = "Register `PRESCALE_WR` writer"] +pub type W = crate::W; +#[cfg(feature = "debug")] +impl core::fmt::Debug for crate::generic::Reg { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "(not readable)") + } +} +impl W {} +#[doc = "The Prescale Register stores the Value for the prescaler. The cont event gets divided by this value\n\nYou can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`prescale_wr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PrescaleWrSpec; +impl crate::RegisterSpec for PrescaleWrSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`prescale_wr::W`](W) writer structure"] +impl crate::Writable for PrescaleWrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PRESCALE_WR to value 0"] +impl crate::Resettable for PrescaleWrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/reload.rs b/zynq7000/src/timer0/reload.rs new file mode 100644 index 0000000..7f35638 --- /dev/null +++ b/zynq7000/src/timer0/reload.rs @@ -0,0 +1,29 @@ +#[doc = "Register `RELOAD[%s]` reader"] +pub type R = crate::R; +#[doc = "Register `RELOAD[%s]` writer"] +pub type W = crate::W; +#[cfg(feature = "debug")] +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "The Reload Register stores the Value the COUNT Register gets reloaded on a when a condition was met.\n\nYou can [`read`](crate::Reg::read) this register and get [`reload::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`reload::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ReloadSpec; +impl crate::RegisterSpec for ReloadSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`reload::R`](R) reader structure"] +impl crate::Readable for ReloadSpec {} +#[doc = "`write(|w| ..)` method takes [`reload::W`](W) writer structure"] +impl crate::Writable for ReloadSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RELOAD[%s] +to value 0"] +impl crate::Resettable for ReloadSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/zynq7000/src/timer0/sr.rs b/zynq7000/src/timer0/sr.rs new file mode 100644 index 0000000..6c19ac6 --- /dev/null +++ b/zynq7000/src/timer0/sr.rs @@ -0,0 +1,365 @@ +#[doc = "Register `SR` reader"] +pub type R = crate::R; +#[doc = "Register `SR` writer"] +pub type W = crate::W; +#[doc = "Shows if Timer is running or not\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Run { + #[doc = "0: Timer is not running"] + Stopped = 0, + #[doc = "1: Timer is running"] + Running = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Run) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `RUN` reader - Shows if Timer is running or not"] +pub type RunR = crate::BitReader; +impl RunR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Run { + match self.bits { + false => Run::Stopped, + true => Run::Running, + } + } + #[doc = "Timer is not running"] + #[inline(always)] + pub fn is_stopped(&self) -> bool { + *self == Run::Stopped + } + #[doc = "Timer is running"] + #[inline(always)] + pub fn is_running(&self) -> bool { + *self == Run::Running + } +} +#[doc = "Shows if the MATCH was hit\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Match { + #[doc = "0: The MATCH condition was not hit"] + NoMatch = 0, + #[doc = "1: The MATCH condition was hit"] + MatchHit = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Match) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `MATCH` reader - Shows if the MATCH was hit"] +pub type MatchR = crate::BitReader; +impl MatchR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Match { + match self.bits { + false => Match::NoMatch, + true => Match::MatchHit, + } + } + #[doc = "The MATCH condition was not hit"] + #[inline(always)] + pub fn is_no_match(&self) -> bool { + *self == Match::NoMatch + } + #[doc = "The MATCH condition was hit"] + #[inline(always)] + pub fn is_match_hit(&self) -> bool { + *self == Match::MatchHit + } +} +#[doc = "Field `MATCH` writer - Shows if the MATCH was hit"] +pub type MatchW<'a, REG> = crate::BitWriter<'a, REG, Match>; +impl<'a, REG> MatchW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "The MATCH condition was not hit"] + #[inline(always)] + pub fn no_match(self) -> &'a mut crate::W { + self.variant(Match::NoMatch) + } + #[doc = "The MATCH condition was hit"] + #[inline(always)] + pub fn match_hit(self) -> &'a mut crate::W { + self.variant(Match::MatchHit) + } +} +#[doc = "Shows if an underflow occured. This flag is sticky\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Un { + #[doc = "0: No underflow occured since last clear"] + NoUnderflow = 0, + #[doc = "1: A minimum of one underflow occured since last clear"] + Underflow = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Un) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `UN` reader - Shows if an underflow occured. This flag is sticky"] +pub type UnR = crate::BitReader; +impl UnR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Un { + match self.bits { + false => Un::NoUnderflow, + true => Un::Underflow, + } + } + #[doc = "No underflow occured since last clear"] + #[inline(always)] + pub fn is_no_underflow(&self) -> bool { + *self == Un::NoUnderflow + } + #[doc = "A minimum of one underflow occured since last clear"] + #[inline(always)] + pub fn is_underflow(&self) -> bool { + *self == Un::Underflow + } +} +#[doc = "Field `UN` writer - Shows if an underflow occured. This flag is sticky"] +pub type UnW<'a, REG> = crate::BitWriter<'a, REG, Un>; +impl<'a, REG> UnW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "No underflow occured since last clear"] + #[inline(always)] + pub fn no_underflow(self) -> &'a mut crate::W { + self.variant(Un::NoUnderflow) + } + #[doc = "A minimum of one underflow occured since last clear"] + #[inline(always)] + pub fn underflow(self) -> &'a mut crate::W { + self.variant(Un::Underflow) + } +} +#[doc = "Shows if an overflow occured. This flag is sticky\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Ov { + #[doc = "0: No overflow occured since last clear"] + NoOverflow = 0, + #[doc = "1: A minimum of one overflow occured since last clear"] + OverflowOccured = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Ov) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `OV` reader - Shows if an overflow occured. This flag is sticky"] +pub type OvR = crate::BitReader; +impl OvR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Ov { + match self.bits { + false => Ov::NoOverflow, + true => Ov::OverflowOccured, + } + } + #[doc = "No overflow occured since last clear"] + #[inline(always)] + pub fn is_no_overflow(&self) -> bool { + *self == Ov::NoOverflow + } + #[doc = "A minimum of one overflow occured since last clear"] + #[inline(always)] + pub fn is_overflow_occured(&self) -> bool { + *self == Ov::OverflowOccured + } +} +#[doc = "Field `OV` writer - Shows if an overflow occured. This flag is sticky"] +pub type OvW<'a, REG> = crate::BitWriter<'a, REG, Ov>; +impl<'a, REG> OvW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, +{ + #[doc = "No overflow occured since last clear"] + #[inline(always)] + pub fn no_overflow(self) -> &'a mut crate::W { + self.variant(Ov::NoOverflow) + } + #[doc = "A minimum of one overflow occured since last clear"] + #[inline(always)] + pub fn overflow_occured(self) -> &'a mut crate::W { + self.variant(Ov::OverflowOccured) + } +} +#[doc = "Shows if Timer is in RESET state\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Rst { + #[doc = "0: Timer is not in RESET state and can operate"] + Ready = 0, + #[doc = "1: Timer is in RESET state and can not operate"] + InReset = 1, +} +impl From for bool { + #[inline(always)] + fn from(variant: Rst) -> Self { + variant as u8 != 0 + } +} +#[doc = "Field `RST` reader - Shows if Timer is in RESET state"] +pub type RstR = crate::BitReader; +impl RstR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Rst { + match self.bits { + false => Rst::Ready, + true => Rst::InReset, + } + } + #[doc = "Timer is not in RESET state and can operate"] + #[inline(always)] + pub fn is_ready(&self) -> bool { + *self == Rst::Ready + } + #[doc = "Timer is in RESET state and can not operate"] + #[inline(always)] + pub fn is_in_reset(&self) -> bool { + *self == Rst::InReset + } +} +#[doc = "Shows the currently active RELOAD Register\n\nValue on reset: 0"] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Reload { + #[doc = "0: Reload Register number 0 is active"] + Reload0 = 0, + #[doc = "1: Reload Register number 1 is active"] + Reload1 = 1, + #[doc = "2: Reload Register number 2 is active"] + Reload2 = 2, + #[doc = "3: Reload Register number 3 is active"] + Reload3 = 3, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Reload) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Reload { + type Ux = u8; +} +impl crate::IsEnum for Reload {} +#[doc = "Field `RELOAD` reader - Shows the currently active RELOAD Register"] +pub type ReloadR = crate::FieldReader; +impl ReloadR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Reload { + match self.bits { + 0 => Reload::Reload0, + 1 => Reload::Reload1, + 2 => Reload::Reload2, + 3 => Reload::Reload3, + _ => unreachable!(), + } + } + #[doc = "Reload Register number 0 is active"] + #[inline(always)] + pub fn is_reload0(&self) -> bool { + *self == Reload::Reload0 + } + #[doc = "Reload Register number 1 is active"] + #[inline(always)] + pub fn is_reload1(&self) -> bool { + *self == Reload::Reload1 + } + #[doc = "Reload Register number 2 is active"] + #[inline(always)] + pub fn is_reload2(&self) -> bool { + *self == Reload::Reload2 + } + #[doc = "Reload Register number 3 is active"] + #[inline(always)] + pub fn is_reload3(&self) -> bool { + *self == Reload::Reload3 + } +} +impl R { + #[doc = "Bit 0 - Shows if Timer is running or not"] + #[inline(always)] + pub fn run(&self) -> RunR { + RunR::new((self.bits & 1) != 0) + } + #[doc = "Bit 8 - Shows if the MATCH was hit"] + #[inline(always)] + pub fn match_(&self) -> MatchR { + MatchR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Shows if an underflow occured. This flag is sticky"] + #[inline(always)] + pub fn un(&self) -> UnR { + UnR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - Shows if an overflow occured. This flag is sticky"] + #[inline(always)] + pub fn ov(&self) -> OvR { + OvR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 12 - Shows if Timer is in RESET state"] + #[inline(always)] + pub fn rst(&self) -> RstR { + RstR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bits 14:15 - Shows the currently active RELOAD Register"] + #[inline(always)] + pub fn reload(&self) -> ReloadR { + ReloadR::new(((self.bits >> 14) & 3) as u8) + } +} +impl W { + #[doc = "Bit 8 - Shows if the MATCH was hit"] + #[inline(always)] + pub fn match_(&mut self) -> MatchW { + MatchW::new(self, 8) + } + #[doc = "Bit 9 - Shows if an underflow occured. This flag is sticky"] + #[inline(always)] + pub fn un(&mut self) -> UnW { + UnW::new(self, 9) + } + #[doc = "Bit 10 - Shows if an overflow occured. This flag is sticky"] + #[inline(always)] + pub fn ov(&mut self) -> OvW { + OvW::new(self, 10) + } +} +#[doc = "Status Register\n\nYou can [`read`](crate::Reg::read) this register and get [`sr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`sr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SrSpec; +impl crate::RegisterSpec for SrSpec { + type Ux = u16; +} +#[doc = "`read()` method returns [`sr::R`](R) reader structure"] +impl crate::Readable for SrSpec {} +#[doc = "`write(|w| ..)` method takes [`sr::W`](W) writer structure"] +impl crate::Writable for SrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u16 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u16 = 0; +} +#[doc = "`reset()` method sets SR to value 0"] +impl crate::Resettable for SrSpec { + const RESET_VALUE: u16 = 0; +}