diff --git a/.cargo/.gitignore b/.cargo/.gitignore new file mode 100644 index 0000000..5b6c096 --- /dev/null +++ b/.cargo/.gitignore @@ -0,0 +1 @@ +config.toml diff --git a/.cargo/def-config.toml b/.cargo/def-config.toml new file mode 100644 index 0000000..1887082 --- /dev/null +++ b/.cargo/def-config.toml @@ -0,0 +1,48 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x openocd.gdb" +# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "gdb -q -x openocd.gdb" +runner = "gdb-multiarch -q -x jlink.gdb" + +# Probe-rs is currently problematic: https://github.com/probe-rs/probe-rs/issues/2567 +# runner = "probe-rs run --chip VA108xx --chip-description-path ./scripts/VA108xx_Series.yaml" +# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"] + +rustflags = [ + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", "link-arg=--nmagic", + + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # knurling-rs tooling. If you want to use flip-link, ensure it is installed first. + # "-C", "linker=flip-link", + # Unfortunately, defmt is clunky to use without probe-rs.. + # "-C", "link-arg=-Tdefmt.x", + + # Can be useful for debugging. + "-Clink-args=-Map=app.map" + +] + +[build] +# Pick ONE of these compilation targets +target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) +# target = "thumbv8m.base-none-eabi" # Cortex-M23 +# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) +# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) + +[alias] +re = "run --example" +rb = "run --bin" +rrb = "run --release --bin" +ut = "test --target x86_64-unknown-linux-gnu" + +[env] +DEFMT_LOG = "info" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7203ede --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: ci +on: [push, pull_request] + +jobs: + check: + name: Check build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: "thumbv6m-none-eabi" + - run: cargo check --release + - run: cargo check --examples --release + + test: + name: Run Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install nextest + uses: taiki-e/install-action@nextest + - run: cargo nextest run --all-features + - run: cargo test --doc + + fmt: + name: Check formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - run: cargo fmt --all -- --check + + docs: + name: Check Documentation Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo +nightly doc --all-features --config 'build.rustdocflags=["--cfg", "docs_rs"]' + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - run: cargo clippy -- -D warnings diff --git a/.gitignore b/.gitignore index 3111a47..2cdfcc7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,12 @@ # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock +/app.map + # These are backup files generated by rustfmt **/*.rs.bk -/.vscode/.cortex-debug.* -/.vscode/settings.json +/.vscode # JetBrains IDEs /.idea diff --git a/.gitmodules b/.gitmodules index dbdd30f..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +0,0 @@ -[submodule "va108xx-rs"] - path = va108xx - url = https://egit.irs.uni-stuttgart.de/rust/va108xx -[submodule "vorago-reb1-rs"] - path = vorago-reb1 - url = https://egit.irs.uni-stuttgart.de/rust/vorago-reb1 -[submodule "va108xx-hal-rs"] - path = va108xx-hal - url = https://egit.irs.uni-stuttgart.de/rust/va108xx-hal.git -[submodule "adt75-rs"] - path = adt75-rs - url = https://egit.irs.uni-stuttgart.de/rust/adt75-rs.git -[submodule "max116xx-10bit"] - path = max116xx-10bit - url = https://egit.irs.uni-stuttgart.de/rust/max116xx-10bit.git diff --git a/Cargo.toml b/Cargo.toml index ae8dbd0..c8fd396 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,31 @@ [workspace] - +resolver = "2" members = [ "vorago-reb1", "va108xx", "va108xx-hal", - "max116xx-10bit", + "examples/simple", + "board-tests", +] + +exclude = [ + "defmt-testapp", ] [profile.dev] -lto = false -debug = true +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +opt-level = 'z' # <- +overflow-checks = true # <- +# cargo build/run --release [profile.release] -# Can be problematic for debugging and is definitely problematic with RTT -lto = false -debug = true -opt-level = 's' - -[profile.release-lto] -inherits = "release" -lto = true +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = 3 # <- +overflow-checks = false # <- diff --git a/README.md b/README.md index fe9e44f..a5495b3 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,102 @@ -Vorago Rust Workspace -======== +Vorago VA108xx Rust Support +========= -Workspace for developing Rust code for the Vorago devices +This crate collection provided support to write Rust applications for the VA108XX family +of devices. -After cloning, run +## List of crates + +This workspace contains the following released crates: + +- The [`va108xx`](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/va108xx) PAC + crate containing basic low-level register definition. +- The [`va108xx-hal`](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/va108xx-hal) + HAL crate containing higher-level abstractions on top of the PAC register crate. +- The [`vorago-reb1`](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1) + BSP crate containing support for the REB1 development board. + +It also contains the following helper crates: + +- The `board-tests` contains an application which can be used to test the libraries on the + board. +- The `examples` crates contains various example applications for the HAL and the PAC. + +## Using the `.cargo/config.toml` file + +Use the following command to have a starting `config.toml` file ```sh -git submodule update --init +cp .cargo/def-config.toml .cargo/config.toml ``` -# Preparing the Rust installation +You then can adapt the `config.toml` to your needs. For example, you can configure runners +to conveniently flash with `cargo run`. +## Using the sample VS Code files -Building an application for the VA108XX family requires the `thumbv6m-none-eabi` -cross-compiler toolchain. If you have not installed it yet, you can do so with +Use the following command to have a starting configuration for VS Code: ```sh -rustup target add thumbv6m-none-eabi +cp -rT vscode .vscode ``` -# Debugging with VS Code +You can then adapt the files in `.vscode` to your needs. -The REB1 board features an on-board JTAG, so all that is required to flash the board is a -Micro-USB cable and an -You can debug applications on the REB1 board with a graphical user interface using VS Code with +## Flashing, running and debugging the software + +You can use CLI or VS Code for flashing, running and debugging. In any case, take +care of installing the pre-requisites first. + +### Pre-Requisites + +1. [SEGGER J-Link tools](https://www.segger.com/downloads/jlink/) installed +2. [gdb-multiarch](https://packages.debian.org/sid/gdb-multiarch) or similar + cross-architecture debugger installed. All commands here assume `gdb-multiarch`. + +### Using CLI + +You can build the blinky example application with the following command + +```sh +cargo build --example blinky +``` + +Start the GDB server first. The server needs to be started with a certain configuration and with +a JLink script to disable ROM protection. +For example, on Debian based system the following command can be used to do this (this command +is also run when running the `jlink-gdb.sh` script) + +```sh +JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG-speed auto \ + -LocalhostOnly +``` + +After this, you can flash and debug the application with the following command + +```sh +gdb-mutliarch -q -x jlink/jlink.gdb target/thumbv6m-none-eabihf/debug/examples/blinky +``` + +Please note that you can automate all steps except starting the GDB server by using a cargo +runner configuration, for example with the following lines in your `.cargo/config.toml` file: + +```toml +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "gdb-multiarch -q -x jlink/jlink.gdb" +``` + +After that, you can simply use `cargo run --example blinky` to flash the blinky +example. + +### Using VS Code + +Assuming a working debug connection to your VA108xx board, you can debug using VS Code with the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug). -Some sample configuration files for VS code were provided as well. You can simply use `Run and Debug` +Some sample configuration files for VS code were provided and can be used by running +`cp -rT vscode .vscode` like specified above. After that, you can use `Run and Debug` to automatically rebuild and flash your application. -The `tasks.json` and the `launch.json` files are generic and you can use them immediately by -opening the folder in VS code or adding it to a workspace. - If you would like to use a custom GDB application, you can specify the gdb binary in the following configuration variables in your `settings.json`: diff --git a/adt75-rs b/adt75-rs deleted file mode 160000 index 8b7121e..0000000 --- a/adt75-rs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8b7121eb4771c2537c6123f632d20fbfb2ba3657 diff --git a/automation/Dockerfile b/automation/Dockerfile new file mode 100644 index 0000000..b789384 --- /dev/null +++ b/automation/Dockerfile @@ -0,0 +1,13 @@ +# Run the following commands from root directory to build and run locally +# docker build -f automation/Dockerfile -t . +# docker run -it +FROM rust:latest +RUN apt-get update +RUN apt-get --yes upgrade +# tzdata is a dependency, won't install otherwise +ARG DEBIAN_FRONTEND=noninteractive + +RUN rustup install nightly && \ + rustup target add thumbv6m-none-eabi && \ + rustup +nightly target add thumbv6m-none-eabi && \ + rustup component add rustfmt clippy diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile new file mode 100644 index 0000000..3698cca --- /dev/null +++ b/automation/Jenkinsfile @@ -0,0 +1,41 @@ +pipeline { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + + stages { + stage('Rust Toolchain Info') { + steps { + sh 'rustc --version' + } + } + stage('Clippy') { + steps { + sh 'cargo clippy' + } + } + stage('Rustfmt') { + steps { + sh 'cargo fmt' + } + } + stage('Docs') { + steps { + sh: cargo +nightly doc --all-features --config 'build.rustdocflags=["--cfg", "docs_rs"]' + } + } + stage('Check') { + steps { + sh 'cargo check --target thumbv6m-none-eabi' + } + } + stage('Check Examples') { + steps { + sh 'cargo check --target thumbv6m-none-eabi --examples' + } + } + } +} diff --git a/board-tests/Cargo.toml b/board-tests/Cargo.toml new file mode 100644 index 0000000..39c6af6 --- /dev/null +++ b/board-tests/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "board-tests" +version = "0.1.0" +edition = "2021" + +[dependencies] +cortex-m-rtic = "1" +panic-halt = "0.2" +cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7" +rtt-target = "0.5" +panic-rtt-target = "0.1.3" +embedded-hal = "1" +embedded-hal-nb = "1" +embedded-io = "0.6" + +[dependencies.va108xx-hal] +version = "0.6" +path = "../va108xx-hal" +features = ["rt"] diff --git a/board-tests/src/main.rs b/board-tests/src/main.rs new file mode 100644 index 0000000..9ae3b9e --- /dev/null +++ b/board-tests/src/main.rs @@ -0,0 +1,207 @@ +//! Test image +//! +//! It would be nice to use a test framework like defmt-test, but I have issues +//! with probe run and it would be better to make the RTT work first +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::{ + delay::DelayNs, + digital::{InputPin, OutputPin, StatefulOutputPin}, +}; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + gpio::{PinState, PinsA, PinsB}, + pac::{self, interrupt}, + prelude::*, + time::Hertz, + timer::{default_ms_irq_handler, set_up_ms_tick, CountDownTimer, IrqCfg}, +}; + +#[allow(dead_code)] +#[derive(Debug)] +enum TestCase { + // Tie PORTA[0] to PORTA[1] for these tests! + TestBasic, + TestPullup, + TestPulldown, + TestMask, + // Tie PORTB[22] to PORTB[23] for this test + PortB, + Perid, + // Tie PA0 to an oscilloscope and configure pulse detection + Pulse, + // Tie PA0, PA1 and PA3 to an oscilloscope + DelayGpio, + DelayMs, +} + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- VA108xx Test Application --"); + let mut dp = pac::Peripherals::take().unwrap(); + let cp = cortex_m::Peripherals::take().unwrap(); + let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); + let pinsb = PinsB::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.portb); + let mut led1 = pinsa.pa10.into_readable_push_pull_output(); + let test_case = TestCase::DelayMs; + + match test_case { + TestCase::TestBasic + | TestCase::TestPulldown + | TestCase::TestPullup + | TestCase::TestMask => { + rprintln!( + "Test case {:?}. Make sure to tie PORTA[0] to PORTA[1]", + test_case + ); + } + _ => { + rprintln!("Test case {:?}", test_case); + } + } + match test_case { + TestCase::TestBasic => { + // Tie PORTA[0] to PORTA[1] for these tests! + let mut out = pinsa.pa0.into_readable_push_pull_output(); + let mut input = pinsa.pa1.into_floating_input(); + out.set_high().unwrap(); + assert!(input.is_high().unwrap()); + out.set_low().unwrap(); + assert!(input.is_low().unwrap()); + } + TestCase::TestPullup => { + // Tie PORTA[0] to PORTA[1] for these tests! + let mut input = pinsa.pa1.into_pull_up_input(); + assert!(input.is_high().unwrap()); + let mut out = pinsa.pa0.into_readable_push_pull_output(); + out.set_low().unwrap(); + assert!(input.is_low().unwrap()); + out.set_high().unwrap(); + assert!(input.is_high().unwrap()); + out.into_floating_input(); + assert!(input.is_high().unwrap()); + } + TestCase::TestPulldown => { + // Tie PORTA[0] to PORTA[1] for these tests! + let mut input = pinsa.pa1.into_pull_down_input(); + assert!(input.is_low().unwrap()); + let mut out = pinsa.pa0.into_push_pull_output(); + out.set_low().unwrap(); + assert!(input.is_low().unwrap()); + out.set_high().unwrap(); + assert!(input.is_high().unwrap()); + out.into_floating_input(); + assert!(input.is_low().unwrap()); + } + TestCase::TestMask => { + // Tie PORTA[0] to PORTA[1] for these tests! + let input = pinsa.pa1.into_pull_down_input().clear_datamask(); + assert!(!input.datamask()); + let mut out = pinsa.pa0.into_push_pull_output().clear_datamask(); + assert!(input.is_low_masked().is_err()); + assert!(out.set_high_masked().is_err()); + } + TestCase::PortB => { + // Tie PORTB[22] to PORTB[23] for these tests! + let mut out = pinsb.pb22.into_readable_push_pull_output(); + let mut input = pinsb.pb23.into_floating_input(); + out.set_high().unwrap(); + assert!(input.is_high().unwrap()); + out.set_low().unwrap(); + assert!(input.is_low().unwrap()); + } + TestCase::Perid => { + assert_eq!(PinsA::get_perid(), 0x004007e1); + assert_eq!(PinsB::get_perid(), 0x004007e1); + } + TestCase::Pulse => { + let mut output_pulsed = pinsa + .pa0 + .into_push_pull_output() + .pulse_mode(true, PinState::Low); + rprintln!("Pulsing high 10 times.."); + output_pulsed.set_low().unwrap(); + for _ in 0..10 { + output_pulsed.set_high().unwrap(); + cortex_m::asm::delay(25_000_000); + } + let mut output_pulsed = output_pulsed.pulse_mode(true, PinState::High); + rprintln!("Pulsing low 10 times.."); + for _ in 0..10 { + output_pulsed.set_low().unwrap(); + cortex_m::asm::delay(25_000_000); + } + } + TestCase::DelayGpio => { + let mut out_0 = pinsa + .pa0 + .into_readable_push_pull_output() + .delay(true, false); + let mut out_1 = pinsa + .pa1 + .into_readable_push_pull_output() + .delay(false, true); + let mut out_2 = pinsa.pa3.into_readable_push_pull_output().delay(true, true); + for _ in 0..20 { + out_0.toggle().unwrap(); + out_1.toggle().unwrap(); + out_2.toggle().unwrap(); + cortex_m::asm::delay(25_000_000); + } + } + TestCase::DelayMs => { + let mut ms_timer = set_up_ms_tick( + IrqCfg::new(pac::Interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + for _ in 0..5 { + led1.toggle().ok(); + ms_timer.delay_ms(500); + led1.toggle().ok(); + ms_timer.delay_ms(500); + } + + let mut delay_timer = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1); + let mut pa0 = pinsa.pa0.into_readable_push_pull_output(); + for _ in 0..5 { + led1.toggle().ok(); + delay_timer.delay_ms(500); + led1.toggle().ok(); + delay_timer.delay_ms(500); + } + let ahb_freq: Hertz = 50.MHz(); + let mut syst_delay = cortex_m::delay::Delay::new(cp.SYST, ahb_freq.raw()); + // Test usecond delay using both TIM peripheral and SYST. Use the release image if you + // want to verify the timings! + loop { + pa0.toggle().ok(); + delay_timer.delay_us(50); + pa0.toggle().ok(); + delay_timer.delay_us(50); + pa0.toggle_with_toggle_reg(); + syst_delay.delay_us(50); + pa0.toggle_with_toggle_reg(); + syst_delay.delay_us(50); + } + } + } + + rprintln!("Test success"); + loop { + led1.toggle().ok(); + cortex_m::asm::delay(25_000_000); + } +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC0() { + default_ms_irq_handler() +} diff --git a/defmt-testapp/.cargo/config.toml b/defmt-testapp/.cargo/config.toml new file mode 100644 index 0000000..68458a8 --- /dev/null +++ b/defmt-testapp/.cargo/config.toml @@ -0,0 +1,48 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x openocd.gdb" +# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "gdb -q -x openocd.gdb" +runner = "gdb-multiarch -q -x jlink.gdb" + +# Probe-rs is currently problematic: https://github.com/probe-rs/probe-rs/issues/2567 +# runner = "probe-rs run --chip VA108xx --chip-description-path ./scripts/VA108xx_Series.yaml" +# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"] + +rustflags = [ + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", "link-arg=--nmagic", + + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # knurling-rs tooling. If you want to use flip-link, ensure it is installed first. + "-C", "linker=flip-link", + # Unfortunately, defmt is clunky to use without probe-rs.. + "-C", "link-arg=-Tdefmt.x", + + # Can be useful for debugging. + "-Clink-args=-Map=app.map" + +] + +[build] +# Pick ONE of these compilation targets +target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) +# target = "thumbv8m.base-none-eabi" # Cortex-M23 +# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) +# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) + +[alias] +re = "run --example" +rb = "run --bin" +rrb = "run --release --bin" +ut = "test --target x86_64-unknown-linux-gnu" + +[env] +DEFMT_LOG = "info" diff --git a/defmt-testapp/.gitignore b/defmt-testapp/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/defmt-testapp/.gitignore @@ -0,0 +1 @@ +/target diff --git a/defmt-testapp/Cargo.toml b/defmt-testapp/Cargo.toml new file mode 100644 index 0000000..9a40f72 --- /dev/null +++ b/defmt-testapp/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "defmt-testapp" +version = "0.1.0" +edition = "2021" + +[dependencies] +cortex-m = {version = "0.7", features = ["critical-section-single-core"]} +panic-rtt-target = "0.1" +cortex-m-rt = "0.7" +rtt-target = "0.5" +rtic-sync = { version = "1.3", features = ["defmt-03"] } +embedded-hal = "1" +embedded-hal-nb = "1" +embedded-io = "0.6" +cortex-m-semihosting = "0.5.0" +# Tricky without probe-rs. +defmt = "0.3" +defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] } +panic-probe = { version = "0.3", features = ["print-defmt"] } + +[dependencies.rtic] +version = "2" +features = ["thumbv6-backend"] + +[dependencies.rtic-monotonics] +version = "1" +features = ["cortex-m-systick"] + +[dependencies.va108xx-hal] +version = "0.6" +path = "../va108xx-hal" +features = ["rt", "defmt"] + +[dependencies.va108xx] +version = "0.3" +path = "../va108xx" diff --git a/defmt-testapp/README.md b/defmt-testapp/README.md new file mode 100644 index 0000000..7514cbe --- /dev/null +++ b/defmt-testapp/README.md @@ -0,0 +1,9 @@ +defmt Testapp +====== + +`defmt` is clunky to use without probe-rs and requires special configuration inside the +`.cargo/config.toml` file. + +`probe-rs` is currently problematic for usage with the VA108xx , so it is not the default tool +recommended and used for the whole workspace. This project contains an isolated, `defmt` compatible +configuration for testing with `defmt` (and `probe-rs`). diff --git a/defmt-testapp/src/lib.rs b/defmt-testapp/src/lib.rs new file mode 100644 index 0000000..7466d3f --- /dev/null +++ b/defmt-testapp/src/lib.rs @@ -0,0 +1,53 @@ +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; + +use defmt_brtt as _; // global logger + +use va108xx_hal as _; // memory layout + +use panic_probe as _; + +// same panicking *behavior* as `panic-probe` but doesn't print a panic message +// this prevents the panic message being printed *twice* when `defmt::panic` is invoked +// #[defmt::panic_handler] +/* +fn panic() -> ! { + cortex_m::asm::udf() +} +*/ + +/// Terminates the application and makes a semihosting-capable debug tool exit +/// with status code 0. +pub fn exit() -> ! { + loop { + debug::exit(debug::EXIT_SUCCESS); + } +} + +/// Hardfault handler. +/// +/// Terminates the application and makes a semihosting-capable debug tool exit +/// with an error. This seems better than the default, which is to spin in a +/// loop. +#[cortex_m_rt::exception] +unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! { + loop { + debug::exit(debug::EXIT_FAILURE); + } +} + +// defmt-test 0.3.0 has the limitation that this `#[tests]` attribute can only be used +// once within a crate. the module can be in any file but there can only be at most +// one `#[tests]` module in this library crate +#[cfg(test)] +#[defmt_test::tests] +mod unit_tests { + use defmt::assert; + + #[test] + fn it_works() { + assert!(true) + } +} diff --git a/defmt-testapp/src/main.rs b/defmt-testapp/src/main.rs new file mode 100644 index 0000000..c0fa5e5 --- /dev/null +++ b/defmt-testapp/src/main.rs @@ -0,0 +1,29 @@ +//! Empty RTIC project template +#![no_main] +#![no_std] + +use defmt_testapp as _; + +#[rtic::app(device = pac)] +mod app { + use va108xx_hal::pac; + + #[local] + struct Local {} + + #[shared] + struct Shared {} + + #[init] + fn init(_ctx: init::Context) -> (Shared, Local) { + defmt::println!("-- Vorago RTIC template --"); + (Shared {}, Local {}) + } + + // `shared` cannot be accessed from this context + #[idle] + fn idle(_cx: idle::Context) -> ! { + #[allow(clippy::empty_loop)] + loop {} + } +} diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml new file mode 100644 index 0000000..391dab6 --- /dev/null +++ b/examples/simple/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "simple-examples" +version = "0.1.0" +edition = "2021" + +[dependencies] +panic-halt = "0.2" +cortex-m = {version = "0.7", features = ["critical-section-single-core"]} +panic-rtt-target = "0.1" +cortex-m-rt = "0.7" +rtt-target = "0.5" +rtic-sync = { version = "1.3", features = ["defmt-03"] } +embedded-hal = "1" +embedded-hal-nb = "1" +embedded-io = "0.6" +cortex-m-semihosting = "0.5.0" +# I'd really like to use those, but it is tricky without probe-rs.. +# defmt = "0.3" +# defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] } +# panic-probe = { version = "0.3", features = ["print-defmt"] } + +[dependencies.rtic] +version = "2" +features = ["thumbv6-backend"] + +[dependencies.rtic-monotonics] +version = "1" +features = ["cortex-m-systick"] + +[dependencies.va108xx-hal] +version = "0.6" +path = "../../va108xx-hal" +features = ["rt", "defmt"] + +[dependencies.va108xx] +version = "0.3" +path = "../../va108xx" diff --git a/examples/simple/examples/blinky-pac.rs b/examples/simple/examples/blinky-pac.rs new file mode 100644 index 0000000..01aebad --- /dev/null +++ b/examples/simple/examples/blinky-pac.rs @@ -0,0 +1,47 @@ +//! Blinky examples using only the PAC +//! +//! Additional note on LEDs: +//! Pulling the GPIOs low makes the LEDs blink. See REB1 +//! schematic for more details. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use panic_halt as _; +use va108xx as pac; + +// REB LED pin definitions. All on port A +const LED_D2: u32 = 1 << 10; +const LED_D3: u32 = 1 << 7; +const LED_D4: u32 = 1 << 6; + +#[entry] +fn main() -> ! { + let dp = pac::Peripherals::take().unwrap(); + // Enable all peripheral clocks + dp.sysconfig + .peripheral_clk_enable() + .modify(|_, w| unsafe { w.bits(0xffffffff) }); + dp.porta + .dir() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + dp.porta + .datamask() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + for _ in 0..10 { + dp.porta + .clrout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + dp.porta + .setout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + } + loop { + dp.porta + .togout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(25_000_000); + } +} diff --git a/examples/simple/examples/blinky.rs b/examples/simple/examples/blinky.rs new file mode 100644 index 0000000..59615c0 --- /dev/null +++ b/examples/simple/examples/blinky.rs @@ -0,0 +1,64 @@ +//! Simple blinky example +//! +//! Additional note on LEDs when using the REB1 development board: +//! Be not afraid: Pulling the GPIOs low makes the LEDs blink. See REB1 +//! schematic for more details. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::{ + delay::DelayNs, + digital::{OutputPin, StatefulOutputPin}, +}; +use panic_halt as _; +use va108xx_hal::{ + gpio::PinsA, + pac::{self, interrupt}, + prelude::*, + pwm::{default_ms_irq_handler, set_up_ms_tick, CountDownTimer}, + timer::DelayMs, + IrqCfg, +}; + +#[entry] +fn main() -> ! { + let mut dp = pac::Peripherals::take().unwrap(); + let mut delay_ms = DelayMs::new(set_up_ms_tick( + IrqCfg::new(interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + )) + .unwrap(); + let mut delay_tim1 = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1); + let porta = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let mut led1 = porta.pa10.into_readable_push_pull_output(); + let mut led2 = porta.pa7.into_readable_push_pull_output(); + let mut led3 = porta.pa6.into_readable_push_pull_output(); + for _ in 0..10 { + led1.set_low().ok(); + led2.set_low().ok(); + led3.set_low().ok(); + delay_ms.delay_ms(200); + led1.set_high().ok(); + led2.set_high().ok(); + led3.set_high().ok(); + delay_tim1.delay_ms(200); + } + loop { + led1.toggle().ok(); + delay_ms.delay_ms(200); + led2.toggle().ok(); + delay_tim1.delay_ms(200); + led3.toggle().ok(); + delay_ms.delay_ms(200); + } +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC0() { + default_ms_irq_handler() +} diff --git a/examples/simple/examples/cascade.rs b/examples/simple/examples/cascade.rs new file mode 100644 index 0000000..b49fce6 --- /dev/null +++ b/examples/simple/examples/cascade.rs @@ -0,0 +1,142 @@ +//! Simple Cascade example +//! +//! A timer will be periodically started which starts another timer via the cascade feature. +//! This timer will then start another timer with the cascade feature as well. +#![no_main] +#![no_std] +#![allow(non_snake_case)] + +use core::cell::RefCell; +use cortex_m::interrupt::Mutex; +use cortex_m_rt::entry; +use embedded_hal::delay::DelayNs; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + pac::{self, interrupt}, + prelude::*, + timer::{ + default_ms_irq_handler, set_up_ms_delay_provider, CascadeCtrl, CascadeSource, + CountDownTimer, Event, IrqCfg, + }, +}; + +static CSD_TGT_1: Mutex>>> = + Mutex::new(RefCell::new(None)); +static CSD_TGT_2: Mutex>>> = + Mutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- VA108xx Cascade example application--"); + + let mut dp = pac::Peripherals::take().unwrap(); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + + // Will be started periodically to trigger a cascade + let mut cascade_triggerer = + CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim3).auto_disable(true); + cascade_triggerer.listen( + Event::TimeOut, + IrqCfg::new(va108xx::Interrupt::OC1, true, false), + Some(&mut dp.irqsel), + Some(&mut dp.sysconfig), + ); + + // First target for cascade + let mut cascade_target_1 = + CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim4).auto_deactivate(true); + cascade_target_1 + .cascade_0_source(CascadeSource::TimBase, Some(3)) + .expect("Configuring cascade source for TIM4 failed"); + let mut csd_cfg = CascadeCtrl { + enb_start_src_csd0: true, + ..Default::default() + }; + // Use trigger mode here + csd_cfg.trg_csd0 = true; + cascade_target_1.cascade_control(csd_cfg); + // Normally it should already be sufficient to activate IRQ in the CTRL + // register but a full interrupt is use here to display print output when + // the timer expires + cascade_target_1.listen( + Event::TimeOut, + IrqCfg::new(va108xx::Interrupt::OC2, true, false), + Some(&mut dp.irqsel), + Some(&mut dp.sysconfig), + ); + // The counter will only activate when the cascade signal is coming in so + // it is okay to call start here to set the reset value + cascade_target_1.start(1.Hz()); + + // Activated by first cascade target + let mut cascade_target_2 = + CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim5).auto_deactivate(true); + // Set TIM4 as cascade source + cascade_target_2 + .cascade_1_source(CascadeSource::TimBase, Some(4)) + .expect("Configuring cascade source for TIM5 failed"); + + csd_cfg = CascadeCtrl::default(); + csd_cfg.enb_start_src_csd1 = true; + // Use trigger mode here + csd_cfg.trg_csd1 = true; + cascade_target_2.cascade_control(csd_cfg); + // Normally it should already be sufficient to activate IRQ in the CTRL + // register but a full interrupt is use here to display print output when + // the timer expires + cascade_target_2.listen( + Event::TimeOut, + IrqCfg::new(va108xx::Interrupt::OC3, true, false), + Some(&mut dp.irqsel), + Some(&mut dp.sysconfig), + ); + // The counter will only activate when the cascade signal is coming in so + // it is okay to call start here to set the reset value + cascade_target_2.start(1.Hz()); + + // Unpend all IRQs + unsafe { + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC1); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC2); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC3); + } + // Make both cascade targets accessible from the IRQ handler with the Mutex dance + cortex_m::interrupt::free(|cs| { + CSD_TGT_1.borrow(cs).replace(Some(cascade_target_1)); + CSD_TGT_2.borrow(cs).replace(Some(cascade_target_2)); + }); + loop { + rprintln!("-- Triggering cascade in 0.5 seconds --"); + cascade_triggerer.start(2.Hz()); + delay.delay_ms(5000); + } +} + +#[interrupt] +fn OC0() { + default_ms_irq_handler() +} + +#[interrupt] +fn OC1() { + static mut IDX: u32 = 0; + rprintln!("{}: Cascade triggered timed out", &IDX); + *IDX += 1; +} + +#[interrupt] +fn OC2() { + static mut IDX: u32 = 0; + rprintln!("{}: First cascade target timed out", &IDX); + *IDX += 1; +} + +#[interrupt] +fn OC3() { + static mut IDX: u32 = 0; + rprintln!("{}: Second cascade target timed out", &IDX); + *IDX += 1; +} diff --git a/examples/simple/examples/pwm.rs b/examples/simple/examples/pwm.rs new file mode 100644 index 0000000..db3fe1c --- /dev/null +++ b/examples/simple/examples/pwm.rs @@ -0,0 +1,72 @@ +//! Simple PWM example +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::{delay::DelayNs, pwm::SetDutyCycle}; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + gpio::PinsA, + pac, + prelude::*, + pwm::{self, get_duty_from_percent, PwmA, PwmB, ReducedPwmPin}, + timer::set_up_ms_delay_provider, +}; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- VA108xx PWM example application--"); + let mut dp = pac::Peripherals::take().unwrap(); + let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); + let mut pwm = pwm::PwmPin::new( + (pinsa.pa3.into_funsel_1(), dp.tim3), + 50.MHz(), + &mut dp.sysconfig, + 10.Hz(), + ); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + let mut current_duty_cycle = 0.0; + pwm.set_duty_cycle(get_duty_from_percent(current_duty_cycle)) + .unwrap(); + pwm.enable(); + + // Delete type information, increased code readibility for the rest of the code + let mut reduced_pin = ReducedPwmPin::from(pwm); + loop { + let mut counter = 0; + // Increase duty cycle continuously + while current_duty_cycle < 1.0 { + delay.delay_ms(400); + current_duty_cycle += 0.02; + counter += 1; + if counter % 10 == 0 { + rprintln!("current duty cycle: {}", current_duty_cycle); + } + + reduced_pin + .set_duty_cycle(get_duty_from_percent(current_duty_cycle)) + .unwrap(); + } + + // Switch to PWMB and decrease the window with a high signal from 100 % to 0 % + // continously + current_duty_cycle = 0.0; + let mut upper_limit = 1.0; + let mut lower_limit = 0.0; + let mut pwmb: ReducedPwmPin = ReducedPwmPin::from(reduced_pin); + pwmb.set_pwmb_lower_limit(get_duty_from_percent(lower_limit)); + pwmb.set_pwmb_upper_limit(get_duty_from_percent(upper_limit)); + while lower_limit < 0.5 { + delay.delay_ms(400); + lower_limit += 0.01; + upper_limit -= 0.01; + pwmb.set_pwmb_lower_limit(get_duty_from_percent(lower_limit)); + pwmb.set_pwmb_upper_limit(get_duty_from_percent(upper_limit)); + rprintln!("Lower limit: {}", pwmb.pwmb_lower_limit()); + rprintln!("Upper limit: {}", pwmb.pwmb_upper_limit()); + } + reduced_pin = ReducedPwmPin::::from(pwmb); + } +} diff --git a/examples/simple/examples/rtic-empty.rs b/examples/simple/examples/rtic-empty.rs new file mode 100644 index 0000000..0950065 --- /dev/null +++ b/examples/simple/examples/rtic-empty.rs @@ -0,0 +1,30 @@ +//! Empty RTIC project template +#![no_main] +#![no_std] + +#[rtic::app(device = pac)] +mod app { + use panic_rtt_target as _; + use rtt_target::{rprintln, rtt_init_default}; + use va108xx_hal::pac; + + #[local] + struct Local {} + + #[shared] + struct Shared {} + + #[init] + fn init(_ctx: init::Context) -> (Shared, Local) { + rtt_init_default!(); + rprintln!("-- Vorago RTIC template --"); + (Shared {}, Local {}) + } + + // `shared` cannot be accessed from this context + #[idle] + fn idle(_cx: idle::Context) -> ! { + #[allow(clippy::empty_loop)] + loop {} + } +} diff --git a/examples/simple/examples/rtt-log.rs b/examples/simple/examples/rtt-log.rs new file mode 100644 index 0000000..11f55be --- /dev/null +++ b/examples/simple/examples/rtt-log.rs @@ -0,0 +1,19 @@ +//! Code to test RTT logger functionality +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use panic_halt as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx as _; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + let mut counter = 0; + loop { + rprintln!("{}: Hello, world!", counter); + counter += 1; + cortex_m::asm::delay(25_000_000); + } +} diff --git a/examples/simple/examples/spi.rs b/examples/simple/examples/spi.rs new file mode 100644 index 0000000..27037ad --- /dev/null +++ b/examples/simple/examples/spi.rs @@ -0,0 +1,244 @@ +//! SPI example application +#![no_main] +#![no_std] + +use core::cell::RefCell; + +use cortex_m_rt::entry; +use embedded_hal::{ + delay::DelayNs, + spi::{Mode, SpiBus, MODE_0}, +}; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + gpio::{PinsA, PinsB}, + pac::{self, interrupt}, + prelude::*, + pwm::{default_ms_irq_handler, set_up_ms_tick}, + spi::{self, Spi, SpiBase, TransferConfig}, + IrqCfg, +}; + +#[derive(PartialEq, Debug)] +pub enum ExampleSelect { + // Enter loopback mode. It is not necessary to tie MOSI/MISO together for this + Loopback, + // Send a test buffer and print everything received + TestBuffer, +} + +#[derive(PartialEq, Debug)] +pub enum SpiBusSelect { + SpiAPortA, + SpiAPortB, + SpiBPortB, +} + +const EXAMPLE_SEL: ExampleSelect = ExampleSelect::Loopback; +const SPI_BUS_SEL: SpiBusSelect = SpiBusSelect::SpiBPortB; +const SPI_SPEED_KHZ: u32 = 1000; +const SPI_MODE: Mode = MODE_0; +const BLOCKMODE: bool = true; +const FILL_WORD: u8 = 0x0f; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- VA108xx SPI example application--"); + let mut dp = pac::Peripherals::take().unwrap(); + let mut delay = set_up_ms_tick( + IrqCfg::new(interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + + let spia_ref: RefCell>> = RefCell::new(None); + let spib_ref: RefCell>> = RefCell::new(None); + let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); + let pinsb = PinsB::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.portb); + + let mut spi_cfg = spi::SpiConfig::default(); + if EXAMPLE_SEL == ExampleSelect::Loopback { + spi_cfg = spi_cfg.loopback(true) + } + + // Set up the SPI peripheral + match SPI_BUS_SEL { + SpiBusSelect::SpiAPortA => { + let (sck, mosi, miso) = ( + pinsa.pa31.into_funsel_1(), + pinsa.pa30.into_funsel_1(), + pinsa.pa29.into_funsel_1(), + ); + let mut spia = Spi::spia( + dp.spia, + (sck, miso, mosi), + 50.MHz(), + spi_cfg, + Some(&mut dp.sysconfig), + None, + ); + spia.set_fill_word(FILL_WORD); + spia_ref.borrow_mut().replace(spia.downgrade()); + } + SpiBusSelect::SpiAPortB => { + let (sck, mosi, miso) = ( + pinsb.pb9.into_funsel_2(), + pinsb.pb8.into_funsel_2(), + pinsb.pb7.into_funsel_2(), + ); + let mut spia = Spi::spia( + dp.spia, + (sck, miso, mosi), + 50.MHz(), + spi_cfg, + Some(&mut dp.sysconfig), + None, + ); + spia.set_fill_word(FILL_WORD); + spia_ref.borrow_mut().replace(spia.downgrade()); + } + SpiBusSelect::SpiBPortB => { + let (sck, mosi, miso) = ( + pinsb.pb5.into_funsel_1(), + pinsb.pb4.into_funsel_1(), + pinsb.pb3.into_funsel_1(), + ); + let mut spib = Spi::spib( + dp.spib, + (sck, miso, mosi), + 50.MHz(), + spi_cfg, + Some(&mut dp.sysconfig), + None, + ); + spib.set_fill_word(FILL_WORD); + spib_ref.borrow_mut().replace(spib.downgrade()); + } + } + // Configure transfer specific properties here + match SPI_BUS_SEL { + SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => { + if let Some(ref mut spi) = *spia_ref.borrow_mut() { + let transfer_cfg = + TransferConfig::new_no_hw_cs(SPI_SPEED_KHZ.kHz(), SPI_MODE, BLOCKMODE, false); + spi.cfg_transfer(&transfer_cfg); + } + } + SpiBusSelect::SpiBPortB => { + if let Some(ref mut spi) = *spib_ref.borrow_mut() { + let hw_cs_pin = pinsb.pb2.into_funsel_1(); + let transfer_cfg = TransferConfig::new( + SPI_SPEED_KHZ.kHz(), + SPI_MODE, + Some(hw_cs_pin), + BLOCKMODE, + false, + ); + spi.cfg_transfer(&transfer_cfg); + } + } + } + + // Application logic + loop { + let mut reply_buf: [u8; 8] = [0; 8]; + match SPI_BUS_SEL { + SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => { + if let Some(ref mut spi) = *spia_ref.borrow_mut() { + if EXAMPLE_SEL == ExampleSelect::Loopback { + // Can't really verify correct reply here. + spi.write(&[0x42]).expect("write failed"); + // Because of the loopback mode, we should get back the fill word here. + spi.read(&mut reply_buf[0..1]).unwrap(); + assert_eq!(reply_buf[0], FILL_WORD); + delay.delay_ms(500_u32); + + let tx_buf: [u8; 3] = [0x01, 0x02, 0x03]; + spi.transfer(&mut reply_buf[0..3], &tx_buf).unwrap(); + assert_eq!(tx_buf, reply_buf[0..3]); + rprintln!( + "Received reply: {}, {}, {}", + reply_buf[0], + reply_buf[1], + reply_buf[2] + ); + delay.delay_ms(500_u32); + + let mut tx_rx_buf: [u8; 3] = [0x03, 0x02, 0x01]; + spi.transfer_in_place(&mut tx_rx_buf).unwrap(); + rprintln!( + "Received reply: {}, {}, {}", + tx_rx_buf[0], + tx_rx_buf[1], + tx_rx_buf[2] + ); + assert_eq!(&tx_rx_buf[0..3], &[0x03, 0x02, 0x01]); + } else { + let send_buf: [u8; 3] = [0x01, 0x02, 0x03]; + spi.transfer(&mut reply_buf[0..3], &send_buf).unwrap(); + rprintln!( + "Received reply: {}, {}, {}", + reply_buf[0], + reply_buf[1], + reply_buf[2] + ); + delay.delay_ms(1000_u32); + } + } + } + SpiBusSelect::SpiBPortB => { + if let Some(ref mut spi) = *spib_ref.borrow_mut() { + if EXAMPLE_SEL == ExampleSelect::Loopback { + // Can't really verify correct reply here. + spi.write(&[0x42]).expect("write failed"); + // Because of the loopback mode, we should get back the fill word here. + spi.read(&mut reply_buf[0..1]).unwrap(); + assert_eq!(reply_buf[0], FILL_WORD); + delay.delay_ms(500_u32); + + let tx_buf: [u8; 3] = [0x01, 0x02, 0x03]; + spi.transfer(&mut reply_buf[0..3], &tx_buf).unwrap(); + assert_eq!(tx_buf, reply_buf[0..3]); + rprintln!( + "Received reply: {}, {}, {}", + reply_buf[0], + reply_buf[1], + reply_buf[2] + ); + delay.delay_ms(500_u32); + + let mut tx_rx_buf: [u8; 3] = [0x03, 0x02, 0x01]; + spi.transfer_in_place(&mut tx_rx_buf).unwrap(); + rprintln!( + "Received reply: {}, {}, {}", + tx_rx_buf[0], + tx_rx_buf[1], + tx_rx_buf[2] + ); + assert_eq!(&tx_rx_buf[0..3], &[0x03, 0x02, 0x01]); + } else { + let send_buf: [u8; 3] = [0x01, 0x02, 0x03]; + spi.transfer(&mut reply_buf[0..3], &send_buf).unwrap(); + rprintln!( + "Received reply: {}, {}, {}", + reply_buf[0], + reply_buf[1], + reply_buf[2] + ); + delay.delay_ms(1000_u32); + } + } + } + } + } +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC0() { + default_ms_irq_handler() +} diff --git a/examples/simple/examples/timer-ticks.rs b/examples/simple/examples/timer-ticks.rs new file mode 100644 index 0000000..af341c4 --- /dev/null +++ b/examples/simple/examples/timer-ticks.rs @@ -0,0 +1,118 @@ +//! MS and Second counter implemented using the TIM0 and TIM1 peripheral +#![no_main] +#![no_std] + +use core::cell::Cell; +use cortex_m::interrupt::Mutex; +use cortex_m_rt::entry; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + clock::{get_sys_clock, set_sys_clock}, + pac::{self, interrupt}, + prelude::*, + time::Hertz, + timer::{default_ms_irq_handler, set_up_ms_tick, CountDownTimer, Event, IrqCfg, MS_COUNTER}, +}; + +#[allow(dead_code)] +enum LibType { + Pac, + Hal, +} + +static SEC_COUNTER: Mutex> = Mutex::new(Cell::new(0)); + +#[entry] +fn main() -> ! { + rtt_init_print!(); + let mut dp = pac::Peripherals::take().unwrap(); + let mut last_ms = 0; + rprintln!("-- Vorago system ticks using timers --"); + set_sys_clock(50.MHz()); + let lib_type = LibType::Hal; + match lib_type { + LibType::Pac => { + unsafe { + dp.sysconfig + .peripheral_clk_enable() + .modify(|_, w| w.irqsel().set_bit()); + dp.sysconfig + .tim_clk_enable() + .modify(|r, w| w.bits(r.bits() | (1 << 0) | (1 << 1))); + dp.irqsel.tim0(0).write(|w| w.bits(0x00)); + dp.irqsel.tim0(1).write(|w| w.bits(0x01)); + } + + let sys_clk: Hertz = 50.MHz(); + let cnt_ms = sys_clk.raw() / 1000 - 1; + let cnt_sec = sys_clk.raw() - 1; + unsafe { + dp.tim0.cnt_value().write(|w| w.bits(cnt_ms)); + dp.tim0.rst_value().write(|w| w.bits(cnt_ms)); + dp.tim0.ctrl().write(|w| { + w.enable().set_bit(); + w.irq_enb().set_bit() + }); + dp.tim1.cnt_value().write(|w| w.bits(cnt_sec)); + dp.tim1.rst_value().write(|w| w.bits(cnt_sec)); + dp.tim1.ctrl().write(|w| { + w.enable().set_bit(); + w.irq_enb().set_bit() + }); + unmask_irqs(); + } + } + LibType::Hal => { + set_up_ms_tick( + IrqCfg::new(interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + let mut second_timer = + CountDownTimer::new(&mut dp.sysconfig, get_sys_clock().unwrap(), dp.tim1); + second_timer.listen( + Event::TimeOut, + IrqCfg::new(interrupt::OC1, true, true), + Some(&mut dp.irqsel), + Some(&mut dp.sysconfig), + ); + second_timer.start(1.Hz()); + } + } + loop { + let current_ms = cortex_m::interrupt::free(|cs| MS_COUNTER.borrow(cs).get()); + if current_ms - last_ms >= 1000 { + last_ms = current_ms; + rprintln!("MS counter: {}", current_ms); + let second = cortex_m::interrupt::free(|cs| SEC_COUNTER.borrow(cs).get()); + rprintln!("Second counter: {}", second); + } + cortex_m::asm::delay(10000); + } +} + +fn unmask_irqs() { + unsafe { + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC1); + } +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC0() { + default_ms_irq_handler() +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC1() { + cortex_m::interrupt::free(|cs| { + let mut sec = SEC_COUNTER.borrow(cs).get(); + sec += 1; + SEC_COUNTER.borrow(cs).set(sec); + }); +} diff --git a/examples/simple/examples/uart-irq-rtic.rs b/examples/simple/examples/uart-irq-rtic.rs new file mode 100644 index 0000000..d808749 --- /dev/null +++ b/examples/simple/examples/uart-irq-rtic.rs @@ -0,0 +1,168 @@ +//! More complex UART application +//! +//! Uses the IRQ capabilities of the VA10820 peripheral and the RTIC framework to poll the UART in +//! a non-blocking way. You can send variably sized strings to the VA10820 which will be echoed +//! back to the sender. +//! +//! This script was tested with an Arduino Due. You can find the test script in the +//! [`/test/DueSerialTest`](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/test/DueSerialTest) +//! folder. +#![no_main] +#![no_std] + +#[rtic::app(device = pac, dispatchers = [OC4])] +mod app { + use embedded_io::Write; + use rtic_monotonics::systick::Systick; + use rtic_sync::make_channel; + use panic_rtt_target as _; + use rtt_target::{rprintln, rtt_init_print}; + use va108xx_hal::{ + time::Hertz, + gpio::PinsB, + pac, + prelude::*, + uart::{self, IrqCfg, IrqResult, UartWithIrqBase}, + }; + + #[local] + struct Local { + rx_info_tx: rtic_sync::channel::Sender<'static, RxInfo, 3>, + rx_info_rx: rtic_sync::channel::Receiver<'static, RxInfo, 3>, + } + + #[shared] + struct Shared { + irq_uart: UartWithIrqBase, + rx_buf: [u8; 64], + } + + #[derive(Debug, Copy, Clone)] + struct RxInfo { + pub bytes_read: usize, + pub end_idx: usize, + pub timeout: bool, + } + + #[init] + fn init(cx: init::Context) -> (Shared, Local) { + rtt_init_print!(); + //set_print_channel(channels.up.0); + rprintln!("-- VA108xx UART IRQ example application--"); + + // Initialize the systick interrupt & obtain the token to prove that we did + let systick_mono_token = rtic_monotonics::create_systick_token!(); + Systick::start(cx.core.SYST, Hertz::from(50.MHz()).raw(), systick_mono_token); + + let mut dp = cx.device; + let gpiob = PinsB::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.portb); + let tx = gpiob.pb21.into_funsel_1(); + let rx = gpiob.pb20.into_funsel_1(); + + let irq_cfg = IrqCfg::new(pac::interrupt::OC3, true, true); + let (mut irq_uart, _) = + uart::Uart::uartb(dp.uartb, (tx, rx), 115200.Hz(), &mut dp.sysconfig, 50.MHz()) + .into_uart_with_irq(irq_cfg, Some(&mut dp.sysconfig), Some(&mut dp.irqsel)) + .downgrade(); + irq_uart + .read_fixed_len_using_irq(64, true) + .expect("Read initialization failed"); + + let (rx_info_tx, rx_info_rx) = make_channel!(RxInfo, 3); + let rx_buf: [u8; 64] = [0; 64]; + //reply_handler::spawn().expect("spawning reply handler failed"); + ( + Shared { irq_uart, rx_buf }, + Local { + rx_info_tx, + rx_info_rx, + }, + ) + } + + // `shared` cannot be accessed from this context + #[idle] + fn idle(_cx: idle::Context) -> ! { + loop { + cortex_m::asm::nop(); + } + } + + #[task( + binds = OC3, + shared = [irq_uart, rx_buf], + local = [cnt: u32 = 0, result: IrqResult = IrqResult::new(), rx_info_tx], + )] + fn reception_task(cx: reception_task::Context) { + let result = cx.local.result; + let cnt: &mut u32 = cx.local.cnt; + let irq_uart = cx.shared.irq_uart; + let rx_buf = cx.shared.rx_buf; + let (completed, end_idx) = (irq_uart, rx_buf).lock(|irq_uart, rx_buf| { + match irq_uart.irq_handler(result, rx_buf) { + Ok(_) => { + if result.complete() { + // Initiate next transfer immediately + irq_uart + .read_fixed_len_using_irq(64, true) + .expect("Read operation init failed"); + + let mut end_idx = 0; + for idx in 0..rx_buf.len() { + if (rx_buf[idx] as char) == '\n' { + end_idx = idx; + break; + } + } + (true, end_idx) + } else { + (false, 0) + } + } + Err(e) => { + rprintln!("reception error {:?}", e); + (false, 0) + } + } + }); + if completed { + rprintln!("counter: {}", cnt); + cx.local + .rx_info_tx + .try_send(RxInfo { + bytes_read: result.bytes_read, + end_idx, + timeout: result.timeout(), + }) + .expect("RX queue full"); + } + *cnt += 1; + } + + #[task(shared = [irq_uart, rx_buf], local = [rx_info_rx], priority=1)] + async fn reply_handler(cx: reply_handler::Context) { + let mut irq_uart = cx.shared.irq_uart; + let mut rx_buf = cx.shared.rx_buf; + loop { + match cx.local.rx_info_rx.recv().await { + Ok(rx_info) => { + rprintln!("reception success, {} bytes read", rx_info.bytes_read); + if rx_info.timeout { + rprintln!("timeout occurred"); + } + rx_buf.lock(|rx_buf| { + let string = core::str::from_utf8(&rx_buf[0..rx_info.end_idx]) + .expect("Invalid string format"); + rprintln!("read string: {}", string); + irq_uart.lock(|uart| { + writeln!(uart.uart, "{}", string).expect("Sending reply failed"); + }); + }); + } + Err(e) => { + rprintln!("error receiving RX info: {:?}", e); + } + } + } + } +} diff --git a/examples/simple/examples/uart.rs b/examples/simple/examples/uart.rs new file mode 100644 index 0000000..beff171 --- /dev/null +++ b/examples/simple/examples/uart.rs @@ -0,0 +1,47 @@ +//! UART example application. Sends a test string over a UART and then enters +//! echo mode. +//! +//! Instructions: +//! +//! 1. Tie a USB to UART converter with RX to PA9 and TX to PA8. +//! 2. Connect to the serial interface by using an application like Putty or picocom. +//! You should set a "Hello World" print when the application starts. After that, everything +//! typed on the console should be printed back by the echo application. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal_nb::{nb, serial::Read}; +use embedded_io::Write as _; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{gpio::PinsA, pac, prelude::*, uart}; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- VA108xx UART example application--"); + + let mut dp = pac::Peripherals::take().unwrap(); + + let gpioa = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let tx = gpioa.pa9.into_funsel_2(); + let rx = gpioa.pa8.into_funsel_2(); + + let uarta = uart::Uart::uarta(dp.uarta, (tx, rx), 115200.Hz(), &mut dp.sysconfig, 50.MHz()); + let (mut tx, mut rx) = uarta.split(); + writeln!(tx, "Hello World\r").unwrap(); + loop { + // Echo what is received on the serial link. + match rx.read() { + Ok(recv) => { + nb::block!(embedded_hal_nb::serial::Write::write(&mut tx, recv)) + .expect("TX send error"); + } + Err(nb::Error::WouldBlock) => (), + Err(nb::Error::Other(uart_error)) => { + rprintln!("UART receive error {:?}", uart_error); + } + } + } +} diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs new file mode 100644 index 0000000..ddb240e --- /dev/null +++ b/examples/simple/src/main.rs @@ -0,0 +1,13 @@ +//! Dummy app which does not do anything. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use panic_rtt_target as _; + +#[entry] +fn main() -> ! { + loop { + cortex_m::asm::nop(); + } +} diff --git a/max116xx-10bit b/max116xx-10bit deleted file mode 160000 index c9b5f6a..0000000 --- a/max116xx-10bit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c9b5f6a4e919f8924db457e14ce9a504dece983c diff --git a/scripts/VA108xx_Series.yaml b/scripts/VA108xx_Series.yaml new file mode 100644 index 0000000..a6baec3 --- /dev/null +++ b/scripts/VA108xx_Series.yaml @@ -0,0 +1,144 @@ +name: VA108xx Series +generated_from_pack: true +pack_file_release: 1.4.0 +variants: +- name: VA108xx + cores: + - name: main + type: armv6m + core_access_options: !Arm + ap: 0 + psel: 0x0 + memory_map: + - !Ram + name: IRAM1 + range: + start: 0x10000000 + end: 0x10008000 + cores: + - main + - !Nvm + name: IROM1 + range: + start: 0x0 + end: 0x20000 + is_boot_memory: true + cores: + - main + flash_algorithms: + - va108xx_fm25v20a_fram_128kb_prog + - va108xx_m95m01_128kb_prog + - va108xx_mr25h10_1mb_prog + - va108xx_ttflash_prog +flash_algorithms: +- name: va108xx_fm25v20a_fram_128kb_prog + description: VA108_FM25V20A_FRAM_128KB + instructions: QLpwR8C6cEdkSMFoyQf80MFoyQb81AMhwWJwR3BHALVgSV9IyGNdSgIgEGFeSBBgXkhQYAMg0GL/9+b/XEiQYNBowAf80AEgkGDAB5Bg//fb/wAgAL0Atf/31v9PSFRJgWDBaMkH/NABIYFg/SGBYMkHgWD/98j/ACAAvXC1ACJLTUZLAiYURp1g//e9/xACnmABAgkOmWAABAAOmGCcYAAg2WiJB/zVnGBAHP8o+NPYaIAH/NUBIMAHmGD/96T/ASBAAlIcgkLe0wAgcL0AIHBHPLUFRgAgC0YAkP/3lP8uTDNIoGD/94//AiCgYCgCAA6gYCgEAA6gYOiyoGAL4OBogAf81RB4oGCgaAGQAJhSHEAcWx4AkAEr8dHgaIAH/NUQeAEhyQdAGKBg//ds/wAgPL0AIHBH8LUORgVG//dj/xZIAyGBYCkCCQ6BYCkECQ6BYOmygWAAIxlGgWDEaGQH/NWEaFscBCv32wAjDOCBYMRoZAf81YRoF3jksqdCAdDoGPC9UhxbHLNC8NMBIckHgWD/9zj/qBnwvQAgBUD///8AQAAAQAcEAACCAgAABgAAgAAAAAA= + pc_init: 0x1f + pc_uninit: 0x57 + pc_program_page: 0xd3 + pc_erase_sector: 0xcf + pc_erase_all: 0x7d + data_section_offset: 0x1b4 + flash_properties: + address_range: + start: 0x0 + end: 0x20000 + page_size: 0x100 + erased_byte_value: 0x0 + program_page_timeout: 3000 + erase_sector_timeout: 3000 + sectors: + - size: 0x2000 + address: 0x0 +- name: va108xx_m95m01_128kb_prog + description: VA108XX_M95M01_128KB + default: true + instructions: QLpwR8C6cEd6SMFoyQf80MFoyQb81AMhwWJwR3i1//fz/wUk5QcAJnJIc0sDIoRghWDBaMkH/NDBaEkH/NWBaACRwWhJB/zVgWgAkckHwmIH0ACWAL8AmUkcAJGZQvnb5ed4vQC1ZklkSMhjYUoCIBBhZEgQYGRIUGADINBi//fD/2JIkGD/97//ASCQYMAHkGD/97n/ACAAvQC1//e+///3sv9TSllIkGD/963/ASCQYFZI9zCQYP/3pv8AIAC98LUAJFFPS00mRq9g//ec/yACAiGpYAECCQ6pYAAEAA6oYK5gACDpaIkH/NWuYEAc/yj40+hogAf81QEgwAeoYP/3gv//94r/ASBAAmQchELb0wAg8L0AIHBHfLUGRgAgFEYNRgCQ//d5///3bf8xSjZIkGD/92j/AiCQYDACAA6QYDAEAA6QYPCykGAL4NBogAf81SB4kGCQaAGQAJhkHEAcbR4AkAEt8dHQaIAH/NUgeAEhyQdAGJBg//dF///3Tf8AIHy9ACBwR/C1FEYORgVG//dD///3N/8WSQMgiGAoAgAOiGAoBAAOiGDosohgACMaRopgyGhAB/zViGhbHAQr99sAIAzgimDLaFsH/NWLaCd427KfQgHQKBjwvUAcZBywQvDTASDAB4hg//cM/6gZ8L0AIAVAUMMAAP///wBAAABABwQAAIICAAAGAACAAAAAAA== + pc_init: 0x65 + pc_uninit: 0x9b + pc_program_page: 0x11b + pc_erase_sector: 0x117 + pc_erase_all: 0xc1 + data_section_offset: 0x210 + flash_properties: + address_range: + start: 0x0 + end: 0x20000 + page_size: 0x100 + erased_byte_value: 0x0 + program_page_timeout: 3000 + erase_sector_timeout: 3000 + sectors: + - size: 0x2000 + address: 0x0 +- name: va108xx_mr25h10_1mb_prog + description: VA108_MR25H10_1Mb + instructions: QLpwR8C6cEdjSMFoyQf80MFoyQb81AMhwWJwR3BHALVfSV5IyGNcSgIgEGFdSBBgXUhQYAMg0GL/9+b/W0iQYP/34v8BIJBgwAeQYP/33P8AIAC9ALX/99f/T0pTSJBg//fS/wEgkGBQSPcwkGD/98v/ACAAvXC1ACJMTUZLAiYURp1g//fA/xACnmABAgkOmWAABAAOmGCcYAAg2WiJB/zVnGBAHP8o+NPYaIAH/NUBIMAHmGD/96f/ASBAAlIcgkLe0wAgcL0AIHBHPLUFRgAgC0YAkP/3l/8vTDNIoGD/95L/AiCgYCgCAA6gYCgEAA6gYOiyoGAL4OBogAf81RB4oGCgaAGQAJhSHEAcWx4AkAEr8dHgaIAH/NUQeAEhyQdAGKBg//dv/wAgPL0AIHBH8LUORgVG//dm/xZIAyGBYCkCCQ6BYCkECQ6BYOmygWAAIxlGgWDEaGQH/NWEaFscBCv32wAjDOCBYMRoZAf81YRoF3jksqdCAdDoGPC9UhxbHLNC8NMBIckHgWD/9zv/qBnwvQAAACAFQP///wBAAABABwQAAIICAAAGAACAAAAAAA== + pc_init: 0x1f + pc_uninit: 0x55 + pc_program_page: 0xcd + pc_erase_sector: 0xc9 + pc_erase_all: 0x77 + data_section_offset: 0x1b0 + flash_properties: + address_range: + start: 0x0 + end: 0x20000 + page_size: 0x100 + erased_byte_value: 0x0 + program_page_timeout: 10000 + erase_sector_timeout: 10000 + sectors: + - size: 0x2000 + address: 0x0 +- name: va108xx_ttflash_prog + description: VA108_TT_Flash_8MBx + instructions: QLpwR8C6cEd9SMFoyQf80MFoyQb81AMhwWJwR3i1//fz/wUk5QcAJnVIdksDIoRghWDBaMkH/NDBaEkH/NWBaACRwWhJB/zVgWgAkckHwmIH0ACWAL8AmUkcAJGZQvnb5ed4vQC1aUlnSMhjZEoCIBBhZ0gQYGdIUGADINBi//fD/2VIkGD/97//ASCQYAAgkGABIMAHkGD/97b/ACAAvQC1//e7///3r/9VSlpIkGD/96r/ASCQYP0gkGDAB5Bg//ei/wAgAL0Atf/3p///95v/S0hQSYFgT0laMYFg//eT///3m/8AIAC9ELUERv/3lf//94n/QkpHSJBg//eE/yAgkGAgAgAOkGAgBAAOkGABIeCyyQdAGJBg//d////3c/8AIBC9fLUGRgAgFEYNRgCQ//dz///3Z/8xSjZIkGD/92L/AiCQYDACAA6QYDAEAA6QYPCykGAL4NBogAf81SB4kGCQaAGQAJhkHEAcbR4AkAEt8dHQaIAH/NUgeAEhyQdAGJBg//c////3R/8AIHy9ACBwR/C1FEYORgVG//c9///3Mf8WSQMgiGAoAgAOiGAoBAAOiGDosohgACMaRopgyGhAB/zViGhbHAQr99sAIAzgimDLaFsH/NWLaCd427KfQgHQKBjwvUAcZBywQvDTASDAB4hg//cG/6gZ8L0AIAVAUMMAAP///wBAAABABwQAAIICAAAGAACAAAAAAA== + pc_init: 0x65 + pc_uninit: 0xa1 + pc_program_page: 0x127 + pc_erase_sector: 0xeb + pc_erase_all: 0xc9 + data_section_offset: 0x21c + flash_properties: + address_range: + start: 0x0 + end: 0x20000 + page_size: 0x100 + erased_byte_value: 0xff + program_page_timeout: 10000 + erase_sector_timeout: 50000 + sectors: + - size: 0x1000 + address: 0x0 + - size: 0x1000 + address: 0x1000 + - size: 0x1000 + address: 0x2000 + - size: 0x1000 + address: 0x3000 + - size: 0x1000 + address: 0x4000 + - size: 0x1000 + address: 0x5000 + - size: 0x1000 + address: 0x6000 + - size: 0x1000 + address: 0x7000 + - size: 0x1000 + address: 0x8000 + - size: 0x1000 + address: 0x9000 + - size: 0x1000 + address: 0xa000 + - size: 0x1000 + address: 0xb000 + - size: 0x1000 + address: 0xc000 + - size: 0x1000 + address: 0xd000 + - size: 0x1000 + address: 0xe000 + - size: 0x1000 + address: 0xf000 diff --git a/va108xx b/va108xx deleted file mode 160000 index f626e33..0000000 --- a/va108xx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f626e33e72d4863b68da89099cf60ce14de3e114 diff --git a/va108xx-hal b/va108xx-hal deleted file mode 160000 index e9f1294..0000000 --- a/va108xx-hal +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e9f12945725cf8814fb224a30ac513074de624cc diff --git a/.cargo/config.toml b/va108xx-hal/.cargo/config.toml similarity index 74% rename from .cargo/config.toml rename to va108xx-hal/.cargo/config.toml index fb1a4c8..dd54ddd 100644 --- a/.cargo/config.toml +++ b/va108xx-hal/.cargo/config.toml @@ -1,10 +1,9 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # uncomment ONE of these three option to make `cargo run` start a GDB session # which option to pick depends on your system -# runner = "arm-none-eabi-gdb -q -x openocd.gdb" -# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "arm-none-eabi-gdb -q -x jlink.gdb" +# runner = "gdb-multiarch -q -x jlink.gdb" # runner = "gdb -q -x openocd.gdb" -runner = "gdb-multiarch -q -x jlink.gdb" rustflags = [ # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x @@ -16,12 +15,12 @@ rustflags = [ # if you run into problems with LLD switch to the GNU linker by commenting out # this line - # "-C", "linker=/home/rmueller/.local/xPacks/@xpack-dev-tools/arm-none-eabi-gcc/10.2.1-1.1.2/.content/bin/arm-none-eabi-ld", + # "-C", "linker=arm-none-eabi-ld", # if you need to link to pre-compiled C libraries provided by a C toolchain # use GCC as the linker by commenting out both lines above and then # uncommenting the three lines below - # "-C", "linker=/home/rmueller/.local/xPacks/@xpack-dev-tools/arm-none-eabi-gcc/10.2.1-1.1.2/.content/bin/arm-none-eabi-gcc", + # "-C", "linker=arm-none-eabi-gcc", # "-C", "link-arg=-Wl,-Tlink.x", # "-C", "link-arg=-nostartfiles", ] diff --git a/va108xx-hal/.github/bors.toml b/va108xx-hal/.github/bors.toml new file mode 100644 index 0000000..1779788 --- /dev/null +++ b/va108xx-hal/.github/bors.toml @@ -0,0 +1,2 @@ +status = ["ci"] +delete_merged_branches = true diff --git a/va108xx-hal/.github/workflows/changelog.yml b/va108xx-hal/.github/workflows/changelog.yml new file mode 100644 index 0000000..dbba297 --- /dev/null +++ b/va108xx-hal/.github/workflows/changelog.yml @@ -0,0 +1,20 @@ +on: + pull_request_target: + +name: Changelog check + +jobs: + changelog: + name: Changelog check + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Changelog updated + uses: Zomzog/changelog-checker@v1.2.0 + with: + fileName: CHANGELOG.md + noChangelogLabel: no changelog + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/va108xx-hal/.github/workflows/ci.yml b/va108xx-hal/.github/workflows/ci.yml new file mode 100644 index 0000000..8caa486 --- /dev/null +++ b/va108xx-hal/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +on: [push] + +name: ci + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - uses: actions-rs/cargo@v1 + with: + command: check + - uses: actions-rs/cargo@v1 + with: + command: check + args: --examples + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + + ci: + if: ${{ success() }} + # all new jobs must be added to this list + needs: [check, fmt, clippy] + runs-on: ubuntu-latest + steps: + - name: CI succeeded + run: exit 0 \ No newline at end of file diff --git a/va108xx-hal/.gitignore b/va108xx-hal/.gitignore new file mode 100644 index 0000000..fd634d0 --- /dev/null +++ b/va108xx-hal/.gitignore @@ -0,0 +1,9 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/va108xx-hal/CHANGELOG.md b/va108xx-hal/CHANGELOG.md new file mode 100644 index 0000000..706be5a --- /dev/null +++ b/va108xx-hal/CHANGELOG.md @@ -0,0 +1,145 @@ +Change Log +======= + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [v0.5.2] 2024-06-16 + +## Fixed + +- Replaced usage to `ptr::write_volatile` in UART module which is denied on more recent Rust + compilers. + +## [v0.5.1] + +### Changes + +- Updated dependencies: + - `cortex-m-rtic` (dev-depencency) to 1.1.2 + - `once_cell` to 1.12.0 + - Other dependencies: Only revision has changed + +## [v0.5.0] + +### Added + +- Reactored IRQ handling, so that `unmask` operations can be moved to HAL +- Added UART IRQ handler. Right now, can only perform reception, TX still needs to be done in + a blocking manner +- Added RTIC template and RTIC UART IRQ application + +### Fixed + +- Bugfix in UART code where RX and TX could not be enabled or disabled independently + +## [v0.4.3] + +- Various smaller fixes for READMEs, update of links in documentation +- Simplified CI for github, do not use `cross` +- New `blinky-pac` example +- Use HAL delay in `blinky` example + +## [v0.4.2] + +### Added + +- `port_mux` function to set pin function select manually + +### Changed + +- Clear TX and RX FIFO in SPI transfer function + +## [v0.4.1] + +### Fixed + +- Initial blockmode setting was not set in SPI constructor + +## [v0.4.0] + +### Changed + +- Replaced `Hertz` by `impl Into` completely and removed + `+ Copy` where not necessary + +## [v0.3.1] + +- Updated all links to point to new repository + +## [v0.3.0] + +### Added + +- TIM Cascade example + +### Changed + +- `CountDownTimer` new function now expects an `impl Into` instead of `Hertz` +- Primary repository now hosted on IRS external git: https://egit.irs.uni-stuttgart.de/rust/va108xx-hal +- Relicensed as Apache-2.0 + +## [0.2.3] + +### Added + +- Basic API for EDAC functionality +- PWM implementation and example +- API to perform peripheral resets + +### Changed + +- Improved Timer API. It is now possible to simply use `new` on `CountDownTimer` + +## [0.2.2] + +### Added + +- DelayUs and DelayMs trait implementations for timer +- SPI implementation for blocking API, supports blockmode as well +- Basic I2C implementation for blocking API + +### Changed + +- API which expects values in Hertz now uses `impl Into` as input parameter + +## [0.2.1] + +### Added + +- Adds the IRQ interface to configure interrupts on output and input pins +- Utility function to set up millisecond timer with `TIM0` +- Function to set clock divisor registers in `clock` module + +### Changed + +- Minor optimizations and tweaks for GPIO module +- Moved the `FilterClkSel` struct to the `clock` module, re-exporting in `gpio` +- Clearing output state at initialization of Output pins + +## [0.2.0] + +### Changed + +- New GPIO implementation which uses type-level programming. Implementation heavily based on the + ATSAMD GPIO HAL: https://docs.rs/atsamd-hal/0.13.0/atsamd_hal/gpio/v2/index.html +- Changes to API, therefore minor version bump + +### Added + +- UART implementation +- UART example +- Some bugfixes for GPIO implementation +- Rust edition updated to 2021 + +## [0.1.0] + +### Added + +- First version of the HAL which adds the GPIO implementation and timer implementation. +- Also adds some examples and helper files to set up new binary crates +- RTT example application +- Added basic test binary in form of an example +- README with basic instructions how to set up own binary crate diff --git a/va108xx-hal/Cargo.toml b/va108xx-hal/Cargo.toml new file mode 100644 index 0000000..50b21b8 --- /dev/null +++ b/va108xx-hal/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "va108xx-hal" +version = "0.6.0" +authors = ["Robin Mueller "] +edition = "2021" +description = "HAL for the Vorago VA108xx family of microcontrollers" +homepage = "https://egit.irs.uni-stuttgart.de/rust/va108xx-hal" +repository = "https://egit.irs.uni-stuttgart.de/rust/va108xx-hal" +license = "Apache-2.0" +keywords = ["no-std", "hal", "cortex-m", "vorago", "va108xx"] +categories = ["aerospace", "embedded", "no-std", "hardware-support"] + +[dependencies] +cortex-m = { version = "0.7", features = ["critical-section-single-core"]} +cortex-m-rt = "0.7" +nb = "1" +paste = "1" +embedded-hal-nb = "1" +libm = "0.2" +embedded-io = "0.6" +fugit = "0.3" +typenum = "1" +defmt = { version = "0.3", optional = true } +delegate = "0.12" + +[dependencies.va108xx] +version = "0.3.0" +path = "../va108xx" +default-features = false +features = ["critical-section"] + +[dependencies.embedded-hal] +version = "1" + +[dependencies.void] +version = "1" +default-features = false + +[dependencies.once_cell] +version = "1.14" +default-features = false + +[features] +default = ["rt"] +rt = ["va108xx/rt"] diff --git a/va108xx-hal/LICENSE-APACHE b/va108xx-hal/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/va108xx-hal/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/va108xx-hal/NOTICE b/va108xx-hal/NOTICE new file mode 100644 index 0000000..4b4fe08 --- /dev/null +++ b/va108xx-hal/NOTICE @@ -0,0 +1,3 @@ +Rust Hardware Abstraction Layer (HAL) crate for the Vorago VA108xx family of MCUs + +This software contains code developed at the University of Stuttgart. \ No newline at end of file diff --git a/va108xx-hal/README.md b/va108xx-hal/README.md new file mode 100644 index 0000000..a632020 --- /dev/null +++ b/va108xx-hal/README.md @@ -0,0 +1,88 @@ +[![Crates.io](https://img.shields.io/crates/v/va108xx-hal)](https://crates.io/crates/va108xx-hal) +[![ci](https://github.com/us-irs/va108xx-hal-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/us-irs/va108xx-hal-rs/actions/workflows/ci.yml) +[![docs.rs](https://img.shields.io/docsrs/va108xx-hal)](https://docs.rs/va108xx-hal) + +# HAL for the Vorago VA108xx MCU family + +This repository contains the **H**ardware **A**bstraction **L**ayer (HAL), which is an additional +hardware abstraction on top of the [peripheral access API](https://egit.irs.uni-stuttgart.de/rust/va108xx). + +It is the result of reading the datasheet for the device and encoding a type-safe layer over the +raw PAC. This crate also implements traits specified by the +[embedded-hal](https://github.com/rust-embedded/embedded-hal) project, making it compatible with +various drivers in the embedded rust ecosystem. + +In contrats to other HAL implementations, there is only one chip variant available here so there +is no need to pass the chip variant as a feature. + +## Supported Boards + + The first way to use this HAL will probably be with the + [REB1 development board](https://www.voragotech.com/products/reb1-va108x0-development-board-0). + The BSP provided for this board also contains instructions how to flash the board. + + | Crate | Version | +|:------|:--------| +[vorago-reb1](https://crates.io/crates/vorago-reb1) | [![Crates.io](https://img.shields.io/crates/v/vorago-reb1)](https://crates.io/crates/vorago-reb1) | + +## Building + +Building an application requires the `thumbv6m-none-eabi` cross-compiler toolchain. +If you have not installed it yet, you can do so with + +```sh +rustup target add thumbv6m-none-eabi +``` + +After that, you can use `cargo build` to build the development version of the crate. + +If you have not done this yet, it is recommended to read some of the excellent resources +available to learn Rust: + +- [Rust Embedded Book](https://docs.rust-embedded.org/book/) +- [Rust Discovery Book](https://docs.rust-embedded.org/discovery/) + +## Examples + +Some examples, which are not specific to a particular board were provided as well. +You can build the timer example with + +```sh +cargo build --example timer-ticks +``` + +## Setting up your own binary crate + +If you have a custom board, you might be interested in setting up a new binary crate for your +project. These steps aim to provide a complete list to get a binary crate working to flash +your custom board. + +The hello world of embedded development is usually to blinky a LED. This example +is contained within the +[examples folder](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/blinky.rs). + +1. Set up your Rust cross-compiler if you have not done so yet. See more in the [build chapter](#Building) +2. Create a new binary crate with `cargo init` +3. To ensure that `cargo build` cross-compiles, it is recommended to create a `.cargo/config.toml` + file. A sample `.cargo/config.toml` file is provided in this repository as well +4. Copy the `memory.x` file into your project. This file contains information required by the linker. +5. Copy the `blinky.rs` file to the `src/main.rs` file in your binary crate +6. You need to add some dependencies to your `Cargo.toml` file + + ```toml + [dependencies] + cortex-m = "" + cortex-m-rt = "" + panic-halt = "" + embedded-hal = "" + + [dependencies.va108xx-hal] + version = "" + features = ["rt"] + ``` + +6. Build the application with `cargo build` + +7. Flashing the board might work differently for different boards and there is usually + more than one way. You can find example instructions for the REB1 development board + [here](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1). diff --git a/va108xx-hal/automation/Dockerfile b/va108xx-hal/automation/Dockerfile new file mode 100644 index 0000000..b789384 --- /dev/null +++ b/va108xx-hal/automation/Dockerfile @@ -0,0 +1,13 @@ +# Run the following commands from root directory to build and run locally +# docker build -f automation/Dockerfile -t . +# docker run -it +FROM rust:latest +RUN apt-get update +RUN apt-get --yes upgrade +# tzdata is a dependency, won't install otherwise +ARG DEBIAN_FRONTEND=noninteractive + +RUN rustup install nightly && \ + rustup target add thumbv6m-none-eabi && \ + rustup +nightly target add thumbv6m-none-eabi && \ + rustup component add rustfmt clippy diff --git a/va108xx-hal/automation/Jenkinsfile b/va108xx-hal/automation/Jenkinsfile new file mode 100644 index 0000000..9a27623 --- /dev/null +++ b/va108xx-hal/automation/Jenkinsfile @@ -0,0 +1,37 @@ +pipeline { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + + + stages { + stage('Clippy') { + steps { + sh 'cargo clippy' + } + } + stage('Rustfmt') { + steps { + sh 'cargo fmt' + } + } + stage('Docs') { + steps { + sh 'cargo +nightly doc' + } + } + stage('Check') { + steps { + sh 'cargo check --target thumbv6m-none-eabi' + } + } + stage('Check Examples') { + steps { + sh 'cargo check --target thumbv6m-none-eabi --examples' + } + } + } +} \ No newline at end of file diff --git a/va108xx-hal/jlink.gdb b/va108xx-hal/jlink.gdb new file mode 100644 index 0000000..20ff2d5 --- /dev/null +++ b/va108xx-hal/jlink.gdb @@ -0,0 +1,10 @@ +target remote localhost:2331 + +monitor reset + +# *try* to stop at the user entry point (it might be gone due to inlining) +break main + +load + +continue diff --git a/va108xx-hal/memory.x b/va108xx-hal/memory.x new file mode 100644 index 0000000..1ca0e97 --- /dev/null +++ b/va108xx-hal/memory.x @@ -0,0 +1,10 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */ + RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */ +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/va108xx-hal/src/clock.rs b/va108xx-hal/src/clock.rs new file mode 100644 index 0000000..850c5da --- /dev/null +++ b/va108xx-hal/src/clock.rs @@ -0,0 +1,64 @@ +//! # API for clock related functionality +//! +//! This also includes functionality to enable the peripheral clocks +use crate::time::Hertz; +use crate::PeripheralSelect; +use cortex_m::interrupt::{self, Mutex}; +use once_cell::unsync::OnceCell; + +static SYS_CLOCK: Mutex> = Mutex::new(OnceCell::new()); + +pub type PeripheralClocks = PeripheralSelect; + +#[derive(Debug, PartialEq, Eq)] +pub enum FilterClkSel { + SysClk = 0, + Clk1 = 1, + Clk2 = 2, + Clk3 = 3, + Clk4 = 4, + Clk5 = 5, + Clk6 = 6, + Clk7 = 7, +} + +/// The Vorago in powered by an external clock which might have different frequencies. +/// The clock can be set here so it can be used by other software components as well. +/// The clock can be set exactly once +pub fn set_sys_clock(freq: impl Into) { + interrupt::free(|cs| { + SYS_CLOCK.borrow(cs).set(freq.into()).ok(); + }) +} + +/// Returns the configured system clock +pub fn get_sys_clock() -> Option { + interrupt::free(|cs| SYS_CLOCK.borrow(cs).get().copied()) +} + +pub fn set_clk_div_register(syscfg: &mut va108xx::Sysconfig, clk_sel: FilterClkSel, div: u32) { + match clk_sel { + FilterClkSel::SysClk => (), + FilterClkSel::Clk1 => syscfg.ioconfig_clkdiv1().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk2 => syscfg.ioconfig_clkdiv2().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk3 => syscfg.ioconfig_clkdiv3().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk4 => syscfg.ioconfig_clkdiv4().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk5 => syscfg.ioconfig_clkdiv5().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk6 => syscfg.ioconfig_clkdiv6().write(|w| unsafe { w.bits(div) }), + FilterClkSel::Clk7 => syscfg.ioconfig_clkdiv7().write(|w| unsafe { w.bits(div) }), + } +} + +#[inline] +pub fn enable_peripheral_clock(syscfg: &mut va108xx::Sysconfig, clock: PeripheralClocks) { + syscfg + .peripheral_clk_enable() + .modify(|r, w| unsafe { w.bits(r.bits() | (1 << clock as u8)) }); +} + +#[inline] +pub fn disable_peripheral_clock(syscfg: &mut va108xx::Sysconfig, clock: PeripheralClocks) { + syscfg + .peripheral_clk_enable() + .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << clock as u8)) }); +} diff --git a/va108xx-hal/src/gpio/dynpins.rs b/va108xx-hal/src/gpio/dynpins.rs new file mode 100644 index 0000000..edbce56 --- /dev/null +++ b/va108xx-hal/src/gpio/dynpins.rs @@ -0,0 +1,517 @@ +//! # Type-erased, value-level module for GPIO pins +//! +//! Although the type-level API is generally preferred, it is not suitable in +//! all cases. Because each pin is represented by a distinct type, it is not +//! possible to store multiple pins in a homogeneous data structure. The +//! value-level API solves this problem by erasing the type information and +//! tracking the pin at run-time. +//! +//! Value-level pins are represented by the [`DynPin`] type. [`DynPin`] has two +//! fields, `id` and `mode` with types [`DynPinId`] and [`DynPinMode`] +//! respectively. The implementation of these types closely mirrors the +//! type-level API. +//! +//! Instances of [`DynPin`] cannot be created directly. Rather, they must be +//! created from their type-level equivalents using [`From`]/[`Into`]. +//! +//! ``` +//! // Move a pin out of the Pins struct and convert to a DynPin +//! let pa0: DynPin = pins.pa0.into(); +//! ``` +//! +//! Conversions between pin modes use a value-level version of the type-level +//! API. +//! +//! ``` +//! // Use one of the literal function names +//! pa0.into_floating_input(); +//! // Use a method and a DynPinMode variant +//! pa0.into_mode(DYN_FLOATING_INPUT); +//! ``` +//! +//! Because the pin state cannot be tracked at compile-time, many [`DynPin`] +//! operations become fallible. Run-time checks are inserted to ensure that +//! users don't try to, for example, set the output level of an input pin. +//! +//! Users may try to convert value-level pins back to their type-level +//! equivalents. However, this option is fallible, because the compiler cannot +//! guarantee the pin has the correct ID or is in the correct mode at +//! compile-time. Use [`TryFrom`](core::convert::TryFrom)/ +//! [`TryInto`](core::convert::TryInto) for this conversion. +//! +//! ``` +//! // Convert to a `DynPin` +//! let pa0: DynPin = pins.pa0.into(); +//! // Change pin mode +//! pa0.into_floating_input(); +//! // Convert back to a `Pin` +//! let pa0: Pin = pa0.try_into().unwrap(); +//! ``` +//! +//! # Embedded HAL traits +//! +//! This module implements all of the embedded HAL GPIO traits for [`DynPin`]. +//! However, whereas the type-level API uses +//! `Error = core::convert::Infallible`, the value-level API can return a real +//! error. If the [`DynPin`] is not in the correct [`DynPinMode`] for the +//! operation, the trait functions will return +//! [`InvalidPinType`](PinError::InvalidPinType). + +use super::{ + pins::{FilterType, InterruptEdge, InterruptLevel, Pin, PinId, PinMode, PinState}, + reg::RegisterInterface, +}; +use crate::{clock::FilterClkSel, pac, FunSel, IrqCfg}; + +//================================================================================================== +// DynPinMode configurations +//================================================================================================== + +/// Value-level `enum` for disabled configurations +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DynDisabled { + Floating, + PullDown, + PullUp, +} + +/// Value-level `enum` for input configurations +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DynInput { + Floating, + PullDown, + PullUp, +} + +/// Value-level `enum` for output configurations +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DynOutput { + PushPull, + OpenDrain, + ReadablePushPull, + ReadableOpenDrain, +} + +pub type DynAlternate = FunSel; + +//============================================================================== +// Error +//============================================================================== + +/// GPIO error type +/// +/// [`DynPin`]s are not tracked and verified at compile-time, so run-time +/// operations are fallible. This `enum` represents the corresponding errors. +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct InvalidPinTypeError; + +impl embedded_hal::digital::Error for InvalidPinTypeError { + fn kind(&self) -> embedded_hal::digital::ErrorKind { + embedded_hal::digital::ErrorKind::Other + } +} + +//================================================================================================== +// DynPinMode +//================================================================================================== + +/// Value-level `enum` representing pin modes +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DynPinMode { + Input(DynInput), + Output(DynOutput), + Alternate(DynAlternate), +} + +/// Value-level variant of [`DynPinMode`] for floating input mode +pub const DYN_FLOATING_INPUT: DynPinMode = DynPinMode::Input(DynInput::Floating); +/// Value-level variant of [`DynPinMode`] for pull-down input mode +pub const DYN_PULL_DOWN_INPUT: DynPinMode = DynPinMode::Input(DynInput::PullDown); +/// Value-level variant of [`DynPinMode`] for pull-up input mode +pub const DYN_PULL_UP_INPUT: DynPinMode = DynPinMode::Input(DynInput::PullUp); + +/// Value-level variant of [`DynPinMode`] for push-pull output mode +pub const DYN_PUSH_PULL_OUTPUT: DynPinMode = DynPinMode::Output(DynOutput::PushPull); +/// Value-level variant of [`DynPinMode`] for open-drain output mode +pub const DYN_OPEN_DRAIN_OUTPUT: DynPinMode = DynPinMode::Output(DynOutput::OpenDrain); +/// Value-level variant of [`DynPinMode`] for readable push-pull output mode +pub const DYN_RD_PUSH_PULL_OUTPUT: DynPinMode = DynPinMode::Output(DynOutput::ReadablePushPull); +/// Value-level variant of [`DynPinMode`] for readable opendrain output mode +pub const DYN_RD_OPEN_DRAIN_OUTPUT: DynPinMode = DynPinMode::Output(DynOutput::ReadableOpenDrain); + +/// Value-level variant of [`DynPinMode`] for function select 1 +pub const DYN_ALT_FUNC_1: DynPinMode = DynPinMode::Alternate(DynAlternate::Sel1); +/// Value-level variant of [`DynPinMode`] for function select 2 +pub const DYN_ALT_FUNC_2: DynPinMode = DynPinMode::Alternate(DynAlternate::Sel2); +/// Value-level variant of [`DynPinMode`] for function select 3 +pub const DYN_ALT_FUNC_3: DynPinMode = DynPinMode::Alternate(DynAlternate::Sel3); + +//================================================================================================== +// DynGroup & DynPinId +//================================================================================================== + +/// Value-level `enum` for pin groups +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DynGroup { + A, + B, +} + +/// Value-level `struct` representing pin IDs +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct DynPinId { + pub group: DynGroup, + pub num: u8, +} + +//================================================================================================== +// DynRegisters +//================================================================================================== + +/// Provide a safe register interface for [`DynPin`]s +/// +/// This `struct` takes ownership of a [`DynPinId`] and provides an API to +/// access the corresponding regsiters. +struct DynRegisters { + id: DynPinId, +} + +// [`DynRegisters`] takes ownership of the [`DynPinId`], and [`DynPin`] +// guarantees that each pin is a singleton, so this implementation is safe. +unsafe impl RegisterInterface for DynRegisters { + #[inline] + fn id(&self) -> DynPinId { + self.id + } +} + +impl DynRegisters { + /// Create a new instance of [`DynRegisters`] + /// + /// # Safety + /// + /// Users must never create two simultaneous instances of this `struct` with + /// the same [`DynPinId`] + #[inline] + unsafe fn new(id: DynPinId) -> Self { + DynRegisters { id } + } +} + +//================================================================================================== +// DynPin +//================================================================================================== + +/// A value-level pin, parameterized by [`DynPinId`] and [`DynPinMode`] +/// +/// This type acts as a type-erased version of [`Pin`]. Every pin is represented +/// by the same type, and pins are tracked and distinguished at run-time. +pub struct DynPin { + regs: DynRegisters, + mode: DynPinMode, +} + +impl DynPin { + /// Create a new [`DynPin`] + /// + /// # Safety + /// + /// Each [`DynPin`] must be a singleton. For a given [`DynPinId`], there + /// must be at most one corresponding [`DynPin`] in existence at any given + /// time. Violating this requirement is `unsafe`. + #[inline] + unsafe fn new(id: DynPinId, mode: DynPinMode) -> Self { + DynPin { + regs: DynRegisters::new(id), + mode, + } + } + + /// Return a copy of the pin ID + #[inline] + pub fn id(&self) -> DynPinId { + self.regs.id + } + + /// Return a copy of the pin mode + #[inline] + pub fn mode(&self) -> DynPinMode { + self.mode + } + + /// Convert the pin to the requested [`DynPinMode`] + #[inline] + pub fn into_mode(&mut self, mode: DynPinMode) { + // Only modify registers if we are actually changing pin mode + if mode != self.mode { + self.regs.change_mode(mode); + self.mode = mode; + } + } + + #[inline] + pub fn into_funsel_1(&mut self) { + self.into_mode(DYN_ALT_FUNC_1); + } + + #[inline] + pub fn into_funsel_2(&mut self) { + self.into_mode(DYN_ALT_FUNC_2); + } + + #[inline] + pub fn into_funsel_3(&mut self) { + self.into_mode(DYN_ALT_FUNC_3); + } + + /// Configure the pin to operate as a floating input + #[inline] + pub fn into_floating_input(&mut self) { + self.into_mode(DYN_FLOATING_INPUT); + } + + /// Configure the pin to operate as a pulled down input + #[inline] + pub fn into_pull_down_input(&mut self) { + self.into_mode(DYN_PULL_DOWN_INPUT); + } + + /// Configure the pin to operate as a pulled up input + #[inline] + pub fn into_pull_up_input(&mut self) { + self.into_mode(DYN_PULL_UP_INPUT); + } + + /// Configure the pin to operate as a push-pull output + #[inline] + pub fn into_push_pull_output(&mut self) { + self.into_mode(DYN_PUSH_PULL_OUTPUT); + } + + /// Configure the pin to operate as a push-pull output + #[inline] + pub fn into_open_drain_output(&mut self) { + self.into_mode(DYN_OPEN_DRAIN_OUTPUT); + } + + /// Configure the pin to operate as a push-pull output + #[inline] + pub fn into_readable_push_pull_output(&mut self) { + self.into_mode(DYN_RD_PUSH_PULL_OUTPUT); + } + + /// Configure the pin to operate as a push-pull output + #[inline] + pub fn into_readable_open_drain_output(&mut self) { + self.into_mode(DYN_RD_OPEN_DRAIN_OUTPUT); + } + + common_reg_if_functions!(); + + /// See p.53 of the programmers guide for more information. + /// Possible delays in clock cycles: + /// - Delay 1: 1 + /// - Delay 2: 2 + /// - Delay 1 + Delay 2: 3 + #[inline] + pub fn delay(self, delay_1: bool, delay_2: bool) -> Result { + match self.mode { + DynPinMode::Output(_) => { + self.regs.delay(delay_1, delay_2); + Ok(self) + } + _ => Err(InvalidPinTypeError), + } + } + + /// See p.52 of the programmers guide for more information. + /// When configured for pulse mode, a given pin will set the non-default state for exactly + /// one clock cycle before returning to the configured default state + pub fn pulse_mode( + self, + enable: bool, + default_state: PinState, + ) -> Result { + match self.mode { + DynPinMode::Output(_) => { + self.regs.pulse_mode(enable, default_state); + Ok(self) + } + _ => Err(InvalidPinTypeError), + } + } + + /// See p.37 and p.38 of the programmers guide for more information. + #[inline] + pub fn filter_type( + self, + filter: FilterType, + clksel: FilterClkSel, + ) -> Result { + match self.mode { + DynPinMode::Input(_) => { + self.regs.filter_type(filter, clksel); + Ok(self) + } + _ => Err(InvalidPinTypeError), + } + } + + pub fn interrupt_edge( + mut self, + edge_type: InterruptEdge, + irq_cfg: IrqCfg, + syscfg: Option<&mut pac::Sysconfig>, + irqsel: Option<&mut pac::Irqsel>, + ) -> Result { + match self.mode { + DynPinMode::Input(_) | DynPinMode::Output(_) => { + self.regs.interrupt_edge(edge_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + Ok(self) + } + _ => Err(InvalidPinTypeError), + } + } + + pub fn interrupt_level( + mut self, + level_type: InterruptLevel, + irq_cfg: IrqCfg, + syscfg: Option<&mut pac::Sysconfig>, + irqsel: Option<&mut pac::Irqsel>, + ) -> Result { + match self.mode { + DynPinMode::Input(_) | DynPinMode::Output(_) => { + self.regs.interrupt_level(level_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + Ok(self) + } + _ => Err(InvalidPinTypeError), + } + } + + #[inline] + pub fn toggle_with_toggle_reg(&mut self) -> Result<(), InvalidPinTypeError> { + match self.mode { + DynPinMode::Output(_) => { + self.regs.toggle(); + Ok(()) + } + _ => Err(InvalidPinTypeError), + } + } + + #[inline] + fn _read(&self) -> Result { + match self.mode { + DynPinMode::Input(_) | DYN_RD_OPEN_DRAIN_OUTPUT | DYN_RD_PUSH_PULL_OUTPUT => { + Ok(self.regs.read_pin()) + } + _ => Err(InvalidPinTypeError), + } + } + #[inline] + fn _write(&mut self, bit: bool) -> Result<(), InvalidPinTypeError> { + match self.mode { + DynPinMode::Output(_) => { + self.regs.write_pin(bit); + Ok(()) + } + _ => Err(InvalidPinTypeError), + } + } + + #[inline] + fn _is_low(&self) -> Result { + self._read().map(|v| !v) + } + #[inline] + fn _is_high(&self) -> Result { + self._read() + } + #[inline] + fn _set_low(&mut self) -> Result<(), InvalidPinTypeError> { + self._write(false) + } + #[inline] + fn _set_high(&mut self) -> Result<(), InvalidPinTypeError> { + self._write(true) + } +} + +//================================================================================================== +// Convert between Pin and DynPin +//================================================================================================== + +impl From> for DynPin { + /// Erase the type-level information in a [`Pin`] and return a value-level + /// [`DynPin`] + #[inline] + fn from(_pin: Pin) -> Self { + // The `Pin` is consumed, so it is safe to replace it with the + // corresponding `DynPin` + unsafe { DynPin::new(I::DYN, M::DYN) } + } +} + +impl TryFrom for Pin { + type Error = InvalidPinTypeError; + + /// Try to recreate a type-level [`Pin`] from a value-level [`DynPin`] + /// + /// There is no way for the compiler to know if the conversion will be + /// successful at compile-time. We must verify the conversion at run-time + /// or refuse to perform it. + #[inline] + fn try_from(pin: DynPin) -> Result { + if pin.regs.id == I::DYN && pin.mode == M::DYN { + // The `DynPin` is consumed, so it is safe to replace it with the + // corresponding `Pin` + Ok(unsafe { Self::new() }) + } else { + Err(InvalidPinTypeError) + } + } +} + +//================================================================================================== +// Embedded HAL traits +//================================================================================================== + +impl embedded_hal::digital::ErrorType for DynPin { + type Error = InvalidPinTypeError; +} + +impl embedded_hal::digital::OutputPin for DynPin { + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + self._set_high() + } + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + self._set_low() + } +} + +impl embedded_hal::digital::InputPin for DynPin { + #[inline] + fn is_high(&mut self) -> Result { + self._is_high() + } + #[inline] + fn is_low(&mut self) -> Result { + self._is_low() + } +} + +impl embedded_hal::digital::StatefulOutputPin for DynPin { + fn is_set_high(&mut self) -> Result { + self._is_high() + } + + fn is_set_low(&mut self) -> Result { + self._is_low() + } +} diff --git a/va108xx-hal/src/gpio/mod.rs b/va108xx-hal/src/gpio/mod.rs new file mode 100644 index 0000000..b09e289 --- /dev/null +++ b/va108xx-hal/src/gpio/mod.rs @@ -0,0 +1,111 @@ +//! # API for the GPIO peripheral +//! +//! The implementation of this GPIO module is heavily based on the +//! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/index.html). +//! +//! This API provides two different submodules, [`mod@pins`] and [`dynpins`], +//! representing two different ways to handle GPIO pins. The default, [`mod@pins`], +//! is a type-level API that tracks the state of each pin at compile-time. The +//! alternative, [`dynpins`] is a type-erased, value-level API that tracks the +//! state of each pin at run-time. +//! +//! The type-level API is strongly preferred. By representing the state of each +//! pin within the type system, the compiler can detect logic errors at +//! compile-time. Furthermore, the type-level API has absolutely zero run-time +//! cost. +//! +//! If needed, [`dynpins`] can be used to erase the type-level differences +//! between pins. However, by doing so, pins must now be tracked at run-time, +//! and each pin has a non-zero memory footprint. +//! +//! ## Examples +//! +//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/blinky.rs) +//! + +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct IsMaskedError; + +macro_rules! common_reg_if_functions { + () => { + paste::paste!( + #[inline] + pub fn datamask(&self) -> bool { + self.regs.datamask() + } + + #[inline] + pub fn clear_datamask(self) -> Self { + self.regs.clear_datamask(); + self + } + + #[inline] + pub fn set_datamask(self) -> Self { + self.regs.set_datamask(); + self + } + + #[inline] + pub fn is_high_masked(&self) -> Result { + self.regs.read_pin_masked() + } + + #[inline] + pub fn is_low_masked(&self) -> Result { + self.regs.read_pin_masked().map(|v| !v) + } + + #[inline] + pub fn set_high_masked(&mut self) -> Result<(), crate::gpio::IsMaskedError> { + self.regs.write_pin_masked(true) + } + + #[inline] + pub fn set_low_masked(&mut self) -> Result<(), crate::gpio::IsMaskedError> { + self.regs.write_pin_masked(false) + } + + fn irq_enb( + &mut self, + irq_cfg: crate::IrqCfg, + syscfg: Option<&mut va108xx::Sysconfig>, + irqsel: Option<&mut va108xx::Irqsel>, + ) { + if syscfg.is_some() { + crate::clock::enable_peripheral_clock( + syscfg.unwrap(), + crate::clock::PeripheralClocks::Irqsel, + ); + } + self.regs.enable_irq(); + if let Some(irqsel) = irqsel { + if irq_cfg.route { + match self.regs.id().group { + // Set the correct interrupt number in the IRQSEL register + DynGroup::A => { + irqsel + .porta0(self.regs.id().num as usize) + .write(|w| unsafe { w.bits(irq_cfg.irq as u32) }); + } + DynGroup::B => { + irqsel + .portb0(self.regs.id().num as usize) + .write(|w| unsafe { w.bits(irq_cfg.irq as u32) }); + } + } + } + } + } + ); + }; +} + +pub mod dynpins; +pub use dynpins::*; + +pub mod pins; +pub use pins::*; + +mod reg; diff --git a/va108xx-hal/src/gpio/pins.rs b/va108xx-hal/src/gpio/pins.rs new file mode 100644 index 0000000..1dbadcd --- /dev/null +++ b/va108xx-hal/src/gpio/pins.rs @@ -0,0 +1,890 @@ +//! # Type-level module for GPIO pins +//! +//! This documentation is strongly based on the +//! [atsamd documentation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/pin/index.html). +//! +//! This module provides a type-level API for GPIO pins. It uses the type system +//! to track the state of pins at compile-time. Representing GPIO pins in this +//! manner incurs no run-time overhead. Each [`Pin`] struct is zero-sized, so +//! there is no data to copy around. Instead, real code is generated as a side +//! effect of type transformations, and the resulting assembly is nearly +//! identical to the equivalent, hand-written C. +//! +//! To track the state of pins at compile-time, this module uses traits to +//! represent [type classes] and types as instances of those type classes. For +//! example, the trait [`InputConfig`] acts as a [type-level enum] of the +//! available input configurations, and the types [`Floating`], [`PullDown`] and +//! [`PullUp`] are its type-level variants. +//! +//! Type-level [`Pin`]s are parameterized by two type-level enums, [`PinId`] and +//! [`PinMode`]. +//! +//! ``` +//! pub struct Pin +//! where +//! I: PinId, +//! M: PinMode, +//! { +//! // ... +//! } +//! ``` +//! +//! A `PinId` identifies a pin by it's group (A, B, C or D) and pin number. Each +//! `PinId` instance is named according to its datasheet identifier, e.g. +//! [`PA02`]. +//! +//! A `PinMode` represents the various pin modes. The available `PinMode` +//! variants are [`Disabled`], [`Input`], [`Interrupt`], [`Output`] and +//! [`Alternate`], each with its own corresponding configurations. +//! +//! It is not possible for users to create new instances of a [`Pin`]. Singleton +//! instances of each pin are made available to users through the [`Pins`] +//! struct. +//! +//! To create the [`Pins`] struct, users must supply the PAC +//! [`PORT`](crate::pac::PORT) peripheral. The [`Pins`] struct takes +//! ownership of the [`PORT`] and provides the corresponding pins. Each [`Pin`] +//! within the [`Pins`] struct can be moved out and used individually. +//! +//! +//! ``` +//! let mut peripherals = Peripherals::take().unwrap(); +//! let pins = Pins::new(peripherals.PORT); +//! ``` +//! +//! Pins can be converted between modes using several different methods. +//! +//! ``` +//! // Use one of the literal function names +//! let pa27 = pins.pa27.into_floating_input(); +//! // Use a generic method and one of the `PinMode` variant types +//! let pa27 = pins.pa27.into_mode::(); +//! // Specify the target type and use `From`/`Into` +//! let pa27: Pin = pins.pa27.into(); +//! ``` +//! +//! # Embedded HAL traits +//! +//! This module implements all of the embedded HAL GPIO traits for each [`Pin`] +//! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`], +//! [`ToggleableOutputPin`] and [`StatefulOutputPin`]. +//! +//! For example, you can control the logic level of an `OutputPin` like so +//! +//! ``` +//! use atsamd_hal::pac::Peripherals; +//! use atsamd_hal::gpio::Pins; +//! use crate::ehal_02::digital::v2::OutputPin; +//! +//! let mut peripherals = Peripherals::take().unwrap(); +//! let mut pins = Pins::new(peripherals.PORT); +//! pins.pa27.set_high(); +//! ``` +//! +//! # Type-level features +//! +//! This module also provides additional, type-level tools to work with GPIO +//! pins. +//! +//! The [`OptionalPinId`] and [`OptionalPin`] traits use the [`OptionalKind`] +//! pattern to act as type-level versions of [`Option`] for `PinId` and `Pin` +//! respectively. And the [`AnyPin`] trait defines an [`AnyKind`] type class +//! for all `Pin` types. +//! +//! [type classes]: crate::typelevel#type-classes +//! [type-level enum]: crate::typelevel#type-level-enum +//! [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern +//! [`AnyKind`]: crate::typelevel#anykind-trait-pattern +use super::dynpins::{DynAlternate, DynGroup, DynInput, DynOutput, DynPinId, DynPinMode}; +use super::reg::RegisterInterface; +use crate::{ + pac::{Irqsel, Porta, Portb, Sysconfig}, + typelevel::Sealed, + IrqCfg, +}; +use core::convert::Infallible; +use core::marker::PhantomData; +use core::mem::transmute; +use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin}; +use paste::paste; + +//================================================================================================== +// Errors and Definitions +//================================================================================================== + +#[derive(Debug, PartialEq, Eq)] +pub enum InterruptEdge { + HighToLow, + LowToHigh, + BothEdges, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum InterruptLevel { + Low = 0, + High = 1, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum PinState { + Low = 0, + High = 1, +} + +//================================================================================================== +// Input configuration +//================================================================================================== + +/// Type-level enum for input configurations +/// +/// The valid options are [`Floating`], [`PullDown`] and [`PullUp`]. +pub trait InputConfig: Sealed { + /// Corresponding [`DynInput`](super::DynInput) + const DYN: DynInput; +} + +pub enum Floating {} +pub enum PullDown {} +pub enum PullUp {} + +impl InputConfig for Floating { + const DYN: DynInput = DynInput::Floating; +} +impl InputConfig for PullDown { + const DYN: DynInput = DynInput::PullDown; +} +impl InputConfig for PullUp { + const DYN: DynInput = DynInput::PullUp; +} + +impl Sealed for Floating {} +impl Sealed for PullDown {} +impl Sealed for PullUp {} + +/// Type-level variant of [`PinMode`] for floating input mode +pub type InputFloating = Input; +/// Type-level variant of [`PinMode`] for pull-down input mode +pub type InputPullDown = Input; +/// Type-level variant of [`PinMode`] for pull-up input mode +pub type InputPullUp = Input; + +/// Type-level variant of [`PinMode`] for input modes +/// +/// Type `C` is one of three input configurations: [`Floating`], [`PullDown`] or +/// [`PullUp`] +pub struct Input { + cfg: PhantomData, +} + +impl Sealed for Input {} + +#[derive(Debug, PartialEq, Eq)] +pub enum FilterType { + SystemClock = 0, + DirectInputWithSynchronization = 1, + FilterOneClockCycle = 2, + FilterTwoClockCycles = 3, + FilterThreeClockCycles = 4, + FilterFourClockCycles = 5, +} + +pub use crate::clock::FilterClkSel; + +//================================================================================================== +// Output configuration +//================================================================================================== + +pub trait OutputConfig: Sealed { + const DYN: DynOutput; +} + +pub trait ReadableOutput: Sealed {} + +/// Type-level variant of [`OutputConfig`] for a push-pull configuration +pub enum PushPull {} +/// Type-level variant of [`OutputConfig`] for an open drain configuration +pub enum OpenDrain {} + +/// Type-level variant of [`OutputConfig`] for a readable push-pull configuration +pub enum ReadablePushPull {} +/// Type-level variant of [`OutputConfig`] for a readable open-drain configuration +pub enum ReadableOpenDrain {} + +impl Sealed for PushPull {} +impl Sealed for OpenDrain {} +impl Sealed for ReadableOpenDrain {} +impl Sealed for ReadablePushPull {} +impl ReadableOutput for ReadableOpenDrain {} +impl ReadableOutput for ReadablePushPull {} + +impl OutputConfig for PushPull { + const DYN: DynOutput = DynOutput::PushPull; +} +impl OutputConfig for OpenDrain { + const DYN: DynOutput = DynOutput::OpenDrain; +} +impl OutputConfig for ReadablePushPull { + const DYN: DynOutput = DynOutput::ReadablePushPull; +} +impl OutputConfig for ReadableOpenDrain { + const DYN: DynOutput = DynOutput::ReadableOpenDrain; +} + +/// Type-level variant of [`PinMode`] for output modes +/// +/// Type `C` is one of four output configurations: [`PushPull`], [`OpenDrain`] or +/// their respective readable versions +pub struct Output { + cfg: PhantomData, +} + +impl Sealed for Output {} + +/// Type-level variant of [`PinMode`] for push-pull output mode +pub type PushPullOutput = Output; +/// Type-level variant of [`PinMode`] for open drain output mode +pub type OutputOpenDrain = Output; + +pub type OutputReadablePushPull = Output; +pub type OutputReadableOpenDrain = Output; + +//================================================================================================== +// Alternate configurations +//================================================================================================== + +/// Type-level enum for alternate peripheral function configurations +pub trait AlternateConfig: Sealed { + const DYN: DynAlternate; +} + +pub enum Funsel1 {} +pub enum Funsel2 {} +pub enum Funsel3 {} + +impl AlternateConfig for Funsel1 { + const DYN: DynAlternate = DynAlternate::Sel1; +} +impl AlternateConfig for Funsel2 { + const DYN: DynAlternate = DynAlternate::Sel2; +} +impl AlternateConfig for Funsel3 { + const DYN: DynAlternate = DynAlternate::Sel3; +} + +impl Sealed for Funsel1 {} +impl Sealed for Funsel2 {} +impl Sealed for Funsel3 {} + +/// Type-level variant of [`PinMode`] for alternate peripheral functions +/// +/// Type `C` is an [`AlternateConfig`] +pub struct Alternate { + cfg: PhantomData, +} + +impl Sealed for Alternate {} + +pub type AltFunc1 = Alternate; +pub type AltFunc2 = Alternate; +pub type AltFunc3 = Alternate; + +/// Type alias for the [`PinMode`] at reset +pub type Reset = InputFloating; + +//================================================================================================== +// Pin modes +//================================================================================================== + +/// Type-level enum representing pin modes +/// +/// The valid options are [`Input`], [`Output`] and [`Alternate`]. +pub trait PinMode: Sealed { + /// Corresponding [`DynPinMode`](super::DynPinMode) + const DYN: DynPinMode; +} + +impl PinMode for Input { + const DYN: DynPinMode = DynPinMode::Input(C::DYN); +} +impl PinMode for Output { + const DYN: DynPinMode = DynPinMode::Output(C::DYN); +} +impl PinMode for Alternate { + const DYN: DynPinMode = DynPinMode::Alternate(C::DYN); +} + +//================================================================================================== +// Pin IDs +//================================================================================================== + +/// Type-level enum for pin IDs +pub trait PinId: Sealed { + /// Corresponding [`DynPinId`](super::DynPinId) + const DYN: DynPinId; +} + +macro_rules! pin_id { + ($Group:ident, $Id:ident, $NUM:literal) => { + // Need paste macro to use ident in doc attribute + paste! { + #[doc = "Pin ID representing pin " $Id] + pub enum $Id {} + impl Sealed for $Id {} + impl PinId for $Id { + const DYN: DynPinId = DynPinId { + group: DynGroup::$Group, + num: $NUM, + }; + } + } + }; +} + +//================================================================================================== +// Pin +//================================================================================================== + +/// A type-level GPIO pin, parameterized by [`PinId`] and [`PinMode`] types + +pub struct Pin { + pub(in crate::gpio) regs: Registers, + mode: PhantomData, +} + +impl Pin { + /// Create a new [`Pin`] + /// + /// # Safety + /// + /// Each [`Pin`] must be a singleton. For a given [`PinId`], there must be + /// at most one corresponding [`Pin`] in existence at any given time. + /// Violating this requirement is `unsafe`. + #[inline] + pub(crate) unsafe fn new() -> Pin { + Pin { + regs: Registers::new(), + mode: PhantomData, + } + } + + /// Convert the pin to the requested [`PinMode`] + #[inline] + pub fn into_mode(mut self) -> Pin { + // Only modify registers if we are actually changing pin mode + // This check should compile away + if N::DYN != M::DYN { + self.regs.change_mode::(); + } + // Safe because we drop the existing Pin + unsafe { Pin::new() } + } + + /// Configure the pin for function select 1. See Programmer Guide p.40 for the function table + #[inline] + pub fn into_funsel_1(self) -> Pin { + self.into_mode() + } + + /// Configure the pin for function select 2. See Programmer Guide p.40 for the function table + #[inline] + pub fn into_funsel_2(self) -> Pin { + self.into_mode() + } + + /// Configure the pin for function select 3. See Programmer Guide p.40 for the function table + #[inline] + pub fn into_funsel_3(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a floating input + #[inline] + pub fn into_floating_input(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a pulled down input + #[inline] + pub fn into_pull_down_input(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a pulled up input + #[inline] + pub fn into_pull_up_input(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a push-pull output + #[inline] + pub fn into_push_pull_output(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a readable push-pull output + #[inline] + pub fn into_readable_push_pull_output(self) -> Pin { + self.into_mode() + } + + /// Configure the pin to operate as a readable open-drain output + #[inline] + pub fn into_readable_open_drain_output(self) -> Pin { + self.into_mode() + } + + common_reg_if_functions!(); + + #[inline] + pub(crate) fn _set_high(&mut self) { + self.regs.write_pin(true) + } + + #[inline] + pub(crate) fn _set_low(&mut self) { + self.regs.write_pin(false) + } + + #[inline] + pub(crate) fn _toggle_with_toggle_reg(&mut self) { + self.regs.toggle(); + } + + #[inline] + pub(crate) fn _is_low(&self) -> bool { + !self.regs.read_pin() + } + + #[inline] + pub(crate) fn _is_high(&self) -> bool { + self.regs.read_pin() + } +} + +//============================================================================== +// AnyPin +//============================================================================== + +/// Type class for [`Pin`] types +/// +/// This trait uses the [`AnyKind`] trait pattern to create a [type class] for +/// [`Pin`] types. See the `AnyKind` documentation for more details on the +/// pattern. +/// +/// ## `v1` Compatibility +/// +/// Normally, this trait would use `Is>` as a super +/// trait. But doing so would restrict implementations to only the `v2` `Pin` +/// type in this module. To aid in backwards compatibility, we want to implement +/// `AnyPin` for the `v1` `Pin` type as well. This is possible for a few +/// reasons. First, both structs are zero-sized, so there is no meaningful +/// memory layout to begin with. And even if there were, the `v1` `Pin` type is +/// a newtype wrapper around a `v2` `Pin`, and single-field structs are +/// guaranteed to have the same layout as the field, even for `repr(Rust)`. +/// +/// [`AnyKind`]: crate::typelevel#anykind-trait-pattern +/// [type class]: crate::typelevel#type-classes +pub trait AnyPin +where + Self: Sealed, + Self: From>, + Self: Into>, + Self: AsRef>, + Self: AsMut>, +{ + /// [`PinId`] of the corresponding [`Pin`] + type Id: PinId; + /// [`PinMode`] of the corresponding [`Pin`] + type Mode: PinMode; +} + +impl Sealed for Pin +where + I: PinId, + M: PinMode, +{ +} + +impl AnyPin for Pin +where + I: PinId, + M: PinMode, +{ + type Id = I; + type Mode = M; +} + +/// Type alias to recover the specific [`Pin`] type from an implementation of +/// [`AnyPin`] +/// +/// See the [`AnyKind`] documentation for more details on the pattern. +/// +/// [`AnyKind`]: crate::typelevel#anykind-trait-pattern +pub type SpecificPin

= Pin<

::Id,

::Mode>; + +impl AsRef

for SpecificPin

{ + #[inline] + fn as_ref(&self) -> &P { + // SAFETY: This is guaranteed to be safe, because P == SpecificPin

+ // Transmuting between `v1` and `v2` `Pin` types is also safe, because + // both are zero-sized, and single-field, newtype structs are guaranteed + // to have the same layout as the field anyway, even for repr(Rust). + unsafe { transmute(self) } + } +} + +impl AsMut

for SpecificPin

{ + #[inline] + fn as_mut(&mut self) -> &mut P { + // SAFETY: This is guaranteed to be safe, because P == SpecificPin

+ // Transmuting between `v1` and `v2` `Pin` types is also safe, because + // both are zero-sized, and single-field, newtype structs are guaranteed + // to have the same layout as the field anyway, even for repr(Rust). + unsafe { transmute(self) } + } +} + +//================================================================================================== +// Additional functionality +//================================================================================================== + +impl Pin> { + pub fn interrupt_edge( + mut self, + edge_type: InterruptEdge, + irq_cfg: IrqCfg, + syscfg: Option<&mut Sysconfig>, + irqsel: Option<&mut Irqsel>, + ) -> Self { + self.regs.interrupt_edge(edge_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + self + } + + pub fn interrupt_level( + mut self, + level_type: InterruptLevel, + irq_cfg: IrqCfg, + syscfg: Option<&mut Sysconfig>, + irqsel: Option<&mut Irqsel>, + ) -> Self { + self.regs.interrupt_level(level_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + self + } +} + +impl Pin> { + /// See p.53 of the programmers guide for more information. + /// Possible delays in clock cycles: + /// - Delay 1: 1 + /// - Delay 2: 2 + /// - Delay 1 + Delay 2: 3 + #[inline] + pub fn delay(self, delay_1: bool, delay_2: bool) -> Self { + self.regs.delay(delay_1, delay_2); + self + } + + #[inline] + pub fn toggle_with_toggle_reg(&mut self) { + self._toggle_with_toggle_reg() + } + + /// See p.52 of the programmers guide for more information. + /// When configured for pulse mode, a given pin will set the non-default state for exactly + /// one clock cycle before returning to the configured default state + pub fn pulse_mode(self, enable: bool, default_state: PinState) -> Self { + self.regs.pulse_mode(enable, default_state); + self + } + + pub fn interrupt_edge( + mut self, + edge_type: InterruptEdge, + irq_cfg: IrqCfg, + syscfg: Option<&mut Sysconfig>, + irqsel: Option<&mut Irqsel>, + ) -> Self { + self.regs.interrupt_edge(edge_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + self + } + + pub fn interrupt_level( + mut self, + level_type: InterruptLevel, + irq_cfg: IrqCfg, + syscfg: Option<&mut Sysconfig>, + irqsel: Option<&mut Irqsel>, + ) -> Self { + self.regs.interrupt_level(level_type); + self.irq_enb(irq_cfg, syscfg, irqsel); + self + } +} + +impl Pin> { + /// See p.37 and p.38 of the programmers guide for more information. + #[inline] + pub fn filter_type(self, filter: FilterType, clksel: FilterClkSel) -> Self { + self.regs.filter_type(filter, clksel); + self + } +} + +//================================================================================================== +// Embedded HAL traits +//================================================================================================== + +impl embedded_hal::digital::ErrorType for Pin +where + I: PinId, + M: PinMode, +{ + type Error = Infallible; +} + +impl OutputPin for Pin> { + #[inline] + fn set_high(&mut self) -> Result<(), Self::Error> { + self._set_high(); + Ok(()) + } + + #[inline] + fn set_low(&mut self) -> Result<(), Self::Error> { + self._set_low(); + Ok(()) + } +} + +impl InputPin for Pin> +where + I: PinId, + C: InputConfig, +{ + #[inline] + fn is_high(&mut self) -> Result { + Ok(self._is_high()) + } + #[inline] + fn is_low(&mut self) -> Result { + Ok(self._is_low()) + } +} + +impl StatefulOutputPin for Pin> +where + I: PinId, + C: OutputConfig + ReadableOutput, +{ + #[inline] + fn is_set_high(&mut self) -> Result { + Ok(self._is_high()) + } + #[inline] + fn is_set_low(&mut self) -> Result { + Ok(self._is_low()) + } +} + +impl InputPin for Pin> +where + I: PinId, + C: OutputConfig + ReadableOutput, +{ + #[inline] + fn is_high(&mut self) -> Result { + Ok(self._is_high()) + } + + #[inline] + fn is_low(&mut self) -> Result { + Ok(self._is_low()) + } +} + +//================================================================================================== +// Registers +//================================================================================================== + +/// Provide a safe register interface for [`Pin`]s +/// +/// This `struct` takes ownership of a [`PinId`] and provides an API to +/// access the corresponding registers. +pub(in crate::gpio) struct Registers { + id: PhantomData, +} + +// [`Registers`] takes ownership of the [`PinId`], and [`Pin`] guarantees that +// each pin is a singleton, so this implementation is safe. +unsafe impl RegisterInterface for Registers { + #[inline] + fn id(&self) -> DynPinId { + I::DYN + } +} + +impl Registers { + /// Create a new instance of [`Registers`] + /// + /// # Safety + /// + /// Users must never create two simultaneous instances of this `struct` with + /// the same [`PinId`] + #[inline] + unsafe fn new() -> Self { + Registers { id: PhantomData } + } + + /// Provide a type-level equivalent for the + /// [`RegisterInterface::change_mode`] method. + #[inline] + pub(in crate::gpio) fn change_mode(&mut self) { + RegisterInterface::change_mode(self, M::DYN); + } +} + +//================================================================================================== +// Pin definitions +//================================================================================================== + +macro_rules! pins { + ( + $Port:ident, $PinsName:ident, $($Id:ident,)+, + ) => { + paste!( + /// Collection of all the individual [`Pin`]s for a given port (PORTA or PORTB) + pub struct $PinsName { + iocfg: Option, + port: $Port, + $( + #[doc = "Pin " $Id] + pub [<$Id:lower>]: Pin<$Id, Reset>, + )+ + } + + impl $PinsName { + /// Create a new struct containing all the Pins. Passing the IOCONFIG peripheral + /// is optional because it might be required to create pin definitions for both + /// ports. + #[inline] + pub fn new( + syscfg: &mut va108xx::Sysconfig, + iocfg: Option, + port: $Port + ) -> $PinsName { + syscfg.peripheral_clk_enable().modify(|_, w| { + w.[<$Port:lower>]().set_bit(); + w.gpio().set_bit(); + w.ioconfig().set_bit() + }); + $PinsName { + iocfg, + port, + // Safe because we only create one `Pin` per `PinId` + $( + [<$Id:lower>]: unsafe { Pin::new() }, + )+ + } + } + + /// Get the peripheral ID + /// Safety: Read-only register + pub fn get_perid() -> u32 { + let port = unsafe { &(*$Port::ptr()) }; + port.perid().read().bits() + } + + /// Consumes the Pins struct and returns the port definitions + pub fn release(self) -> (Option, $Port) { + (self.iocfg, self.port) + } + } + ); + } +} + +macro_rules! declare_pins { + ( + $Group:ident, $PinsName:ident, $Port:ident, [$(($Id:ident, $NUM:literal),)+] + ) => { + pins!($Port, $PinsName, $($Id,)+,); + $( + pin_id!($Group, $Id, $NUM); + )+ + } +} + +declare_pins!( + A, + PinsA, + Porta, + [ + (PA0, 0), + (PA1, 1), + (PA2, 2), + (PA3, 3), + (PA4, 4), + (PA5, 5), + (PA6, 6), + (PA7, 7), + (PA8, 8), + (PA9, 9), + (PA10, 10), + (PA11, 11), + (PA12, 12), + (PA13, 13), + (PA14, 14), + (PA15, 15), + (PA16, 16), + (PA17, 17), + (PA18, 18), + (PA19, 19), + (PA20, 20), + (PA21, 21), + (PA22, 22), + (PA23, 23), + (PA24, 24), + (PA25, 25), + (PA26, 26), + (PA27, 27), + (PA28, 28), + (PA29, 29), + (PA30, 30), + (PA31, 31), + ] +); + +declare_pins!( + B, + PinsB, + Portb, + [ + (PB0, 0), + (PB1, 1), + (PB2, 2), + (PB3, 3), + (PB4, 4), + (PB5, 5), + (PB6, 6), + (PB7, 7), + (PB8, 8), + (PB9, 9), + (PB10, 10), + (PB11, 11), + (PB12, 12), + (PB13, 13), + (PB14, 14), + (PB15, 15), + (PB16, 16), + (PB17, 17), + (PB18, 18), + (PB19, 19), + (PB20, 20), + (PB21, 21), + (PB22, 22), + (PB23, 23), + ] +); diff --git a/va108xx-hal/src/gpio/reg.rs b/va108xx-hal/src/gpio/reg.rs new file mode 100644 index 0000000..9e2abff --- /dev/null +++ b/va108xx-hal/src/gpio/reg.rs @@ -0,0 +1,382 @@ +use super::dynpins::{self, DynGroup, DynPinId, DynPinMode}; +use super::pins::{FilterType, InterruptEdge, InterruptLevel, PinState}; +use super::IsMaskedError; +use crate::clock::FilterClkSel; +use va108xx::{ioconfig, porta}; + +/// Type definition to avoid confusion: These register blocks are identical +type PortRegisterBlock = porta::RegisterBlock; + +//================================================================================================== +// ModeFields +//================================================================================================== + +/// Collect all fields needed to set the [`PinMode`](super::PinMode) +#[derive(Default)] +struct ModeFields { + dir: bool, + opendrn: bool, + pull_en: bool, + /// true for pullup, false for pulldown + pull_dir: bool, + funsel: u8, + enb_input: bool, +} + +impl From for ModeFields { + #[inline] + fn from(mode: DynPinMode) -> Self { + let mut fields = Self::default(); + use DynPinMode::*; + match mode { + Input(config) => { + use dynpins::DynInput::*; + fields.dir = false; + match config { + Floating => (), + PullUp => { + fields.pull_en = true; + fields.pull_dir = true; + } + PullDown => { + fields.pull_en = true; + } + } + } + Output(config) => { + use dynpins::DynOutput::*; + fields.dir = true; + match config { + PushPull => (), + OpenDrain => { + fields.opendrn = true; + } + ReadableOpenDrain => { + fields.enb_input = true; + fields.opendrn = true; + } + ReadablePushPull => { + fields.enb_input = true; + } + } + } + Alternate(config) => { + fields.funsel = config as u8; + } + } + fields + } +} + +//================================================================================================== +// Register Interface +//================================================================================================== + +pub type PortReg = ioconfig::Porta; +/* +pub type IocfgPort = ioconfig::Porta; +#[repr(C)] +pub(super) struct IocfgPortGroup { + port: [IocfgPort; 32], +} +*/ + +/// Provide a safe register interface for pin objects +/// +/// [`PORTA`] and [`PORTB`], like every PAC `struct`, is [`Send`] but not [`Sync`], because it +/// points to a `RegisterBlock` of `VolatileCell`s. Unfortunately, such an +/// interface is quite restrictive. Instead, it would be ideal if we could split +/// the [`PORT`] into independent pins that are both [`Send`] and [`Sync`]. +/// +/// [`PORT`] is a single, zero-sized marker `struct` that provides access to +/// every [`PORT`] register. Instead, we would like to create zero-sized marker +/// `struct`s for every pin, where each pin is only allowed to control its own +/// registers. Furthermore, each pin `struct` should be a singleton, so that +/// exclusive access to the `struct` also guarantees exclusive access to the +/// corresponding registers. Finally, the pin `struct`s should not have any +/// interior mutability. Together, these requirements would allow the pin +/// `struct`s to be both [`Send`] and [`Sync`]. +/// +/// This trait creates a safe API for accomplishing these goals. Implementers +/// supply a pin ID through the [`id`] function. The remaining functions provide +/// a safe API for accessing the registers associated with that pin ID. Any +/// modification of the registers requires `&mut self`, which destroys interior +/// mutability. +/// +/// # Safety +/// +/// Users should only implement the [`id`] function. No default function +/// implementations should be overridden. The implementing type must also have +/// "control" over the corresponding pin ID, i.e. it must guarantee that a each +/// pin ID is a singleton. +/// +/// [`id`]: Self::id +pub(super) unsafe trait RegisterInterface { + /// Provide a [`DynPinId`] identifying the set of registers controlled by + /// this type. + fn id(&self) -> DynPinId; + + const PORTA: *const PortRegisterBlock = va108xx::Porta::ptr(); + const PORTB: *const PortRegisterBlock = va108xx::Portb::ptr(); + + /// Change the pin mode + #[inline] + fn change_mode(&mut self, mode: DynPinMode) { + let ModeFields { + dir, + funsel, + opendrn, + pull_dir, + pull_en, + enb_input, + } = mode.into(); + let (portreg, iocfg) = (self.port_reg(), self.iocfg_port()); + iocfg.write(|w| { + w.opendrn().bit(opendrn); + w.pen().bit(pull_en); + w.plevel().bit(pull_dir); + w.iewo().bit(enb_input); + unsafe { w.funsel().bits(funsel) } + }); + let mask = self.mask_32(); + unsafe { + if dir { + portreg.dir().modify(|r, w| w.bits(r.bits() | mask)); + // Clear output + portreg.clrout().write(|w| w.bits(mask)); + } else { + portreg.dir().modify(|r, w| w.bits(r.bits() & !mask)); + } + } + } + + #[inline] + fn port_reg(&self) -> &PortRegisterBlock { + match self.id().group { + DynGroup::A => unsafe { &(*Self::PORTA) }, + DynGroup::B => unsafe { &(*Self::PORTB) }, + } + } + fn iocfg_port(&self) -> &PortReg { + let ioconfig = unsafe { va108xx::Ioconfig::ptr().as_ref().unwrap() }; + match self.id().group { + DynGroup::A => ioconfig.porta(self.id().num as usize), + DynGroup::B => ioconfig.portb0(self.id().num as usize), + } + } + + #[inline] + fn mask_32(&self) -> u32 { + 1 << self.id().num + } + + #[inline] + fn enable_irq(&self) { + self.port_reg() + .irq_enb() + .modify(|r, w| unsafe { w.bits(r.bits() | self.mask_32()) }); + } + + #[inline] + /// Read the logic level of an output pin + fn read_pin(&self) -> bool { + let portreg = self.port_reg(); + ((portreg.datainraw().read().bits() >> self.id().num) & 0x01) == 1 + } + + // Get DATAMASK bit for this particular pin + #[inline(always)] + fn datamask(&self) -> bool { + let portreg = self.port_reg(); + (portreg.datamask().read().bits() >> self.id().num) == 1 + } + + /// Read a pin but use the masked version but check whether the datamask for the pin is + /// cleared as well + #[inline(always)] + fn read_pin_masked(&self) -> Result { + if !self.datamask() { + Err(IsMaskedError) + } else { + Ok(((self.port_reg().datain().read().bits() >> self.id().num) & 0x01) == 1) + } + } + + /// Write the logic level of an output pin + #[inline(always)] + fn write_pin(&mut self, bit: bool) { + // Safety: SETOUT is a "mask" register, and we only write the bit for + // this pin ID + unsafe { + if bit { + self.port_reg().setout().write(|w| w.bits(self.mask_32())); + } else { + self.port_reg().clrout().write(|w| w.bits(self.mask_32())); + } + } + } + + /// Write the logic level of an output pin but check whether the datamask for the pin is + /// cleared as well + #[inline] + fn write_pin_masked(&mut self, bit: bool) -> Result<(), IsMaskedError> { + if !self.datamask() { + Err(IsMaskedError) + } else { + // Safety: SETOUT is a "mask" register, and we only write the bit for + // this pin ID + unsafe { + if bit { + self.port_reg().setout().write(|w| w.bits(self.mask_32())); + } else { + self.port_reg().clrout().write(|w| w.bits(self.mask_32())); + } + Ok(()) + } + } + } + + /// Toggle the logic level of an output pin + #[inline(always)] + fn toggle(&mut self) { + // Safety: TOGOUT is a "mask" register, and we only write the bit for + // this pin ID + unsafe { self.port_reg().togout().write(|w| w.bits(self.mask_32())) }; + } + + /// Only useful for interrupt pins. Configure whether to use edges or level as interrupt soure + /// When using edge mode, it is possible to generate interrupts on both edges as well + #[inline] + fn interrupt_edge(&mut self, edge_type: InterruptEdge) { + unsafe { + self.port_reg() + .irq_sen() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + match edge_type { + InterruptEdge::HighToLow => { + self.port_reg() + .irq_evt() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } + InterruptEdge::LowToHigh => { + self.port_reg() + .irq_evt() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } + InterruptEdge::BothEdges => { + self.port_reg() + .irq_edge() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } + } + } + } + + /// Configure which edge or level type triggers an interrupt + #[inline] + fn interrupt_level(&mut self, level: InterruptLevel) { + unsafe { + self.port_reg() + .irq_sen() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + if level == InterruptLevel::Low { + self.port_reg() + .irq_evt() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } else { + self.port_reg() + .irq_evt() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } + } + } + + /// Only useful for input pins + #[inline] + fn filter_type(&self, filter: FilterType, clksel: FilterClkSel) { + self.iocfg_port().modify(|_, w| { + // Safety: Only write to register for this Pin ID + unsafe { + w.flttype().bits(filter as u8); + w.fltclk().bits(clksel as u8) + } + }); + } + + /// Set DATAMASK bit for this particular pin. 1 is the default + /// state of the bit and allows access of the corresponding bit + #[inline(always)] + fn set_datamask(&self) { + let portreg = self.port_reg(); + unsafe { + portreg + .datamask() + .modify(|r, w| w.bits(r.bits() | self.mask_32())) + } + } + + /// Clear DATAMASK bit for this particular pin. This prevents access + /// of the corresponding bit for output and input operations + #[inline(always)] + fn clear_datamask(&self) { + let portreg = self.port_reg(); + unsafe { + portreg + .datamask() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())) + } + } + + /// Only useful for output pins + /// See p.52 of the programmers guide for more information. + /// When configured for pulse mode, a given pin will set the non-default state for exactly + /// one clock cycle before returning to the configured default state + fn pulse_mode(&self, enable: bool, default_state: PinState) { + let portreg = self.port_reg(); + unsafe { + if enable { + portreg + .pulse() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } else { + portreg + .pulse() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } + if default_state == PinState::Low { + portreg + .pulsebase() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } else { + portreg + .pulsebase() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } + } + } + + /// Only useful for output pins + fn delay(&self, delay_1: bool, delay_2: bool) { + let portreg = self.port_reg(); + unsafe { + if delay_1 { + portreg + .delay1() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } else { + portreg + .delay1() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } + if delay_2 { + portreg + .delay2() + .modify(|r, w| w.bits(r.bits() | self.mask_32())); + } else { + portreg + .delay2() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())); + } + } + } +} diff --git a/va108xx-hal/src/i2c.rs b/va108xx-hal/src/i2c.rs new file mode 100644 index 0000000..88d1d6d --- /dev/null +++ b/va108xx-hal/src/i2c.rs @@ -0,0 +1,878 @@ +//! API for the I2C peripheral +//! +//! ## Examples +//! +//! - [REB1 I2C temperature sensor example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/adt75-temp-sensor.rs) +use crate::{ + clock::{enable_peripheral_clock, PeripheralClocks}, + pac, + time::Hertz, + typelevel::Sealed, +}; +use core::marker::PhantomData; +use embedded_hal::i2c::{self, Operation, SevenBitAddress, TenBitAddress}; + +//================================================================================================== +// Defintions +//================================================================================================== + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum FifoEmptyMode { + Stall = 0, + EndTransaction = 1, +} + +#[derive(Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Error { + InvalidTimingParams, + ArbitrationLost, + NackAddr, + /// Data not acknowledged in write operation + NackData, + /// Not enough data received in read operation + InsufficientDataReceived, + /// Number of bytes in transfer too large (larger than 0x7fe) + DataTooLarge, + WrongAddrMode, +} + +impl embedded_hal::i2c::Error for Error { + fn kind(&self) -> embedded_hal::i2c::ErrorKind { + match self { + Error::ArbitrationLost => embedded_hal::i2c::ErrorKind::ArbitrationLoss, + Error::NackAddr => { + embedded_hal::i2c::ErrorKind::NoAcknowledge(i2c::NoAcknowledgeSource::Address) + } + Error::NackData => { + embedded_hal::i2c::ErrorKind::NoAcknowledge(i2c::NoAcknowledgeSource::Data) + } + Error::DataTooLarge + | Error::WrongAddrMode + | Error::InsufficientDataReceived + | Error::InvalidTimingParams => embedded_hal::i2c::ErrorKind::Other, + } + } +} + +#[derive(Debug, PartialEq, Copy, Clone)] +enum I2cCmd { + Start = 0b00, + Stop = 0b10, + StartWithStop = 0b11, + Cancel = 0b100, +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum I2cSpeed { + Regular100khz = 0, + Fast400khz = 1, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum I2cDirection { + Send = 0, + Read = 1, +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum I2cAddress { + Regular(u8), + TenBit(u16), +} + +//================================================================================================== +// Config +//================================================================================================== + +pub struct TrTfThighTlow(u8, u8, u8, u8); +pub struct TsuStoTsuStaThdStaTBuf(u8, u8, u8, u8); + +pub struct TimingCfg { + // 4 bit max width + tr: u8, + // 4 bit max width + tf: u8, + // 4 bit max width + thigh: u8, + // 4 bit max width + tlow: u8, + // 4 bit max width + tsu_sto: u8, + // 4 bit max width + tsu_sta: u8, + // 4 bit max width + thd_sta: u8, + // 4 bit max width + tbuf: u8, +} + +impl TimingCfg { + pub fn new( + first_16_bits: TrTfThighTlow, + second_16_bits: TsuStoTsuStaThdStaTBuf, + ) -> Result { + if first_16_bits.0 > 0xf + || first_16_bits.1 > 0xf + || first_16_bits.2 > 0xf + || first_16_bits.3 > 0xf + || second_16_bits.0 > 0xf + || second_16_bits.1 > 0xf + || second_16_bits.2 > 0xf + || second_16_bits.3 > 0xf + { + return Err(Error::InvalidTimingParams); + } + Ok(TimingCfg { + tr: first_16_bits.0, + tf: first_16_bits.1, + thigh: first_16_bits.2, + tlow: first_16_bits.3, + tsu_sto: second_16_bits.0, + tsu_sta: second_16_bits.1, + thd_sta: second_16_bits.2, + tbuf: second_16_bits.3, + }) + } + + pub fn reg(&self) -> u32 { + (self.tbuf as u32) << 28 + | (self.thd_sta as u32) << 24 + | (self.tsu_sta as u32) << 20 + | (self.tsu_sto as u32) << 16 + | (self.tlow as u32) << 12 + | (self.thigh as u32) << 8 + | (self.tf as u32) << 4 + | (self.tr as u32) + } +} + +impl Default for TimingCfg { + fn default() -> Self { + TimingCfg { + tr: 0x02, + tf: 0x01, + thigh: 0x08, + tlow: 0x09, + tsu_sto: 0x8, + tsu_sta: 0x0a, + thd_sta: 0x8, + tbuf: 0xa, + } + } +} + +pub struct MasterConfig { + pub tx_fe_mode: FifoEmptyMode, + pub rx_fe_mode: FifoEmptyMode, + /// Enable the analog delay glitch filter + pub alg_filt: bool, + /// Enable the digital glitch filter + pub dlg_filt: bool, + pub tm_cfg: Option, + // Loopback mode + // lbm: bool, +} + +impl Default for MasterConfig { + fn default() -> Self { + MasterConfig { + tx_fe_mode: FifoEmptyMode::Stall, + rx_fe_mode: FifoEmptyMode::Stall, + alg_filt: false, + dlg_filt: false, + tm_cfg: None, + } + } +} + +impl Sealed for MasterConfig {} + +pub struct SlaveConfig { + pub tx_fe_mode: FifoEmptyMode, + pub rx_fe_mode: FifoEmptyMode, + /// Maximum number of words before issuing a negative acknowledge. + /// Range should be 0 to 0x7fe. Setting the value to 0x7ff has the same effect as not setting + /// the enable bit since RXCOUNT stops counting at 0x7fe. + pub max_words: Option, + /// A received address is compared to the ADDRESS register (addr) using the address mask + /// (addr_mask). Those bits with a 1 in the address mask must match for there to be an address + /// match + pub addr: I2cAddress, + /// The default address mask will be 0x3ff to only allow full matches + pub addr_mask: Option, + /// Optionally specify a second I2C address the slave interface responds to + pub addr_b: Option, + pub addr_b_mask: Option, +} + +impl SlaveConfig { + /// Build a default slave config given a specified slave address to respond to + pub fn new(addr: I2cAddress) -> Self { + SlaveConfig { + tx_fe_mode: FifoEmptyMode::Stall, + rx_fe_mode: FifoEmptyMode::Stall, + max_words: None, + addr, + addr_mask: None, + addr_b: None, + addr_b_mask: None, + } + } +} + +impl Sealed for SlaveConfig {} + +//================================================================================================== +// I2C Base +//================================================================================================== + +pub struct I2cBase { + i2c: I2C, + sys_clk: Hertz, +} + +impl I2cBase { + #[inline] + fn unwrap_addr(addr: I2cAddress) -> (u16, u32) { + match addr { + I2cAddress::Regular(addr) => (addr as u16, 0 << 15), + I2cAddress::TenBit(addr) => (addr, 1 << 15), + } + } +} + +macro_rules! i2c_base { + ($($I2CX:path: ($i2cx:ident, $clk_enb:path),)+) => { + $( + impl I2cBase<$I2CX> { + pub fn $i2cx( + i2c: $I2CX, + sys_clk: impl Into, + speed_mode: I2cSpeed, + ms_cfg: Option<&MasterConfig>, + sl_cfg: Option<&SlaveConfig>, + sys_cfg: Option<&mut va108xx::Sysconfig>, + ) -> Self { + if let Some(sys_cfg) = sys_cfg { + enable_peripheral_clock(sys_cfg, $clk_enb); + } + let mut i2c_base = I2cBase { + i2c, + sys_clk: sys_clk.into(), + }; + if let Some(ms_cfg) = ms_cfg { + i2c_base.cfg_master(ms_cfg); + } + + if let Some(sl_cfg) = sl_cfg { + i2c_base.cfg_slave(sl_cfg); + } + i2c_base.cfg_clk_scale(speed_mode); + i2c_base + } + + fn cfg_master(&mut self, ms_cfg: &MasterConfig) { + let (txfemd, rxfemd) = match (ms_cfg.tx_fe_mode, ms_cfg.rx_fe_mode) { + (FifoEmptyMode::Stall, FifoEmptyMode::Stall) => (false, false), + (FifoEmptyMode::Stall, FifoEmptyMode::EndTransaction) => (false, true), + (FifoEmptyMode::EndTransaction, FifoEmptyMode::Stall) => (true, false), + (FifoEmptyMode::EndTransaction, FifoEmptyMode::EndTransaction) => (true, true), + }; + self.i2c.ctrl().modify(|_, w| { + w.txfemd().bit(txfemd); + w.rxffmd().bit(rxfemd); + w.dlgfilter().bit(ms_cfg.dlg_filt); + w.algfilter().bit(ms_cfg.alg_filt) + }); + if let Some(ref tm_cfg) = ms_cfg.tm_cfg { + self.i2c.tmconfig().write(|w| unsafe { w.bits(tm_cfg.reg()) }); + } + self.i2c.fifo_clr().write(|w| { + w.rxfifo().set_bit(); + w.txfifo().set_bit() + }); + } + + fn cfg_slave(&mut self, sl_cfg: &SlaveConfig) { + let (txfemd, rxfemd) = match (sl_cfg.tx_fe_mode, sl_cfg.rx_fe_mode) { + (FifoEmptyMode::Stall, FifoEmptyMode::Stall) => (false, false), + (FifoEmptyMode::Stall, FifoEmptyMode::EndTransaction) => (false, true), + (FifoEmptyMode::EndTransaction, FifoEmptyMode::Stall) => (true, false), + (FifoEmptyMode::EndTransaction, FifoEmptyMode::EndTransaction) => (true, true), + }; + self.i2c.s0_ctrl().modify(|_, w| { + w.txfemd().bit(txfemd); + w.rxffmd().bit(rxfemd) + }); + self.i2c.s0_fifo_clr().write(|w| { + w.rxfifo().set_bit(); + w.txfifo().set_bit() + }); + let max_words = sl_cfg.max_words; + if let Some(max_words) = max_words { + self.i2c + .s0_maxwords() + .write(|w| unsafe { w.bits(1 << 31 | max_words as u32) }); + } + let (addr, addr_mode_mask) = Self::unwrap_addr(sl_cfg.addr); + // The first bit is the read/write value. Normally, both read and write are matched + // using the RWMASK bit of the address mask register + self.i2c + .s0_address() + .write(|w| unsafe { w.bits((addr << 1) as u32 | addr_mode_mask) }); + if let Some(addr_mask) = sl_cfg.addr_mask { + self.i2c + .s0_addressmask() + .write(|w| unsafe { w.bits((addr_mask << 1) as u32) }); + } + if let Some(addr_b) = sl_cfg.addr_b { + let (addr, addr_mode_mask) = Self::unwrap_addr(addr_b); + self.i2c + .s0_addressb() + .write(|w| unsafe { w.bits((addr << 1) as u32 | addr_mode_mask) }) + } + if let Some(addr_b_mask) = sl_cfg.addr_b_mask { + self.i2c + .s0_addressmaskb() + .write(|w| unsafe { w.bits((addr_b_mask << 1) as u32) }) + } + } + + #[inline] + pub fn filters(&mut self, digital_filt: bool, analog_filt: bool) { + self.i2c.ctrl().modify(|_, w| { + w.dlgfilter().bit(digital_filt); + w.algfilter().bit(analog_filt) + }); + } + + #[inline] + pub fn fifo_empty_mode(&mut self, rx: FifoEmptyMode, tx: FifoEmptyMode) { + self.i2c.ctrl().modify(|_, w| { + w.txfemd().bit(tx as u8 != 0); + w.rxffmd().bit(rx as u8 != 0) + }); + } + + fn calc_clk_div(&self, speed_mode: I2cSpeed) -> u8 { + if speed_mode == I2cSpeed::Regular100khz { + ((self.sys_clk.raw() / (u32::pow(10, 5) * 20)) - 1) as u8 + } else { + (((10 * self.sys_clk.raw()) / u32::pow(10, 8)) - 1) as u8 + } + } + + /// Configures the clock scale for a given speed mode setting + pub fn cfg_clk_scale(&mut self, speed_mode: I2cSpeed) { + self.i2c.clkscale().write(|w| unsafe { + w.bits((speed_mode as u32) << 31 | self.calc_clk_div(speed_mode) as u32) + }); + } + + pub fn load_address(&mut self, addr: u16) { + // Load address + self.i2c + .address() + .write(|w| unsafe { w.bits((addr << 1) as u32) }); + } + + #[inline] + fn stop_cmd(&mut self) { + self.i2c + .cmd() + .write(|w| unsafe { w.bits(I2cCmd::Stop as u32) }); + } + } + )+ + } +} + +// Unique mode to use the loopback functionality +// pub struct I2cLoopback { +// i2c_base: I2cBase, +// master_cfg: MasterConfig, +// slave_cfg: SlaveConfig, +// } + +i2c_base!( + pac::I2ca: (i2ca, PeripheralClocks::I2c0), + pac::I2cb: (i2cb, PeripheralClocks::I2c1), +); + +//================================================================================================== +// I2C Master +//================================================================================================== + +pub struct I2cMaster { + i2c_base: I2cBase, + _addr: PhantomData, +} + +macro_rules! i2c_master { + ($($I2CX:path: ($i2cx:ident, $clk_enb:path),)+) => { + $( + impl I2cMaster<$I2CX, ADDR> { + pub fn $i2cx( + i2c: $I2CX, + cfg: MasterConfig, + sys_clk: impl Into + Copy, + speed_mode: I2cSpeed, + sys_cfg: Option<&mut pac::Sysconfig>, + ) -> Self { + I2cMaster { + i2c_base: I2cBase::$i2cx( + i2c, + sys_clk, + speed_mode, + Some(&cfg), + None, + sys_cfg + ), + _addr: PhantomData, + } + .enable_master() + } + + #[inline] + pub fn cancel_transfer(&self) { + self.i2c_base + .i2c + .cmd() + .write(|w| unsafe { w.bits(I2cCmd::Cancel as u32) }); + } + + #[inline] + pub fn clear_tx_fifo(&self) { + self.i2c_base.i2c.fifo_clr().write(|w| w.txfifo().set_bit()); + } + + #[inline] + pub fn clear_rx_fifo(&self) { + self.i2c_base.i2c.fifo_clr().write(|w| w.rxfifo().set_bit()); + } + + #[inline] + pub fn enable_master(self) -> Self { + self.i2c_base.i2c.ctrl().modify(|_, w| w.enable().set_bit()); + self + } + + #[inline] + pub fn disable_master(self) -> Self { + self.i2c_base.i2c.ctrl().modify(|_, w| w.enable().clear_bit()); + self + } + + #[inline(always)] + fn load_fifo(&self, word: u8) { + self.i2c_base + .i2c + .data() + .write(|w| unsafe { w.bits(word as u32) }); + } + + #[inline(always)] + fn read_fifo(&self) -> u8 { + self.i2c_base.i2c.data().read().bits() as u8 + } + + fn error_handler_write(&mut self, init_cmd: &I2cCmd) { + self.clear_tx_fifo(); + if *init_cmd == I2cCmd::Start { + self.i2c_base.stop_cmd() + } + } + + fn write_base( + &mut self, + addr: I2cAddress, + init_cmd: I2cCmd, + bytes: impl IntoIterator, + ) -> Result<(), Error> { + let mut iter = bytes.into_iter(); + // Load address + let (addr, addr_mode_bit) = I2cBase::<$I2CX>::unwrap_addr(addr); + self.i2c_base.i2c.address().write(|w| unsafe { + w.bits(I2cDirection::Send as u32 | (addr << 1) as u32 | addr_mode_bit) + }); + + self.i2c_base + .i2c + .cmd() + .write(|w| unsafe { w.bits(init_cmd as u32) }); + let mut load_if_next_available = || { + if let Some(next_byte) = iter.next() { + self.load_fifo(next_byte); + } + }; + loop { + let status_reader = self.i2c_base.i2c.status().read(); + if status_reader.arblost().bit_is_set() { + self.error_handler_write(&init_cmd); + return Err(Error::ArbitrationLost); + } else if status_reader.nackaddr().bit_is_set() { + self.error_handler_write(&init_cmd); + return Err(Error::NackAddr); + } else if status_reader.nackdata().bit_is_set() { + self.error_handler_write(&init_cmd); + return Err(Error::NackData); + } else if status_reader.idle().bit_is_set() { + return Ok(()); + } else { + while !status_reader.txnfull().bit_is_set() { + load_if_next_available(); + } + } + } + } + + fn write_from_buffer( + &mut self, + init_cmd: I2cCmd, + addr: I2cAddress, + output: &[u8], + ) -> Result<(), Error> { + let len = output.len(); + // It should theoretically possible to transfer larger data sizes by tracking + // the number of sent words and setting it to 0x7fe as soon as only that many + // bytes are remaining. However, large transfer like this are not common. This + // feature will therefore not be supported for now. + if len > 0x7fe { + return Err(Error::DataTooLarge); + } + // Load number of words + self.i2c_base + .i2c + .words() + .write(|w| unsafe { w.bits(len as u32) }); + let mut bytes = output.iter(); + // FIFO has a depth of 16. We load slightly above the trigger level + // but not all of it because the transaction might fail immediately + const FILL_DEPTH: usize = 12; + + // load the FIFO + for _ in 0..core::cmp::min(FILL_DEPTH, len) { + self.load_fifo(*bytes.next().unwrap()); + } + + self.write_base(addr, init_cmd, output.iter().cloned()) + } + + fn read_internal(&mut self, addr: I2cAddress, buffer: &mut [u8]) -> Result<(), Error> { + let len = buffer.len(); + // It should theoretically possible to transfer larger data sizes by tracking + // the number of sent words and setting it to 0x7fe as soon as only that many + // bytes are remaining. However, large transfer like this are not common. This + // feature will therefore not be supported for now. + if len > 0x7fe { + return Err(Error::DataTooLarge); + } + // Clear the receive FIFO + self.clear_rx_fifo(); + + // Load number of words + self.i2c_base + .i2c + .words() + .write(|w| unsafe { w.bits(len as u32) }); + let (addr, addr_mode_bit) = match addr { + I2cAddress::Regular(addr) => (addr as u16, 0 << 15), + I2cAddress::TenBit(addr) => (addr, 1 << 15), + }; + // Load address + self.i2c_base.i2c.address().write(|w| unsafe { + w.bits(I2cDirection::Read as u32 | (addr << 1) as u32 | addr_mode_bit) + }); + + let mut buf_iter = buffer.iter_mut(); + let mut read_bytes = 0; + // Start receive transfer + self.i2c_base + .i2c + .cmd() + .write(|w| unsafe { w.bits(I2cCmd::StartWithStop as u32) }); + let mut read_if_next_available = || { + if let Some(next_byte) = buf_iter.next() { + *next_byte = self.read_fifo(); + } + }; + loop { + let status_reader = self.i2c_base.i2c.status().read(); + if status_reader.arblost().bit_is_set() { + self.clear_rx_fifo(); + return Err(Error::ArbitrationLost); + } else if status_reader.nackaddr().bit_is_set() { + self.clear_rx_fifo(); + return Err(Error::NackAddr); + } else if status_reader.idle().bit_is_set() { + if read_bytes != len { + return Err(Error::InsufficientDataReceived); + } + return Ok(()); + } else if status_reader.rxnempty().bit_is_set() { + read_if_next_available(); + read_bytes += 1; + } + } + } + } + + //====================================================================================== + // Embedded HAL I2C implementations + //====================================================================================== + + impl embedded_hal::i2c::ErrorType for I2cMaster<$I2CX, SevenBitAddress> { + type Error = Error; + } + impl embedded_hal::i2c::I2c for I2cMaster<$I2CX, SevenBitAddress> { + fn transaction( + &mut self, + address: SevenBitAddress, + operations: &mut [Operation<'_>], + ) -> Result<(), Self::Error> { + for operation in operations { + match operation { + Operation::Read(buf) => self.read_internal(I2cAddress::Regular(address), buf)?, + Operation::Write(buf) => self.write_from_buffer( + I2cCmd::StartWithStop, + I2cAddress::Regular(address), + buf, + )?, + } + } + Ok(()) + } + } + + impl embedded_hal::i2c::ErrorType for I2cMaster<$I2CX, TenBitAddress> { + type Error = Error; + } + impl embedded_hal::i2c::I2c for I2cMaster<$I2CX, TenBitAddress> { + fn transaction( + &mut self, + address: TenBitAddress, + operations: &mut [Operation<'_>], + ) -> Result<(), Self::Error> { + for operation in operations { + match operation { + Operation::Read(buf) => self.read_internal(I2cAddress::TenBit(address), buf)?, + Operation::Write(buf) => self.write_from_buffer( + I2cCmd::StartWithStop, + I2cAddress::TenBit(address), + buf, + )?, + } + } + Ok(()) + } + } + )+ + } +} + +i2c_master!( + pac::I2ca: (i2ca, PeripheralClocks::I2c0), + pac::I2cb: (i2cb, PeripheralClocks::I2c1), +); + +//================================================================================================== +// I2C Slave +//================================================================================================== + +pub struct I2cSlave { + i2c_base: I2cBase, + _addr: PhantomData, +} + +macro_rules! i2c_slave { + ($($I2CX:path: ($i2cx:ident, $i2cx_slave:ident),)+) => { + $( + impl I2cSlave<$I2CX, ADDR> { + fn $i2cx_slave( + i2c: $I2CX, + cfg: SlaveConfig, + sys_clk: impl Into, + speed_mode: I2cSpeed, + sys_cfg: Option<&mut pac::Sysconfig>, + ) -> Self { + I2cSlave { + i2c_base: I2cBase::$i2cx( + i2c, + sys_clk, + speed_mode, + None, + Some(&cfg), + sys_cfg + ), + _addr: PhantomData, + } + .enable_slave() + } + + #[inline] + pub fn enable_slave(self) -> Self { + self.i2c_base + .i2c + .s0_ctrl() + .modify(|_, w| w.enable().set_bit()); + self + } + + #[inline] + pub fn disable_slave(self) -> Self { + self.i2c_base + .i2c + .s0_ctrl() + .modify(|_, w| w.enable().clear_bit()); + self + } + + #[inline(always)] + fn load_fifo(&self, word: u8) { + self.i2c_base + .i2c + .s0_data() + .write(|w| unsafe { w.bits(word as u32) }); + } + + #[inline(always)] + fn read_fifo(&self) -> u8 { + self.i2c_base.i2c.s0_data().read().bits() as u8 + } + + #[inline] + fn clear_tx_fifo(&self) { + self.i2c_base + .i2c + .s0_fifo_clr() + .write(|w| w.txfifo().set_bit()); + } + + #[inline] + fn clear_rx_fifo(&self) { + self.i2c_base + .i2c + .s0_fifo_clr() + .write(|w| w.rxfifo().set_bit()); + } + + /// Get the last address that was matched by the slave control and the corresponding + /// master direction + pub fn last_address(&self) -> (I2cDirection, u32) { + let bits = self.i2c_base.i2c.s0_lastaddress().read().bits(); + match bits & 0x01 { + 0 => (I2cDirection::Send, bits >> 1), + 1 => (I2cDirection::Read, bits >> 1), + _ => (I2cDirection::Send, bits >> 1), + } + } + + pub fn write(&mut self, output: &[u8]) -> Result<(), Error> { + let len = output.len(); + // It should theoretically possible to transfer larger data sizes by tracking + // the number of sent words and setting it to 0x7fe as soon as only that many + // bytes are remaining. However, large transfer like this are not common. This + // feature will therefore not be supported for now. + if len > 0x7fe { + return Err(Error::DataTooLarge); + } + let mut bytes = output.iter(); + // FIFO has a depth of 16. We load slightly above the trigger level + // but not all of it because the transaction might fail immediately + const FILL_DEPTH: usize = 12; + + // load the FIFO + for _ in 0..core::cmp::min(FILL_DEPTH, len) { + self.load_fifo(*bytes.next().unwrap()); + } + + let status_reader = self.i2c_base.i2c.s0_status().read(); + let mut load_if_next_available = || { + if let Some(next_byte) = bytes.next() { + self.load_fifo(*next_byte); + } + }; + loop { + if status_reader.nackdata().bit_is_set() { + self.clear_tx_fifo(); + return Err(Error::NackData); + } else if status_reader.idle().bit_is_set() { + return Ok(()); + } else { + while !status_reader.txnfull().bit_is_set() { + load_if_next_available(); + } + } + } + } + + pub fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { + let len = buffer.len(); + // It should theoretically possible to transfer larger data sizes by tracking + // the number of sent words and setting it to 0x7fe as soon as only that many + // bytes are remaining. However, large transfer like this are not common. This + // feature will therefore not be supported for now. + if len > 0x7fe { + return Err(Error::DataTooLarge); + } + // Clear the receive FIFO + self.clear_rx_fifo(); + + let mut buf_iter = buffer.iter_mut(); + let mut read_bytes = 0; + let mut read_if_next_available = || { + if let Some(next_byte) = buf_iter.next() { + *next_byte = self.read_fifo(); + } + }; + loop { + let status_reader = self.i2c_base.i2c.s0_status().read(); + if status_reader.idle().bit_is_set() { + if read_bytes != len { + return Err(Error::InsufficientDataReceived); + } + return Ok(()); + } else if status_reader.rxnempty().bit_is_set() { + read_bytes += 1; + read_if_next_available(); + } + } + } + } + + + impl I2cSlave<$I2CX, SevenBitAddress> { + /// Create a new I2C slave for seven bit addresses + /// + /// Returns a [`Error::WrongAddrMode`] error if a ten bit address is passed + pub fn i2ca( + i2c: $I2CX, + cfg: SlaveConfig, + sys_clk: impl Into, + speed_mode: I2cSpeed, + sys_cfg: Option<&mut pac::Sysconfig>, + ) -> Result { + if let I2cAddress::TenBit(_) = cfg.addr { + return Err(Error::WrongAddrMode); + } + Ok(Self::$i2cx_slave(i2c, cfg, sys_clk, speed_mode, sys_cfg)) + } + } + + impl I2cSlave<$I2CX, TenBitAddress> { + pub fn $i2cx( + i2c: $I2CX, + cfg: SlaveConfig, + sys_clk: impl Into, + speed_mode: I2cSpeed, + sys_cfg: Option<&mut pac::Sysconfig>, + ) -> Self { + Self::$i2cx_slave(i2c, cfg, sys_clk, speed_mode, sys_cfg) + } + } + )+ + } +} + +i2c_slave!(pac::I2ca: (i2ca, i2ca_slave), pac::I2cb: (i2cb, i2cb_slave),); diff --git a/va108xx-hal/src/lib.rs b/va108xx-hal/src/lib.rs new file mode 100644 index 0000000..f74b8ee --- /dev/null +++ b/va108xx-hal/src/lib.rs @@ -0,0 +1,99 @@ +#![no_std] + +pub use va108xx; +pub use va108xx as pac; + +pub mod clock; +pub mod gpio; +pub mod i2c; +pub mod prelude; +pub mod pwm; +pub mod spi; +pub mod sysconfig; +pub mod time; +pub mod timer; +pub mod typelevel; +pub mod uart; +pub mod utility; + +#[derive(Debug, Eq, Copy, Clone, PartialEq)] +pub enum FunSel { + Sel1 = 0b01, + Sel2 = 0b10, + Sel3 = 0b11, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum PortSel { + PortA, + PortB, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum PeripheralSelect { + PortA = 0, + PortB = 1, + Spi0 = 4, + Spi1 = 5, + Spi2 = 6, + Uart0 = 8, + Uart1 = 9, + I2c0 = 16, + I2c1 = 17, + Irqsel = 21, + Ioconfig = 22, + Utility = 23, + Gpio = 24, +} + +/// Generic IRQ config which can be used to specify whether the HAL driver will +/// use the IRQSEL register to route an interrupt, and whether the IRQ will be unmasked in the +/// Cortex-M0 NVIC. Both are generally necessary for IRQs to work, but the user might perform +/// this steps themselves +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct IrqCfg { + /// Interrupt target vector. Should always be set, might be required for disabling IRQs + pub irq: pac::Interrupt, + /// Specfiy whether IRQ should be routed to an IRQ vector using the IRQSEL peripheral + pub route: bool, + /// Specify whether the IRQ is unmasked in the Cortex-M NVIC + pub enable: bool, +} + +impl IrqCfg { + pub fn new(irq: pac::Interrupt, route: bool, enable: bool) -> Self { + IrqCfg { irq, route, enable } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct InvalidPin(pub(crate) ()); + +/// Can be used to manually manipulate the function select of port pins +pub fn port_mux( + ioconfig: &mut pac::Ioconfig, + port: PortSel, + pin: u8, + funsel: FunSel, +) -> Result<(), InvalidPin> { + match port { + PortSel::PortA => { + if pin > 31 { + return Err(InvalidPin(())); + } + ioconfig + .porta(pin as usize) + .modify(|_, w| unsafe { w.funsel().bits(funsel as u8) }); + Ok(()) + } + PortSel::PortB => { + if pin > 23 { + return Err(InvalidPin(())); + } + ioconfig + .portb0(pin as usize) + .modify(|_, w| unsafe { w.funsel().bits(funsel as u8) }); + Ok(()) + } + } +} diff --git a/va108xx-hal/src/prelude.rs b/va108xx-hal/src/prelude.rs new file mode 100644 index 0000000..435a2f7 --- /dev/null +++ b/va108xx-hal/src/prelude.rs @@ -0,0 +1,3 @@ +//! Prelude +pub use fugit::ExtU32 as _; +pub use fugit::RateExtU32 as _; diff --git a/va108xx-hal/src/pwm.rs b/va108xx-hal/src/pwm.rs new file mode 100644 index 0000000..1232666 --- /dev/null +++ b/va108xx-hal/src/pwm.rs @@ -0,0 +1,387 @@ +//! API for Pulse-Width Modulation (PWM) +//! +//! The Vorago VA108xx devices use the TIM peripherals to perform PWM related tasks +//! +//! ## Examples +//! +//! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/pwm.rs) +use core::convert::Infallible; +use core::marker::PhantomData; + +use crate::pac; +use crate::{clock::enable_peripheral_clock, gpio::DynPinId}; +pub use crate::{gpio::PinId, time::Hertz, timer::*}; + +const DUTY_MAX: u16 = u16::MAX; + +pub struct PwmBase { + sys_clk: Hertz, + /// For PWMB, this is the upper limit + current_duty: u16, + /// For PWMA, this value will not be used + current_lower_limit: u16, + current_period: Hertz, + current_rst_val: u32, +} + +enum StatusSelPwm { + PwmA = 3, + PwmB = 4, +} + +pub struct PwmA {} +pub struct PwmB {} + +//================================================================================================== +// Common +//================================================================================================== + +macro_rules! pwm_common_func { + () => { + #[inline] + fn enable_pwm_a(&mut self) { + self.reg + .reg() + .ctrl() + .modify(|_, w| unsafe { w.status_sel().bits(StatusSelPwm::PwmA as u8) }); + } + + #[inline] + fn enable_pwm_b(&mut self) { + self.reg + .reg() + .ctrl() + .modify(|_, w| unsafe { w.status_sel().bits(StatusSelPwm::PwmB as u8) }); + } + + #[inline] + pub fn get_period(&self) -> Hertz { + self.pwm_base.current_period + } + + #[inline] + pub fn set_period(&mut self, period: impl Into) { + self.pwm_base.current_period = period.into(); + // Avoid division by 0 + if self.pwm_base.current_period.raw() == 0 { + return; + } + self.pwm_base.current_rst_val = + self.pwm_base.sys_clk.raw() / self.pwm_base.current_period.raw(); + self.reg + .reg() + .rst_value() + .write(|w| unsafe { w.bits(self.pwm_base.current_rst_val) }); + } + + #[inline] + pub fn disable(&mut self) { + self.reg.reg().ctrl().modify(|_, w| w.enable().clear_bit()); + } + + #[inline] + pub fn enable(&mut self) { + self.reg.reg().ctrl().modify(|_, w| w.enable().set_bit()); + } + + #[inline] + pub fn period(&self) -> Hertz { + self.pwm_base.current_period + } + + #[inline(always)] + pub fn duty(&self) -> u16 { + self.pwm_base.current_duty + } + }; +} + +macro_rules! pwmb_func { + () => { + pub fn pwmb_lower_limit(&self) -> u16 { + self.pwm_base.current_lower_limit + } + + pub fn pwmb_upper_limit(&self) -> u16 { + self.pwm_base.current_duty + } + + /// Set the lower limit for PWMB + /// + /// The PWM signal will be 1 as long as the current RST counter is larger than + /// the lower limit. For example, with a lower limit of 0.5 and and an upper limit + /// of 0.7, Only a fixed period between 0.5 * period and 0.7 * period will be in a high + /// state + pub fn set_pwmb_lower_limit(&mut self, duty: u16) { + self.pwm_base.current_lower_limit = duty; + let pwmb_val: u64 = (self.pwm_base.current_rst_val as u64 + * self.pwm_base.current_lower_limit as u64) + / DUTY_MAX as u64; + self.reg + .reg() + .pwmb_value() + .write(|w| unsafe { w.bits(pwmb_val as u32) }); + } + + /// Set the higher limit for PWMB + /// + /// The PWM signal will be 1 as long as the current RST counter is smaller than + /// the higher limit. For example, with a lower limit of 0.5 and and an upper limit + /// of 0.7, Only a fixed period between 0.5 * period and 0.7 * period will be in a high + /// state + pub fn set_pwmb_upper_limit(&mut self, duty: u16) { + self.pwm_base.current_duty = duty; + let pwma_val: u64 = (self.pwm_base.current_rst_val as u64 + * self.pwm_base.current_duty as u64) + / DUTY_MAX as u64; + self.reg + .reg() + .pwma_value() + .write(|w| unsafe { w.bits(pwma_val as u32) }); + } + }; +} + +//================================================================================================== +// Strongly typed PWM pin +//================================================================================================== + +pub struct PwmPin { + reg: TimAndPinRegister, + pwm_base: PwmBase, + mode: PhantomData, +} + +impl PwmPin +where + (Pin, Tim): ValidTimAndPin, +{ + /// Create a new stronlgy typed PWM pin + pub fn new( + vtp: (Pin, Tim), + sys_clk: impl Into + Copy, + sys_cfg: &mut pac::Sysconfig, + initial_period: impl Into + Copy, + ) -> Self { + let mut pin = PwmPin { + pwm_base: PwmBase { + current_duty: 0, + current_lower_limit: 0, + current_period: initial_period.into(), + current_rst_val: 0, + sys_clk: sys_clk.into(), + }, + reg: unsafe { TimAndPinRegister::new(vtp.0, vtp.1) }, + mode: PhantomData, + }; + enable_peripheral_clock(sys_cfg, crate::clock::PeripheralClocks::Gpio); + enable_peripheral_clock(sys_cfg, crate::clock::PeripheralClocks::Ioconfig); + sys_cfg + .tim_clk_enable() + .modify(|r, w| unsafe { w.bits(r.bits() | pin.reg.mask_32()) }); + pin.enable_pwm_a(); + pin.set_period(initial_period); + pin + } + pub fn release(self) -> (Pin, Tim) { + self.reg.release() + } + + pwm_common_func!(); +} + +impl From> for PwmPin +where + (Pin, Tim): ValidTimAndPin, +{ + fn from(other: PwmPin) -> Self { + let mut pwmb = Self { + reg: other.reg, + pwm_base: other.pwm_base, + mode: PhantomData, + }; + pwmb.enable_pwm_b(); + pwmb + } +} + +impl From> for PwmPin +where + (PIN, TIM): ValidTimAndPin, +{ + fn from(other: PwmPin) -> Self { + let mut pwmb = Self { + reg: other.reg, + pwm_base: other.pwm_base, + mode: PhantomData, + }; + pwmb.enable_pwm_a(); + pwmb + } +} + +impl PwmPin +where + (Pin, Tim): ValidTimAndPin, +{ + pub fn pwma( + vtp: (Pin, Tim), + sys_clk: impl Into + Copy, + sys_cfg: &mut pac::Sysconfig, + initial_period: impl Into + Copy, + ) -> Self { + let mut pin: PwmPin = Self::new(vtp, sys_clk, sys_cfg, initial_period); + pin.enable_pwm_a(); + pin + } +} + +impl PwmPin +where + (Pin, Tim): ValidTimAndPin, +{ + pub fn pwmb( + vtp: (Pin, Tim), + sys_clk: impl Into + Copy, + sys_cfg: &mut pac::Sysconfig, + initial_period: impl Into + Copy, + ) -> Self { + let mut pin: PwmPin = Self::new(vtp, sys_clk, sys_cfg, initial_period); + pin.enable_pwm_b(); + pin + } +} + +//================================================================================================== +// Reduced PWM pin +//================================================================================================== + +/// Reduced version where type information is deleted +pub struct ReducedPwmPin { + reg: TimDynRegister, + pwm_base: PwmBase, + pin_id: DynPinId, + mode: PhantomData, +} + +impl From> for ReducedPwmPin { + fn from(pwm_pin: PwmPin) -> Self { + ReducedPwmPin { + reg: TimDynRegister::from(pwm_pin.reg), + pwm_base: pwm_pin.pwm_base, + pin_id: PIN::DYN, + mode: PhantomData, + } + } +} + +impl ReducedPwmPin { + pwm_common_func!(); +} + +impl From> for ReducedPwmPin { + fn from(other: ReducedPwmPin) -> Self { + let mut pwmb = Self { + reg: other.reg, + pwm_base: other.pwm_base, + pin_id: other.pin_id, + mode: PhantomData, + }; + pwmb.enable_pwm_b(); + pwmb + } +} + +impl From> for ReducedPwmPin { + fn from(other: ReducedPwmPin) -> Self { + let mut pwmb = Self { + reg: other.reg, + pwm_base: other.pwm_base, + pin_id: other.pin_id, + mode: PhantomData, + }; + pwmb.enable_pwm_a(); + pwmb + } +} + +//================================================================================================== +// PWMB implementations +//================================================================================================== + +impl PwmPin +where + (PIN, TIM): ValidTimAndPin, +{ + pwmb_func!(); +} + +impl ReducedPwmPin { + pwmb_func!(); +} + +//================================================================================================== +// Embedded HAL implementation: PWMA only +//================================================================================================== + +impl embedded_hal::pwm::ErrorType for PwmPin { + type Error = Infallible; +} + +impl embedded_hal::pwm::ErrorType for ReducedPwmPin { + type Error = Infallible; +} + +impl embedded_hal::pwm::SetDutyCycle for ReducedPwmPin { + #[inline] + fn max_duty_cycle(&self) -> u16 { + DUTY_MAX + } + + #[inline] + fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> { + self.pwm_base.current_duty = duty; + let pwma_val: u64 = (self.pwm_base.current_rst_val as u64 + * (DUTY_MAX as u64 - self.pwm_base.current_duty as u64)) + / DUTY_MAX as u64; + self.reg + .reg() + .pwma_value() + .write(|w| unsafe { w.bits(pwma_val as u32) }); + Ok(()) + } +} + +impl embedded_hal::pwm::SetDutyCycle for PwmPin { + #[inline] + fn max_duty_cycle(&self) -> u16 { + DUTY_MAX + } + + #[inline] + fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> { + self.pwm_base.current_duty = duty; + let pwma_val: u64 = (self.pwm_base.current_rst_val as u64 + * (DUTY_MAX as u64 - self.pwm_base.current_duty as u64)) + / DUTY_MAX as u64; + self.reg + .reg() + .pwma_value() + .write(|w| unsafe { w.bits(pwma_val as u32) }); + Ok(()) + } +} + +/// Get the corresponding u16 duty cycle from a percent value ranging between 0.0 and 1.0. +/// +/// Please note that this might load a lot of floating point code because this processor does not +/// have a FPU +pub fn get_duty_from_percent(percent: f32) -> u16 { + if percent > 1.0 { + DUTY_MAX + } else if percent <= 0.0 { + 0 + } else { + (percent * DUTY_MAX as f32) as u16 + } +} diff --git a/va108xx-hal/src/spi.rs b/va108xx-hal/src/spi.rs new file mode 100644 index 0000000..db2f768 --- /dev/null +++ b/va108xx-hal/src/spi.rs @@ -0,0 +1,1214 @@ +//! API for the SPI peripheral +//! +//! ## Examples +//! +//! - [Blocking SPI example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/spi.rs) +use crate::{ + clock::{enable_peripheral_clock, PeripheralClocks}, + gpio::pins::{ + AltFunc1, AltFunc2, AltFunc3, Pin, PA10, PA11, PA12, PA13, PA14, PA15, PA16, PA17, PA18, + PA19, PA20, PA21, PA22, PA23, PA24, PA25, PA26, PA27, PA28, PA29, PA30, PA31, PB0, PB1, + PB10, PB11, PB12, PB13, PB14, PB15, PB16, PB17, PB18, PB19, PB2, PB22, PB23, PB3, PB4, PB5, + PB6, PB7, PB8, PB9, + }, + pac, + time::Hertz, + typelevel::Sealed, +}; +use core::{convert::Infallible, fmt::Debug, marker::PhantomData}; +use embedded_hal::spi::{Mode, SpiBus, MODE_0, MODE_1, MODE_2, MODE_3}; + +//================================================================================================== +// Defintions +//================================================================================================== + +// FIFO has a depth of 16. +const FILL_DEPTH: usize = 12; + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum HwChipSelectId { + Id0 = 0, + Id1 = 1, + Id2 = 2, + Id3 = 3, + Id4 = 4, + Id5 = 5, + Id6 = 6, + Id7 = 7, + Invalid = 0xff, +} + +#[derive(Debug)] +pub enum SpiPort { + Porta = 0, + Portb = 1, + Portc = 2, + Invalid = 3, +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum WordSize { + OneBit = 0x00, + FourBits = 0x03, + EightBits = 0x07, + SixteenBits = 0x0f, +} + +//================================================================================================== +// Pin type definitions +//================================================================================================== + +pub trait PinSck: Sealed {} +pub trait PinMosi: Sealed {} +pub trait PinMiso: Sealed {} + +pub trait HwCsProvider: Sealed { + const CS_ID: HwChipSelectId; + const SPI_PORT: SpiPort; +} + +pub trait OptionalHwCs: HwCsProvider + Sealed {} + +macro_rules! hw_cs_pin { + ($SPIx:path, $portId: path, $PXx:ident, $AFx:ident, $HwCsIdent:path, $typedef:ident) => { + impl HwCsProvider for Pin<$PXx, $AFx> { + const CS_ID: HwChipSelectId = $HwCsIdent; + const SPI_PORT: SpiPort = $portId; + } + impl OptionalHwCs<$SPIx> for Pin<$PXx, $AFx> {} + pub type $typedef = Pin<$PXx, $AFx>; + }; +} + +impl HwCsProvider for NoneT { + const CS_ID: HwChipSelectId = HwChipSelectId::Invalid; + const SPI_PORT: SpiPort = SpiPort::Invalid; +} + +impl OptionalHwCs for NoneT {} +impl OptionalHwCs for NoneT {} + +// SPIA + +impl PinSck for Pin {} +impl PinMosi for Pin {} +impl PinMiso for Pin {} + +pub type SpiAPortASck = Pin; +pub type SpiAPortAMosi = Pin; +pub type SpiAPortAMiso = Pin; + +impl PinSck for Pin {} +impl PinMosi for Pin {} +impl PinMiso for Pin {} + +pub type SpiAPortBSck = Pin; +pub type SpiAPortBMosi = Pin; +pub type SpiAPortBMiso = Pin; + +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA28, + AltFunc1, + HwChipSelectId::Id0, + HwCs0SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA27, + AltFunc1, + HwChipSelectId::Id1, + HwCs1SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA26, + AltFunc1, + HwChipSelectId::Id2, + HwCs2SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA25, + AltFunc1, + HwChipSelectId::Id3, + HwCs3SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA24, + AltFunc1, + HwChipSelectId::Id4, + HwCs4SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA23, + AltFunc1, + HwChipSelectId::Id5, + HwCs5SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA22, + AltFunc1, + HwChipSelectId::Id6, + HwCs6SpiAPortA +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PA21, + AltFunc1, + HwChipSelectId::Id7, + HwCs7SpiAPortA +); + +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB6, + AltFunc2, + HwChipSelectId::Id0, + HwCs0SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB5, + AltFunc2, + HwChipSelectId::Id6, + HwCs6SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB4, + AltFunc2, + HwChipSelectId::Id5, + HwCs5SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB3, + AltFunc2, + HwChipSelectId::Id4, + HwCs4SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB2, + AltFunc2, + HwChipSelectId::Id3, + HwCs3SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB1, + AltFunc2, + HwChipSelectId::Id2, + HwCs2SpiAPortB +); +hw_cs_pin!( + pac::Spia, + SpiPort::Porta, + PB0, + AltFunc2, + HwChipSelectId::Id1, + HwCs1SpiAPortB +); + +// SPIB + +impl PinSck for Pin {} +impl PinMosi for Pin {} +impl PinMiso for Pin {} + +pub type SpiBPortASck = Pin; +pub type SpiBPortAMosi = Pin; +pub type SpiBPortAMiso = Pin; + +impl PinSck for Pin {} +impl PinMosi for Pin {} +impl PinMiso for Pin {} + +impl PinSck for Pin {} +impl PinMosi for Pin {} +impl PinMiso for Pin {} + +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB16, + AltFunc1, + HwChipSelectId::Id0, + HwCs0SpiBPortB0 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB15, + AltFunc1, + HwChipSelectId::Id1, + HwCs1SpiBPortB0 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB14, + AltFunc1, + HwChipSelectId::Id2, + HwCs2SpiBPortB0 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB13, + AltFunc1, + HwChipSelectId::Id3, + HwCs3SpiBPortB +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB12, + AltFunc1, + HwChipSelectId::Id4, + HwCs4SpiBPortB +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB11, + AltFunc1, + HwChipSelectId::Id5, + HwCs5SpiBPortB +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB10, + AltFunc1, + HwChipSelectId::Id6, + HwCs6SpiBPortB +); + +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB2, + AltFunc1, + HwChipSelectId::Id0, + HwCs0SpiBPortB1 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB1, + AltFunc1, + HwChipSelectId::Id1, + HwCs1SpiBPortB1 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB0, + AltFunc1, + HwChipSelectId::Id2, + HwCs2SpiBPortB1 +); + +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB12, + AltFunc2, + HwChipSelectId::Id0, + HwCs0SpiBPortB2 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB11, + AltFunc2, + HwChipSelectId::Id1, + HwCs1SpiBPortB2 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PB10, + AltFunc2, + HwChipSelectId::Id2, + HwCs2SpiBPortB2 +); + +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA17, + AltFunc2, + HwChipSelectId::Id0, + HwCs0SpiBPortA +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA16, + AltFunc2, + HwChipSelectId::Id1, + HwCs1SpiBPortA +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA15, + AltFunc2, + HwChipSelectId::Id2, + HwCs2SpiBPortA +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA14, + AltFunc2, + HwChipSelectId::Id3, + HwCs3SpiBPortA +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA13, + AltFunc2, + HwChipSelectId::Id4, + HwCs4SpiBPortA +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA12, + AltFunc2, + HwChipSelectId::Id5, + HwCs5SpiBPortA0 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA11, + AltFunc2, + HwChipSelectId::Id6, + HwCs6SpiBPortA0 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA10, + AltFunc2, + HwChipSelectId::Id7, + HwCs7SpiBPortA0 +); + +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA23, + AltFunc2, + HwChipSelectId::Id5, + HwCs5SpiBPortA1 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA22, + AltFunc2, + HwChipSelectId::Id6, + HwCs6SpiBPortA1 +); +hw_cs_pin!( + pac::Spib, + SpiPort::Portb, + PA21, + AltFunc2, + HwChipSelectId::Id7, + HwCs7SpiBPortA1 +); + +// SPIC + +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB9, + AltFunc3, + HwChipSelectId::Id1, + HwCs1SpiCPortB0 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB8, + AltFunc3, + HwChipSelectId::Id2, + HwCs2SpiCPortB0 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB7, + AltFunc3, + HwChipSelectId::Id3, + HwCs3SpiCPortB +); + +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB22, + AltFunc3, + HwChipSelectId::Id1, + HwCs1SpiCPortB1 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB23, + AltFunc3, + HwChipSelectId::Id2, + HwCs2SpiCPortB1 +); + +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA20, + AltFunc1, + HwChipSelectId::Id1, + HwCs1SpiCPortA0 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA19, + AltFunc1, + HwChipSelectId::Id2, + HwCs2SpiCPortA0 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PB18, + AltFunc1, + HwChipSelectId::Id3, + HwCs3SpiCPortA0 +); + +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA23, + AltFunc3, + HwChipSelectId::Id1, + HwCs1SpiCPortA1 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA22, + AltFunc3, + HwChipSelectId::Id2, + HwCs2SpiCPortA1 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA21, + AltFunc3, + HwChipSelectId::Id3, + HwCs3SpiCPortA1 +); +hw_cs_pin!( + pac::Spic, + SpiPort::Portc, + PA20, + AltFunc3, + HwChipSelectId::Id4, + HwCs4SpiCPortA +); + +//================================================================================================== +// Config +//================================================================================================== + +pub trait GenericTransferConfig { + fn sod(&mut self, sod: bool); + fn blockmode(&mut self, blockmode: bool); + fn mode(&mut self, mode: Mode); + fn frequency(&mut self, spi_clk: Hertz); + fn hw_cs_id(&self) -> u8; +} + +/// This struct contains all configuration parameter which are transfer specific +/// and might change for transfers to different SPI slaves +#[derive(Copy, Clone)] +pub struct TransferConfig { + pub spi_clk: Hertz, + pub mode: Mode, + /// This only works if the Slave Output Disable (SOD) bit of the [`SpiConfig`] is set to + /// false + pub hw_cs: Option, + pub sod: bool, + /// If this is enabled, all data in the FIFO is transmitted in a single frame unless + /// the BMSTOP bit is set on a dataword. A frame is defined as CSn being active for the + /// duration of multiple data words + pub blockmode: bool, +} + +/// Type erased variant of the transfer configuration. This is required to avoid generics in +/// the SPI constructor. +pub struct ReducedTransferConfig { + pub spi_clk: Hertz, + pub mode: Mode, + pub sod: bool, + /// If this is enabled, all data in the FIFO is transmitted in a single frame unless + /// the BMSTOP bit is set on a dataword. A frame is defined as CSn being active for the + /// duration of multiple data words + pub blockmode: bool, + pub hw_cs: HwChipSelectId, +} + +impl TransferConfig { + pub fn new_no_hw_cs(spi_clk: impl Into, mode: Mode, blockmode: bool, sod: bool) -> Self { + TransferConfig { + spi_clk: spi_clk.into(), + mode, + hw_cs: None, + sod, + blockmode, + } + } +} + +impl TransferConfig { + pub fn new( + spi_clk: impl Into, + mode: Mode, + hw_cs: Option, + blockmode: bool, + sod: bool, + ) -> Self { + TransferConfig { + spi_clk: spi_clk.into(), + mode, + hw_cs, + sod, + blockmode, + } + } + + pub fn downgrade(self) -> ReducedTransferConfig { + ReducedTransferConfig { + spi_clk: self.spi_clk, + mode: self.mode, + sod: self.sod, + blockmode: self.blockmode, + hw_cs: HwCs::CS_ID, + } + } +} + +impl GenericTransferConfig for TransferConfig { + /// Slave Output Disable + fn sod(&mut self, sod: bool) { + self.sod = sod; + } + + fn blockmode(&mut self, blockmode: bool) { + self.blockmode = blockmode; + } + + fn mode(&mut self, mode: Mode) { + self.mode = mode; + } + + fn frequency(&mut self, spi_clk: Hertz) { + self.spi_clk = spi_clk; + } + + fn hw_cs_id(&self) -> u8 { + HwCs::CS_ID as u8 + } +} + +#[derive(Default)] +/// Configuration options for the whole SPI bus. See Programmer Guide p.92 for more details +pub struct SpiConfig { + /// Serial clock rate divider. Together with the CLKPRESCALE register, it determines + /// the SPI clock rate in master mode. 0 by default. Specifying a higher value + /// limits the maximum attainable SPI speed + pub scrdv: u8, + /// By default, configure SPI for master mode (ms == false) + ms: bool, + /// Slave output disable. Useful if separate GPIO pins or decoders are used for CS control + sod: bool, + /// Loopback mode. If you use this, don't connect MISO to MOSI, they will be tied internally + lbm: bool, + /// Enable Master Delayer Capture Mode. See Programmers Guide p.92 for more details + pub mdlycap: bool, +} + +impl SpiConfig { + pub fn loopback(mut self, enable: bool) -> Self { + self.lbm = enable; + self + } + + pub fn master_mode(mut self, master: bool) -> Self { + self.ms = !master; + self + } + + pub fn slave_output_disable(mut self, sod: bool) -> Self { + self.sod = sod; + self + } +} + +//================================================================================================== +// Word Size +//================================================================================================== + +/// Configuration trait for the Word Size +/// used by the SPI peripheral +pub trait Word: Copy + Default { + fn word_reg() -> u8; +} + +impl Word for u8 { + fn word_reg() -> u8 { + 0x07 + } +} + +impl Word for u16 { + fn word_reg() -> u8 { + 0x0f + } +} + +//================================================================================================== +// Spi +//================================================================================================== + +pub struct SpiBase { + spi: SpiInstance, + cfg: SpiConfig, + sys_clk: Hertz, + /// Fill word for read-only SPI transactions. + pub fill_word: Word, + blockmode: bool, + _word: PhantomData, +} + +pub struct Spi { + inner: SpiBase, + pins: Pins, +} + +// Not sure if implementing SpiDevice is a good idea here.. +/* +pub struct SpiWithHwCs { + inner: SpiBase, + pins: Pins, + hw_cs: HwCs, +} + +pub struct SpiWithHwCsErased { + inner: SpiBase, +} +*/ + +// Re-export this so it can be used for the constructor +pub use crate::typelevel::NoneT; + +macro_rules! spi { + ($($SPIX:path: ($spix:ident, $clk_enb:path) => ($($WORD:ident),+),)+) => { + $( + impl, Miso: PinMiso<$SPIX>, Mosi: PinMosi<$SPIX>, + WORD: Word> Spi<$SPIX, (Sck, Miso, Mosi), WORD> + { + /// Create a new SPI struct + /// + /// You can delete the pin type information by calling the + /// [`downgrade`](Self::downgrade) function + /// + /// ## Arguments + /// * `spi` - SPI bus to use + /// * `pins` - Pins to be used for SPI transactions. These pins are consumed + /// to ensure the pins can not be used for other purposes anymore + /// * `spi_cfg` - Configuration specific to the SPI bus + /// * `transfer_cfg` - Optional initial transfer configuration which includes + /// configuration which can change across individual SPI transfers like SPI mode + /// or SPI clock. If only one device is connected, this configuration only needs + /// to be done once. + /// * `syscfg` - Can be passed optionally to enable the peripheral clock + pub fn $spix( + spi: $SPIX, + pins: (Sck, Miso, Mosi), + sys_clk: impl Into + Copy, + spi_cfg: SpiConfig, + syscfg: Option<&mut pac::Sysconfig>, + transfer_cfg: Option<&ReducedTransferConfig>, + ) -> Self { + if let Some(syscfg) = syscfg { + enable_peripheral_clock(syscfg, $clk_enb); + } + let SpiConfig { + scrdv, + ms, + sod, + lbm, + mdlycap, + } = spi_cfg; + let mut mode = MODE_0; + let mut clk_prescale = 0x02; + let mut ss = 0; + let mut init_blockmode = false; + if let Some(transfer_cfg) = transfer_cfg { + mode = transfer_cfg.mode; + clk_prescale = sys_clk.into().raw() / (transfer_cfg.spi_clk.raw() * (scrdv as u32 + 1)); + if transfer_cfg.hw_cs != HwChipSelectId::Invalid { + ss = transfer_cfg.hw_cs as u8; + } + init_blockmode = transfer_cfg.blockmode; + } + + let (cpo_bit, cph_bit) = match mode { + MODE_0 => (false, false), + MODE_1 => (false, true), + MODE_2 => (true, false), + MODE_3 => (true, true), + }; + spi.ctrl0().write(|w| { + unsafe { + w.size().bits(WORD::word_reg()); + w.scrdv().bits(scrdv); + // Clear clock phase and polarity. Will be set to correct value for each + // transfer + w.spo().bit(cpo_bit); + w.sph().bit(cph_bit) + } + }); + spi.ctrl1().write(|w| { + w.lbm().bit(lbm); + w.sod().bit(sod); + w.ms().bit(ms); + w.mdlycap().bit(mdlycap); + w.blockmode().bit(init_blockmode); + unsafe { w.ss().bits(ss) } + }); + + spi.fifo_clr().write(|w| { + w.rxfifo().set_bit(); + w.txfifo().set_bit() + }); + spi.clkprescale().write(|w| unsafe { w.bits(clk_prescale) }); + // Enable the peripheral as the last step as recommended in the + // programmers guide + spi.ctrl1().modify(|_, w| w.enable().set_bit()); + Spi { + inner: SpiBase { + spi, + cfg: spi_cfg, + sys_clk: sys_clk.into(), + fill_word: Default::default(), + blockmode: init_blockmode, + _word: PhantomData, + }, + pins, + } + } + + #[inline] + pub fn cfg_clock(&mut self, spi_clk: impl Into) { + self.inner.cfg_clock(spi_clk); + } + + #[inline] + pub fn cfg_mode(&mut self, mode: Mode) { + self.inner.cfg_mode(mode); + } + + pub fn set_fill_word(&mut self, fill_word: WORD) { + self.inner.fill_word = fill_word; + } + + pub fn fill_word(&self) -> WORD { + self.inner.fill_word + } + + #[inline] + pub fn perid(&self) -> u32 { + self.inner.perid() + } + + pub fn cfg_transfer>(&mut self, transfer_cfg: &TransferConfig) { + self.inner.cfg_transfer(transfer_cfg); + } + + /// Releases the SPI peripheral and associated pins + pub fn release(self) -> ($SPIX, (Sck, Miso, Mosi), SpiConfig) { + (self.inner.spi, self.pins, self.inner.cfg) + } + + pub fn downgrade(self) -> SpiBase<$SPIX, WORD> { + self.inner + } + } + + impl SpiBase<$SPIX, WORD> { + #[inline] + pub fn cfg_clock(&mut self, spi_clk: impl Into) { + let clk_prescale = self.sys_clk.raw() / (spi_clk.into().raw() * (self.cfg.scrdv as u32 + 1)); + self.spi + .clkprescale() + .write(|w| unsafe { w.bits(clk_prescale) }); + } + + #[inline] + pub fn cfg_mode(&mut self, mode: Mode) { + let (cpo_bit, cph_bit) = match mode { + MODE_0 => (false, false), + MODE_1 => (false, true), + MODE_2 => (true, false), + MODE_3 => (true, true), + }; + self.spi.ctrl0().modify(|_, w| { + w.spo().bit(cpo_bit); + w.sph().bit(cph_bit) + }); + } + + #[inline] + pub fn clear_tx_fifo(&self) { + self.spi.fifo_clr().write(|w| w.txfifo().set_bit()); + } + + #[inline] + pub fn clear_rx_fifo(&self) { + self.spi.fifo_clr().write(|w| w.rxfifo().set_bit()); + } + + #[inline] + pub fn perid(&self) -> u32 { + self.spi.perid().read().bits() + } + + #[inline] + pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId) { + if hw_cs == HwChipSelectId::Invalid { + return; + } + self.spi.ctrl1().modify(|_, w| { + w.sod().clear_bit(); + unsafe { + w.ss().bits(hw_cs as u8); + } + w + }); + } + + #[inline] + pub fn cfg_hw_cs_with_pin>(&mut self, _: &HwCs) { + self.cfg_hw_cs(HwCs::CS_ID); + } + + pub fn cfg_hw_cs_disable(&mut self) { + self.spi.ctrl1().modify(|_, w| { + w.sod().set_bit(); + w + }); + } + + pub fn cfg_transfer>(&mut self, transfer_cfg: &TransferConfig) { + self.cfg_clock(transfer_cfg.spi_clk); + self.cfg_mode(transfer_cfg.mode); + self.blockmode = transfer_cfg.blockmode; + self.spi.ctrl1().modify(|_, w| { + if transfer_cfg.sod { + w.sod().set_bit(); + } else if transfer_cfg.hw_cs.is_some() { + w.sod().clear_bit(); + unsafe { + w.ss().bits(HwCs::CS_ID as u8); + } + } else { + w.sod().clear_bit(); + } + if transfer_cfg.blockmode { + w.blockmode().set_bit(); + } else { + w.blockmode().clear_bit(); + } + w + }); + } + } + + /// Changing the word size also requires a type conversion + impl , Miso: PinMiso<$SPIX>, Mosi: PinMosi<$SPIX>> + From> for Spi<$SPIX, (Sck, Miso, Mosi), u16> + { + fn from( + old_spi: Spi<$SPIX, (Sck, Miso, Mosi), u8> + ) -> Self { + old_spi.inner.spi.ctrl0().modify(|_, w| { + unsafe { + w.size().bits(WordSize::SixteenBits as u8) + } + }); + Spi { + inner: SpiBase { + spi: old_spi.inner.spi, + cfg: old_spi.inner.cfg, + blockmode: old_spi.inner.blockmode, + fill_word: Default::default(), + sys_clk: old_spi.inner.sys_clk, + _word: PhantomData, + }, + pins: old_spi.pins, + } + } + } + + /// Changing the word size also requires a type conversion + impl , Miso: PinMiso<$SPIX>, Mosi: PinMosi<$SPIX>> + From> for + Spi<$SPIX, (Sck, Miso, Mosi), u8> + { + fn from( + old_spi: Spi<$SPIX, (Sck, Miso, Mosi), u16> + ) -> Self { + old_spi.inner.spi.ctrl0().modify(|_, w| { + unsafe { + w.size().bits(WordSize::EightBits as u8) + } + }); + Spi { + inner: SpiBase { + spi: old_spi.inner.spi, + cfg: old_spi.inner.cfg, + blockmode: old_spi.inner.blockmode, + sys_clk: old_spi.inner.sys_clk, + fill_word: Default::default(), + _word: PhantomData, + }, + pins: old_spi.pins, + } + } + } + + $( + + impl SpiBase<$SPIX, $WORD> { + /// Sends a word to the slave + #[inline(always)] + fn send_blocking(&self, word: $WORD) { + // TODO: Upper limit for wait cycles to avoid complete hangups? + while self.spi.status().read().tnf().bit_is_clear() {} + self.send(word) + } + + #[inline(always)] + fn send(&self, word: $WORD) { + self.spi.data().write(|w| unsafe { w.bits(word as u32) }); + } + + /// Read a word from the slave. Must be preceeded by a [`send`](Self::send) call + #[inline(always)] + fn read_blocking(&self) -> $WORD { + // TODO: Upper limit for wait cycles to avoid complete hangups? + while self.spi.status().read().rne().bit_is_clear() {} + self.read_single_word() + } + + #[inline(always)] + fn read_single_word(&self) -> $WORD { + (self.spi.data().read().bits() & 0xffff) as $WORD + } + + fn transfer_preparation(&self, words: &[$WORD]) -> Result<(), Infallible> { + if words.len() == 0 { + return Ok(()); + } + let mut status_reg = self.spi.status().read(); + loop { + // Wait until all bytes have been transferred. + while status_reg.tfe().bit_is_clear() { + // Ignore all received read words. + if status_reg.rne().bit_is_set() { + self.clear_rx_fifo(); + } + status_reg = self.spi.status().read(); + continue; + } + break; + } + // Ignore all received read words. + if status_reg.rne().bit_is_set() { + self.clear_rx_fifo(); + } + Ok(()) + } + + fn initial_send_fifo_pumping(&self, words: Option<&[$WORD]>) -> usize { + if self.blockmode { + self.spi.ctrl1().modify(|_, w| w.mtxpause().set_bit()) + } + // Fill the first half of the write FIFO + let mut current_write_idx = 0; + for _ in 0..core::cmp::min(FILL_DEPTH, words.map_or(0, |words| words.len())) { + self.send_blocking(words.map_or(self.fill_word, |words| words[current_write_idx])); + current_write_idx += 1; + } + if self.blockmode { + self.spi.ctrl1().modify(|_, w| w.mtxpause().clear_bit()) + } + current_write_idx + } + } + + impl embedded_hal::spi::ErrorType for SpiBase<$SPIX, $WORD> { + type Error = Infallible; + } + + impl SpiBus<$WORD> for SpiBase<$SPIX, $WORD> { + fn read(&mut self, words: &mut [$WORD]) -> Result<(), Self::Error> { + self.transfer_preparation(words)?; + let mut current_read_idx = 0; + let mut current_write_idx = self.initial_send_fifo_pumping(None); + loop { + if current_write_idx < words.len() { + self.send_blocking(self.fill_word); + current_write_idx += 1; + } + if current_read_idx < words.len() { + words[current_read_idx] = self.read_blocking(); + current_read_idx += 1; + } + if current_read_idx >= words.len() && current_write_idx >= words.len() { + break; + } + } + Ok(()) + } + + fn write(&mut self, words: &[$WORD]) -> Result<(), Self::Error> { + self.transfer_preparation(words)?; + let mut current_write_idx = self.initial_send_fifo_pumping(Some(words)); + while current_write_idx < words.len() { + self.send_blocking(words[current_write_idx]); + current_write_idx += 1; + // Ignore received words. + if self.spi.status().read().rne().bit_is_set() { + self.clear_rx_fifo(); + } + } + Ok(()) + } + + fn transfer(&mut self, read: &mut [$WORD], write: &[$WORD]) -> Result<(), Self::Error> { + self.transfer_preparation(write)?; + let mut current_read_idx = 0; + let mut current_write_idx = self.initial_send_fifo_pumping(Some(write)); + while current_read_idx < read.len() || current_write_idx < write.len() { + if current_write_idx < write.len() { + self.send_blocking(write[current_write_idx]); + current_write_idx += 1; + } + if current_read_idx < read.len() { + read[current_read_idx] = self.read_blocking(); + current_read_idx += 1; + } + } + + Ok(()) + } + + fn transfer_in_place(&mut self, words: &mut [$WORD]) -> Result<(), Self::Error> { + self.transfer_preparation(words)?; + let mut current_read_idx = 0; + let mut current_write_idx = self.initial_send_fifo_pumping(Some(words)); + + while current_read_idx < words.len() || current_write_idx < words.len() { + if current_write_idx < words.len() { + self.send_blocking(words[current_write_idx]); + current_write_idx += 1; + } + if current_read_idx < words.len() && current_read_idx < current_write_idx { + words[current_read_idx] = self.read_blocking(); + current_read_idx += 1; + } + } + Ok(()) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + let status_reg = self.spi.status().read(); + while status_reg.tfe().bit_is_clear() || status_reg.rne().bit_is_set() { + if status_reg.rne().bit_is_set() { + self.read_single_word(); + } + } + Ok(()) + } + } + + impl, Miso: PinMiso<$SPIX>, Mosi: PinMosi<$SPIX>> + embedded_hal::spi::ErrorType for Spi<$SPIX, (Sck, Miso, Mosi), $WORD> + { + type Error = Infallible; + } + + impl, Miso: PinMiso<$SPIX>, Mosi: PinMosi<$SPIX>> SpiBus<$WORD> + for Spi<$SPIX, (Sck, Miso, Mosi), $WORD> + { + fn read(&mut self, words: &mut [$WORD]) -> Result<(), Self::Error> { + self.inner.read(words) + } + + fn write(&mut self, words: &[$WORD]) -> Result<(), Self::Error> { + self.inner.write(words) + } + + fn transfer(&mut self, read: &mut [$WORD], write: &[$WORD]) -> Result<(), Self::Error> { + self.inner.transfer(read, write) + } + + fn transfer_in_place(&mut self, words: &mut [$WORD]) -> Result<(), Self::Error> { + self.inner.transfer_in_place(words) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + self.inner.flush() + } + } + )+ + )+ + } +} + +spi!( + pac::Spia: (spia, PeripheralClocks::Spi0) => (u8, u16), + pac::Spib: (spib, PeripheralClocks::Spi1) => (u8, u16), + pac::Spic: (spic, PeripheralClocks::Spi2) => (u8, u16), +); diff --git a/va108xx-hal/src/sysconfig.rs b/va108xx-hal/src/sysconfig.rs new file mode 100644 index 0000000..bd7ca4a --- /dev/null +++ b/va108xx-hal/src/sysconfig.rs @@ -0,0 +1,56 @@ +use crate::{pac, PeripheralSelect}; + +#[derive(PartialEq, Eq, Debug)] +pub struct InvalidounterResetVal(pub(crate) ()); + +/// Enable scrubbing for the ROM +/// +/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0 +/// (equivalent to disabling) or larger than 24 bits +pub fn enable_rom_scrubbing( + syscfg: &mut pac::Sysconfig, + scrub_rate: u32, +) -> Result<(), InvalidounterResetVal> { + if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) { + return Err(InvalidounterResetVal(())); + } + syscfg.rom_scrub().write(|w| unsafe { w.bits(scrub_rate) }); + Ok(()) +} + +pub fn disable_rom_scrubbing(syscfg: &mut pac::Sysconfig) { + syscfg.rom_scrub().write(|w| unsafe { w.bits(0) }) +} + +/// Enable scrubbing for the RAM +/// +/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0 +/// (equivalent to disabling) or larger than 24 bits +pub fn enable_ram_scrubbing( + syscfg: &mut pac::Sysconfig, + scrub_rate: u32, +) -> Result<(), InvalidounterResetVal> { + if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) { + return Err(InvalidounterResetVal(())); + } + syscfg.ram_scrub().write(|w| unsafe { w.bits(scrub_rate) }); + Ok(()) +} + +pub fn disable_ram_scrubbing(syscfg: &mut pac::Sysconfig) { + syscfg.ram_scrub().write(|w| unsafe { w.bits(0) }) +} + +/// Clear the reset bit. This register is active low, so doing this will hold the peripheral +/// in a reset state +pub fn clear_reset_bit(syscfg: &mut pac::Sysconfig, periph_sel: PeripheralSelect) { + syscfg + .peripheral_reset() + .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << periph_sel as u8)) }); +} + +pub fn set_reset_bit(syscfg: &mut pac::Sysconfig, periph_sel: PeripheralSelect) { + syscfg + .peripheral_reset() + .modify(|r, w| unsafe { w.bits(r.bits() | (1 << periph_sel as u8)) }); +} diff --git a/va108xx-hal/src/time.rs b/va108xx-hal/src/time.rs new file mode 100644 index 0000000..9808028 --- /dev/null +++ b/va108xx-hal/src/time.rs @@ -0,0 +1,26 @@ +//! Time units + +// Frequency based + +/// Hertz +pub type Hertz = fugit::HertzU32; + +/// KiloHertz +pub type KiloHertz = fugit::KilohertzU32; + +/// MegaHertz +pub type MegaHertz = fugit::MegahertzU32; + +// Period based + +/// Seconds +pub type Seconds = fugit::SecsDurationU32; + +/// Milliseconds +pub type Milliseconds = fugit::MillisDurationU32; + +/// Microseconds +pub type Microseconds = fugit::MicrosDurationU32; + +/// Nanoseconds +pub type Nanoseconds = fugit::NanosDurationU32; diff --git a/va108xx-hal/src/timer.rs b/va108xx-hal/src/timer.rs new file mode 100644 index 0000000..2d4cf68 --- /dev/null +++ b/va108xx-hal/src/timer.rs @@ -0,0 +1,790 @@ +//! API for the TIM peripherals +//! +//! ## Examples +//! +//! - [MS and second tick implementation](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/timer-ticks.rs) +//! - [Cascade feature example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/cascade.rs) +pub use crate::IrqCfg; +use crate::{ + clock::{enable_peripheral_clock, PeripheralClocks}, + gpio::{ + AltFunc1, AltFunc2, AltFunc3, DynPinId, Pin, PinId, PA0, PA1, PA10, PA11, PA12, PA13, PA14, + PA15, PA2, PA24, PA25, PA26, PA27, PA28, PA29, PA3, PA30, PA31, PA4, PA5, PA6, PA7, PA8, + PA9, PB0, PB1, PB10, PB11, PB12, PB13, PB14, PB15, PB16, PB17, PB18, PB19, PB2, PB20, PB21, + PB22, PB23, PB3, PB4, PB5, PB6, + }, + pac::{self, tim0}, + time::Hertz, + timer, + typelevel::Sealed, + utility::unmask_irq, +}; +use core::cell::Cell; +use cortex_m::interrupt::Mutex; +use fugit::RateExtU32; + +const IRQ_DST_NONE: u32 = 0xffffffff; +pub static MS_COUNTER: Mutex> = Mutex::new(Cell::new(0)); + +//================================================================================================== +// Defintions +//================================================================================================== + +/// Interrupt events +pub enum Event { + /// Timer timed out / count down ended + TimeOut, +} + +#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)] +pub struct CascadeCtrl { + /// Enable Cascade 0 signal active as a requirement for counting + pub enb_start_src_csd0: bool, + /// Invert Cascade 0, making it active low + pub inv_csd0: bool, + /// Enable Cascade 1 signal active as a requirement for counting + pub enb_start_src_csd1: bool, + /// Invert Cascade 1, making it active low + pub inv_csd1: bool, + /// Specify required operation if both Cascade 0 and Cascade 1 are active. + /// 0 is a logical AND of both cascade signals, 1 is a logical OR + pub dual_csd_op: bool, + /// Enable trigger mode for Cascade 0. In trigger mode, couting will start with the selected + /// cascade signal active, but once the counter is active, cascade control will be ignored + pub trg_csd0: bool, + /// Trigger mode, identical to [`trg_csd0`](CascadeCtrl) but for Cascade 1 + pub trg_csd1: bool, + /// Enable Cascade 2 signal active as a requirement to stop counting. This mode is similar + /// to the REQ_STOP control bit, but signalled by a Cascade source + pub enb_stop_src_csd2: bool, + /// Invert Cascade 2, making it active low + pub inv_csd2: bool, + /// The counter is automatically disabled if the corresponding Cascade 2 level-sensitive input + /// souce is active when the count reaches 0. If the counter is not 0, the cascade control is + /// ignored + pub trg_csd2: bool, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum CascadeSel { + Csd0 = 0, + Csd1 = 1, + Csd2 = 2, +} + +/// The numbers are the base numbers for bundles like PORTA, PORTB or TIM +#[derive(Debug, PartialEq, Eq)] +pub enum CascadeSource { + PortABase = 0, + PortBBase = 32, + TimBase = 64, + RamSbe = 96, + RamMbe = 97, + RomSbe = 98, + RomMbe = 99, + Txev = 100, + ClockDividerBase = 120, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum TimerErrors { + Canceled, + /// Invalid input for Cascade source + InvalidCsdSourceInput, +} + +//================================================================================================== +// Valid TIM and PIN combinations +//================================================================================================== + +pub trait TimPin { + const DYN: DynPinId; +} + +pub trait ValidTim { + // TIM ID ranging from 0 to 23 for 24 TIM peripherals + const TIM_ID: u8; +} + +macro_rules! tim_marker { + ($TIMX:path, $ID:expr) => { + impl ValidTim for $TIMX { + const TIM_ID: u8 = $ID; + } + }; +} + +tim_marker!(pac::Tim0, 0); +tim_marker!(pac::Tim1, 1); +tim_marker!(pac::Tim2, 2); +tim_marker!(pac::Tim3, 3); +tim_marker!(pac::Tim4, 4); +tim_marker!(pac::Tim5, 5); +tim_marker!(pac::Tim6, 6); +tim_marker!(pac::Tim7, 7); +tim_marker!(pac::Tim8, 8); +tim_marker!(pac::Tim9, 9); +tim_marker!(pac::Tim10, 10); +tim_marker!(pac::Tim11, 11); +tim_marker!(pac::Tim12, 12); +tim_marker!(pac::Tim13, 13); +tim_marker!(pac::Tim14, 14); +tim_marker!(pac::Tim15, 15); +tim_marker!(pac::Tim16, 16); +tim_marker!(pac::Tim17, 17); +tim_marker!(pac::Tim18, 18); +tim_marker!(pac::Tim19, 19); +tim_marker!(pac::Tim20, 20); +tim_marker!(pac::Tim21, 21); +tim_marker!(pac::Tim22, 22); +tim_marker!(pac::Tim23, 23); + +pub trait ValidTimAndPin: Sealed {} + +macro_rules! pin_and_tim { + ($PAX:ident, $ALTFUNC:ident, $ID:expr, $TIMX:path) => { + impl TimPin for Pin<$PAX, $ALTFUNC> + where + $PAX: PinId, + { + const DYN: DynPinId = $PAX::DYN; + } + + impl ValidTimAndPin for (Pin<$PAX, $ALTFUNC>, $TIMX) + where + Pin<$PAX, $ALTFUNC>: TimPin, + $PAX: PinId, + { + } + + impl Sealed for (Pin<$PAX, $ALTFUNC>, $TIMX) {} + }; +} + +pin_and_tim!(PA31, AltFunc2, 23, pac::Tim23); +pin_and_tim!(PA30, AltFunc2, 22, pac::Tim22); +pin_and_tim!(PA29, AltFunc2, 21, pac::Tim21); +pin_and_tim!(PA28, AltFunc2, 20, pac::Tim20); +pin_and_tim!(PA27, AltFunc2, 19, pac::Tim19); +pin_and_tim!(PA26, AltFunc2, 18, pac::Tim18); +pin_and_tim!(PA25, AltFunc2, 17, pac::Tim17); +pin_and_tim!(PA24, AltFunc2, 16, pac::Tim16); + +pin_and_tim!(PA15, AltFunc1, 15, pac::Tim15); +pin_and_tim!(PA14, AltFunc1, 14, pac::Tim14); +pin_and_tim!(PA13, AltFunc1, 13, pac::Tim13); +pin_and_tim!(PA12, AltFunc1, 12, pac::Tim12); +pin_and_tim!(PA11, AltFunc1, 11, pac::Tim11); +pin_and_tim!(PA10, AltFunc1, 10, pac::Tim10); +pin_and_tim!(PA9, AltFunc1, 9, pac::Tim9); +pin_and_tim!(PA8, AltFunc1, 8, pac::Tim8); +pin_and_tim!(PA7, AltFunc1, 7, pac::Tim7); +pin_and_tim!(PA6, AltFunc1, 6, pac::Tim6); +pin_and_tim!(PA5, AltFunc1, 5, pac::Tim5); +pin_and_tim!(PA4, AltFunc1, 4, pac::Tim4); +pin_and_tim!(PA3, AltFunc1, 3, pac::Tim3); +pin_and_tim!(PA2, AltFunc1, 2, pac::Tim2); +pin_and_tim!(PA1, AltFunc1, 1, pac::Tim1); +pin_and_tim!(PA0, AltFunc1, 0, pac::Tim0); + +pin_and_tim!(PB23, AltFunc3, 23, pac::Tim23); +pin_and_tim!(PB22, AltFunc3, 22, pac::Tim22); +pin_and_tim!(PB21, AltFunc3, 21, pac::Tim21); +pin_and_tim!(PB20, AltFunc3, 20, pac::Tim20); +pin_and_tim!(PB19, AltFunc3, 19, pac::Tim19); +pin_and_tim!(PB18, AltFunc3, 18, pac::Tim18); +pin_and_tim!(PB17, AltFunc3, 17, pac::Tim17); +pin_and_tim!(PB16, AltFunc3, 16, pac::Tim16); +pin_and_tim!(PB15, AltFunc3, 15, pac::Tim15); +pin_and_tim!(PB14, AltFunc3, 14, pac::Tim14); +pin_and_tim!(PB13, AltFunc3, 13, pac::Tim13); +pin_and_tim!(PB12, AltFunc3, 12, pac::Tim12); +pin_and_tim!(PB11, AltFunc3, 11, pac::Tim11); +pin_and_tim!(PB10, AltFunc3, 10, pac::Tim10); + +pin_and_tim!(PB6, AltFunc3, 6, pac::Tim6); +pin_and_tim!(PB5, AltFunc3, 5, pac::Tim5); +pin_and_tim!(PB4, AltFunc3, 4, pac::Tim4); +pin_and_tim!(PB3, AltFunc3, 3, pac::Tim3); +pin_and_tim!(PB2, AltFunc3, 2, pac::Tim2); +pin_and_tim!(PB1, AltFunc3, 1, pac::Tim1); +pin_and_tim!(PB0, AltFunc3, 0, pac::Tim0); + +//================================================================================================== +// Register Interface for TIM registers and TIM pins +//================================================================================================== + +pub type TimRegBlock = tim0::RegisterBlock; + +/// Register interface. +/// +/// This interface provides valid TIM pins a way to access their corresponding TIM +/// registers +/// +/// # Safety +/// +/// Users should only implement the [`tim_id`] function. No default function +/// implementations should be overridden. The implementing type must also have +/// "control" over the corresponding pin ID, i.e. it must guarantee that a each +/// pin ID is a singleton. +pub(super) unsafe trait TimRegInterface { + fn tim_id(&self) -> u8; + + const PORT_BASE: *const tim0::RegisterBlock = pac::Tim0::ptr() as *const _; + + /// All 24 TIM blocks are identical. This helper functions returns the correct + /// memory mapped peripheral depending on the TIM ID. + #[inline(always)] + fn reg(&self) -> &TimRegBlock { + unsafe { &*Self::PORT_BASE.offset(self.tim_id() as isize) } + } + + #[inline(always)] + fn mask_32(&self) -> u32 { + 1 << self.tim_id() + } + + /// Clear the reset bit of the TIM, holding it in reset + /// + /// # Safety + /// + /// Only the bit related to the corresponding TIM peripheral is modified + #[inline] + #[allow(dead_code)] + fn clear_tim_reset_bit(&self) { + unsafe { + va108xx::Peripherals::steal() + .sysconfig + .tim_reset() + .modify(|r, w| w.bits(r.bits() & !self.mask_32())) + } + } + + #[inline] + #[allow(dead_code)] + fn set_tim_reset_bit(&self) { + unsafe { + va108xx::Peripherals::steal() + .sysconfig + .tim_reset() + .modify(|r, w| w.bits(r.bits() | self.mask_32())) + } + } +} + +/// Provide a safe register interface for [`ValidTimAndPin`]s +/// +/// This `struct` takes ownership of a [`ValidTimAndPin`] and provides an API to +/// access the corresponding registers. +pub(super) struct TimAndPinRegister { + pin: Pin, + tim: Tim, +} + +pub(super) struct TimRegister { + tim: TIM, +} + +impl TimRegister { + #[inline] + pub(super) unsafe fn new(tim: TIM) -> Self { + TimRegister { tim } + } + + pub(super) fn release(self) -> TIM { + self.tim + } +} + +unsafe impl TimRegInterface for TimRegister { + fn tim_id(&self) -> u8 { + TIM::TIM_ID + } +} + +impl TimAndPinRegister +where + (PIN, TIM): ValidTimAndPin, +{ + #[inline] + pub(super) unsafe fn new(pin: PIN, tim: TIM) -> Self { + TimAndPinRegister { pin, tim } + } + + pub(super) fn release(self) -> (PIN, TIM) { + (self.pin, self.tim) + } +} + +unsafe impl TimRegInterface for TimAndPinRegister { + #[inline(always)] + fn tim_id(&self) -> u8 { + TIM::TIM_ID + } +} + +pub(super) struct TimDynRegister { + tim_id: u8, + #[allow(dead_code)] + pin_id: DynPinId, +} + +impl From> for TimDynRegister { + fn from(_reg: TimAndPinRegister) -> Self { + Self { + tim_id: TIM::TIM_ID, + pin_id: PIN::DYN, + } + } +} + +unsafe impl TimRegInterface for TimDynRegister { + #[inline(always)] + fn tim_id(&self) -> u8 { + self.tim_id + } +} + +//================================================================================================== +// Timers +//================================================================================================== + +/// Hardware timers +pub struct CountDownTimer { + tim: TimRegister, + curr_freq: Hertz, + irq_cfg: Option, + sys_clk: Hertz, + rst_val: u32, + last_cnt: u32, + listening: bool, +} + +fn enable_tim_clk(syscfg: &mut pac::Sysconfig, idx: u8) { + syscfg + .tim_clk_enable() + .modify(|r, w| unsafe { w.bits(r.bits() | (1 << idx)) }); +} + +unsafe impl TimRegInterface for CountDownTimer { + fn tim_id(&self) -> u8 { + TIM::TIM_ID + } +} + +macro_rules! csd_sel { + ($func_name:ident, $csd_reg:ident) => { + /// Configure the Cascade sources + pub fn $func_name( + &mut self, + src: CascadeSource, + id: Option, + ) -> Result<(), TimerErrors> { + let mut id_num = 0; + if let CascadeSource::PortABase + | CascadeSource::PortBBase + | CascadeSource::ClockDividerBase + | CascadeSource::TimBase = src + { + if id.is_none() { + return Err(TimerErrors::InvalidCsdSourceInput); + } + } + if id.is_some() { + id_num = id.unwrap(); + } + match src { + CascadeSource::PortABase => { + if id_num > 55 { + return Err(TimerErrors::InvalidCsdSourceInput); + } + self.tim.reg().$csd_reg().write(|w| unsafe { + w.cassel().bits(CascadeSource::PortABase as u8 + id_num) + }); + Ok(()) + } + CascadeSource::PortBBase => { + if id_num > 23 { + return Err(TimerErrors::InvalidCsdSourceInput); + } + self.tim.reg().$csd_reg().write(|w| unsafe { + w.cassel().bits(CascadeSource::PortBBase as u8 + id_num) + }); + Ok(()) + } + CascadeSource::TimBase => { + if id_num > 23 { + return Err(TimerErrors::InvalidCsdSourceInput); + } + self.tim.reg().$csd_reg().write(|w| unsafe { + w.cassel().bits(CascadeSource::TimBase as u8 + id_num) + }); + Ok(()) + } + CascadeSource::ClockDividerBase => { + if id_num > 7 { + return Err(TimerErrors::InvalidCsdSourceInput); + } + self.tim.reg().cascade0().write(|w| unsafe { + w.cassel() + .bits(CascadeSource::ClockDividerBase as u8 + id_num) + }); + Ok(()) + } + _ => { + self.tim + .reg() + .$csd_reg() + .write(|w| unsafe { w.cassel().bits(src as u8) }); + Ok(()) + } + } + } + }; +} + +impl CountDownTimer { + /// Configures a TIM peripheral as a periodic count down timer + pub fn new(syscfg: &mut pac::Sysconfig, sys_clk: impl Into, tim: TIM) -> Self { + enable_tim_clk(syscfg, TIM::TIM_ID); + let cd_timer = CountDownTimer { + tim: unsafe { TimRegister::new(tim) }, + sys_clk: sys_clk.into(), + irq_cfg: None, + rst_val: 0, + curr_freq: 0.Hz(), + listening: false, + last_cnt: 0, + }; + cd_timer + .tim + .reg() + .ctrl() + .modify(|_, w| w.enable().set_bit()); + cd_timer + } + + /// Listen for events. Depending on the IRQ configuration, this also activates the IRQ in the + /// IRQSEL peripheral for the provided interrupt and unmasks the interrupt + pub fn listen( + &mut self, + event: Event, + irq_cfg: IrqCfg, + irq_sel: Option<&mut pac::Irqsel>, + sys_cfg: Option<&mut pac::Sysconfig>, + ) { + match event { + Event::TimeOut => { + cortex_m::peripheral::NVIC::mask(irq_cfg.irq); + self.irq_cfg = Some(irq_cfg); + if irq_cfg.route { + if let Some(sys_cfg) = sys_cfg { + enable_peripheral_clock(sys_cfg, PeripheralClocks::Irqsel); + } + if let Some(irq_sel) = irq_sel { + irq_sel + .tim0(TIM::TIM_ID as usize) + .write(|w| unsafe { w.bits(irq_cfg.irq as u32) }); + } + } + self.listening = true; + } + } + } + + pub fn unlisten( + &mut self, + event: Event, + syscfg: &mut pac::Sysconfig, + irqsel: &mut pac::Irqsel, + ) { + match event { + Event::TimeOut => { + enable_peripheral_clock(syscfg, PeripheralClocks::Irqsel); + irqsel + .tim0(TIM::TIM_ID as usize) + .write(|w| unsafe { w.bits(IRQ_DST_NONE) }); + self.disable_interrupt(); + self.listening = false; + } + } + } + + #[inline(always)] + pub fn enable_interrupt(&mut self) { + self.tim.reg().ctrl().modify(|_, w| w.irq_enb().set_bit()); + } + + #[inline(always)] + pub fn disable_interrupt(&mut self) { + self.tim.reg().ctrl().modify(|_, w| w.irq_enb().clear_bit()); + } + + pub fn release(self, syscfg: &mut pac::Sysconfig) -> TIM { + self.tim.reg().ctrl().write(|w| w.enable().clear_bit()); + syscfg + .tim_clk_enable() + .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << TIM::TIM_ID)) }); + self.tim.release() + } + + /// Load the count down timer with a timeout but do not start it. + pub fn load(&mut self, timeout: impl Into) { + self.tim.reg().ctrl().modify(|_, w| w.enable().clear_bit()); + self.curr_freq = timeout.into(); + self.rst_val = self.sys_clk.raw() / self.curr_freq.raw(); + self.set_reload(self.rst_val); + self.set_count(self.rst_val); + } + + #[inline(always)] + pub fn set_reload(&mut self, val: u32) { + self.tim.reg().rst_value().write(|w| unsafe { w.bits(val) }); + } + + #[inline(always)] + pub fn set_count(&mut self, val: u32) { + self.tim.reg().cnt_value().write(|w| unsafe { w.bits(val) }); + } + + #[inline(always)] + pub fn count(&self) -> u32 { + self.tim.reg().cnt_value().read().bits() + } + + #[inline(always)] + pub fn enable(&mut self) { + self.tim.reg().ctrl().modify(|_, w| w.enable().set_bit()); + if let Some(irq_cfg) = self.irq_cfg { + self.enable_interrupt(); + if irq_cfg.enable { + unmask_irq(irq_cfg.irq); + } + } + } + + #[inline(always)] + pub fn disable(&mut self) { + self.tim.reg().ctrl().modify(|_, w| w.enable().clear_bit()); + } + + /// Disable the counter, setting both enable and active bit to 0 + pub fn auto_disable(self, enable: bool) -> Self { + if enable { + self.tim + .reg() + .ctrl() + .modify(|_, w| w.auto_disable().set_bit()); + } else { + self.tim + .reg() + .ctrl() + .modify(|_, w| w.auto_disable().clear_bit()); + } + self + } + + /// This option only applies when the Auto-Disable functionality is 0. + /// + /// The active bit is changed to 0 when count reaches 0, but the counter stays + /// enabled. When Auto-Disable is 1, Auto-Deactivate is implied + pub fn auto_deactivate(self, enable: bool) -> Self { + if enable { + self.tim + .reg() + .ctrl() + .modify(|_, w| w.auto_deactivate().set_bit()); + } else { + self.tim + .reg() + .ctrl() + .modify(|_, w| w.auto_deactivate().clear_bit()); + } + self + } + + /// Configure the cascade parameters + pub fn cascade_control(&mut self, ctrl: CascadeCtrl) { + self.tim.reg().csd_ctrl().write(|w| { + w.csden0().bit(ctrl.enb_start_src_csd0); + w.csdinv0().bit(ctrl.inv_csd0); + w.csden1().bit(ctrl.enb_start_src_csd1); + w.csdinv1().bit(ctrl.inv_csd1); + w.dcasop().bit(ctrl.dual_csd_op); + w.csdtrg0().bit(ctrl.trg_csd0); + w.csdtrg1().bit(ctrl.trg_csd1); + w.csden2().bit(ctrl.enb_stop_src_csd2); + w.csdinv2().bit(ctrl.inv_csd2); + w.csdtrg2().bit(ctrl.trg_csd2) + }); + } + + csd_sel!(cascade_0_source, cascade0); + csd_sel!(cascade_1_source, cascade1); + csd_sel!(cascade_2_source, cascade2); + + pub fn curr_freq(&self) -> Hertz { + self.curr_freq + } + + pub fn listening(&self) -> bool { + self.listening + } +} + +/// CountDown implementation for TIMx +impl CountDownTimer { + #[inline] + pub fn start(&mut self, timeout: T) + where + T: Into, + { + self.load(timeout); + self.enable(); + } + + /// Return `Ok` if the timer has wrapped. Peripheral will automatically clear the + /// flag and restart the time if configured correctly + pub fn wait(&mut self) -> nb::Result<(), void::Void> { + let cnt = self.tim.reg().cnt_value().read().bits(); + if (cnt > self.last_cnt) || cnt == 0 { + self.last_cnt = self.rst_val; + Ok(()) + } else { + self.last_cnt = cnt; + Err(nb::Error::WouldBlock) + } + } + + pub fn cancel(&mut self) -> Result<(), TimerErrors> { + if !self.tim.reg().ctrl().read().enable().bit_is_set() { + return Err(TimerErrors::Canceled); + } + self.tim.reg().ctrl().write(|w| w.enable().clear_bit()); + Ok(()) + } +} + +impl embedded_hal::delay::DelayNs for CountDownTimer { + fn delay_ns(&mut self, ns: u32) { + let ticks = (u64::from(ns)) * (u64::from(self.sys_clk.raw())) / 1_000_000_000; + + let full_cycles = ticks >> 32; + let mut last_count; + let mut new_count; + if full_cycles > 0 { + self.set_reload(u32::MAX); + self.set_count(u32::MAX); + self.enable(); + + for _ in 0..full_cycles { + // Always ensure that both values are the same at the start. + new_count = self.count(); + last_count = new_count; + loop { + new_count = self.count(); + if new_count == 0 { + // Wait till timer has wrapped. + while self.count() == 0 { + cortex_m::asm::nop() + } + break; + } + // Timer has definitely wrapped. + if new_count > last_count { + break; + } + last_count = new_count; + } + } + } + let ticks = (ticks & u32::MAX as u64) as u32; + self.disable(); + if ticks > 1 { + self.set_reload(ticks); + self.set_count(ticks); + self.enable(); + last_count = ticks; + + loop { + new_count = self.count(); + if new_count == 0 || (new_count > last_count) { + break; + } + last_count = new_count; + } + } + + self.disable(); + } +} + +// Set up a millisecond timer on TIM0. Please note that the user still has to provide an IRQ handler +// which should call [default_ms_irq_handler]. +pub fn set_up_ms_tick( + irq_cfg: IrqCfg, + sys_cfg: &mut pac::Sysconfig, + irq_sel: Option<&mut pac::Irqsel>, + sys_clk: impl Into, + tim0: TIM, +) -> CountDownTimer { + let mut ms_timer = CountDownTimer::new(sys_cfg, sys_clk, tim0); + ms_timer.listen(timer::Event::TimeOut, irq_cfg, irq_sel, Some(sys_cfg)); + ms_timer.start(1000.Hz()); + ms_timer +} + +pub fn set_up_ms_delay_provider( + sys_cfg: &mut pac::Sysconfig, + sys_clk: impl Into, + tim: TIM, +) -> CountDownTimer { + let mut provider = CountDownTimer::new(sys_cfg, sys_clk, tim); + provider.start(1000.Hz()); + provider +} + +/// This function can be called in a specified interrupt handler to increment +/// the MS counter +pub fn default_ms_irq_handler() { + cortex_m::interrupt::free(|cs| { + let mut ms = MS_COUNTER.borrow(cs).get(); + ms += 1; + MS_COUNTER.borrow(cs).set(ms); + }); +} + +/// Get the current MS tick count +pub fn get_ms_ticks() -> u32 { + cortex_m::interrupt::free(|cs| MS_COUNTER.borrow(cs).get()) +} + +//================================================================================================== +// Delay implementations +//================================================================================================== + +pub struct DelayMs(CountDownTimer); + +impl DelayMs { + pub fn new(timer: CountDownTimer) -> Option { + if timer.curr_freq() != Hertz::from_raw(1000) || !timer.listening() { + return None; + } + Some(Self(timer)) + } +} + +/// This assumes that the user has already set up a MS tick timer in TIM0 as a system tick +/// with [`set_up_ms_delay_provider`] +impl embedded_hal::delay::DelayNs for DelayMs { + fn delay_ns(&mut self, ns: u32) { + let ns_as_ms = ns / 1_000_000; + if self.0.curr_freq() != Hertz::from_raw(1000) || !self.0.listening() { + return; + } + let start_time = get_ms_ticks(); + while get_ms_ticks() - start_time < ns_as_ms { + cortex_m::asm::nop(); + } + } +} diff --git a/va108xx-hal/src/typelevel.rs b/va108xx-hal/src/typelevel.rs new file mode 100644 index 0000000..7803c20 --- /dev/null +++ b/va108xx-hal/src/typelevel.rs @@ -0,0 +1,155 @@ +//! Module supporting type-level programming +//! +//! This module is identical to the +//! [atsamd typelevel](https://docs.rs/atsamd-hal/latest/atsamd_hal/typelevel/index.html). + +use core::ops::{Add, Sub}; + +use typenum::{Add1, Bit, Sub1, UInt, Unsigned, B1, U0}; + +mod private { + /// Super trait used to mark traits with an exhaustive set of + /// implementations + pub trait Sealed {} + + impl Sealed for u8 {} + impl Sealed for i8 {} + impl Sealed for u16 {} + impl Sealed for i16 {} + impl Sealed for u32 {} + impl Sealed for i32 {} + impl Sealed for f32 {} + + /// Mapping from an instance of a countable type to its successor + pub trait Increment { + /// Successor type of `Self` + type Inc; + /// Consume an instance of `Self` and return its successor + fn inc(self) -> Self::Inc; + } + + /// Mapping from an instance of a countable type to its predecessor + pub trait Decrement { + /// Predecessor type of `Self` + type Dec; + /// Consume an instance of `Self` and return its predecessor + fn dec(self) -> Self::Dec; + } +} + +pub(crate) use private::Decrement as PrivateDecrement; +pub(crate) use private::Increment as PrivateIncrement; +pub(crate) use private::Sealed; + +/// Type-level version of the [`None`] variant +#[derive(Default)] +pub struct NoneT; + +impl Sealed for NoneT {} + +//============================================================================== +// Is +//============================================================================== + +/// Marker trait for type identity +/// +/// This trait is used as part of the [`AnyKind`] trait pattern. It represents +/// the concept of type identity, because all implementors have +/// `::Type == Self`. When used as a trait bound with a specific +/// type, it guarantees that the corresponding type parameter is exactly the +/// specific type. Stated differently, it guarantees that `T == Specific` in +/// the following example. +/// +/// ```ignore +/// where T: Is +/// ``` +/// +/// Moreover, the super traits guarantee that any instance of or reference to a +/// type `T` can be converted into the `Specific` type. +/// +/// ```ignore +/// fn example(mut any: T) +/// where +/// T: Is, +/// { +/// let specific_mut: &mut Specific = any.as_mut(); +/// let specific_ref: &Specific = any.as_ref(); +/// let specific: Specific = any.into(); +/// } +/// ``` +/// +/// [`AnyKind`]: #anykind-trait-pattern +pub trait Is +where + Self: Sealed, + Self: From>, + Self: Into>, + Self: AsRef>, + Self: AsMut>, +{ + type Type; +} + +/// Type alias for [`Is::Type`] +pub type IsType = ::Type; + +impl Is for T +where + T: Sealed + AsRef + AsMut, +{ + type Type = T; +} + +//============================================================================== +// Counting +//============================================================================== + +/// Implement `Sealed` for [`U0`] +impl Sealed for U0 {} + +/// Implement `Sealed` for all type-level, [`Unsigned`] integers *except* [`U0`] +impl Sealed for UInt {} + +/// Trait mapping each countable type to its successor +/// +/// This trait maps each countable type to its corresponding successor type. The +/// actual implementation of this trait is contained within `PrivateIncrement`. +/// Access to `PrivateIncrement` is restricted, so that safe HAL APIs can be +/// built with it. +pub trait Increment: PrivateIncrement {} + +impl Increment for T {} + +/// Trait mapping each countable type to its predecessor +/// +/// This trait maps each countable type to its corresponding predecessor type. +/// The actual implementation of this trait is contained within +/// `PrivateDecrement`. Access to `PrivateDecrement` is restricted, so that safe +/// HAL APIs can be built with it. +pub trait Decrement: PrivateDecrement {} + +impl Decrement for T {} + +impl PrivateIncrement for N +where + N: Unsigned + Add, + Add1: Unsigned, +{ + type Inc = Add1; + #[inline] + fn inc(self) -> Self::Inc { + Self::Inc::default() + } +} + +impl PrivateDecrement for N +where + N: Unsigned + Sub, + Sub1: Unsigned, +{ + type Dec = Sub1; + #[inline] + fn dec(self) -> Self::Dec { + Self::Dec::default() + } +} diff --git a/va108xx-hal/src/uart.rs b/va108xx-hal/src/uart.rs new file mode 100644 index 0000000..aafd5f5 --- /dev/null +++ b/va108xx-hal/src/uart.rs @@ -0,0 +1,1018 @@ +//! # API for the UART peripheral +//! +//! ## Examples +//! +//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart.rs) +//! - [UART with IRQ and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart-irq-rtic.rs) +use core::{marker::PhantomData, ops::Deref}; +use embedded_hal_nb::serial::Read; +use fugit::RateExtU32; +use libm::floorf; + +pub use crate::IrqCfg; +use crate::{ + clock::{self, enable_peripheral_clock, PeripheralClocks}, + gpio::pins::{ + AltFunc1, AltFunc2, AltFunc3, Pin, PA16, PA17, PA18, PA19, PA2, PA26, PA27, PA3, PA30, + PA31, PA8, PA9, PB18, PB19, PB20, PB21, PB22, PB23, PB6, PB7, PB8, PB9, + }, + pac::{self, uarta as uart_base}, + time::Hertz, + utility::unmask_irq, +}; + +//================================================================================================== +// Type-Level support +//================================================================================================== + +pub trait Pins {} + +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} + +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} + +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} + +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} +impl Pins for (Pin, Pin) {} + +//================================================================================================== +// Regular Definitions +//================================================================================================== + +#[derive(Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum Error { + Overrun, + FramingError, + ParityError, + BreakCondition, + TransferPending, + BufferTooShort, + /// Can be a combination of overrun, framing or parity error + IrqError, +} + +impl embedded_io::Error for Error { + fn kind(&self) -> embedded_io::ErrorKind { + embedded_io::ErrorKind::Other + } +} + +impl embedded_hal_nb::serial::Error for Error { + fn kind(&self) -> embedded_hal_nb::serial::ErrorKind { + embedded_hal_nb::serial::ErrorKind::Other + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub enum Event { + // Receiver FIFO interrupt enable. Generates interrupt + // when FIFO is at least half full. Half full is defined as FIFO + // count >= RXFIFOIRQTRG + RxFifoHalfFull, + // Framing error, Overrun error, Parity Error and Break error + RxError, + // Event for timeout condition: Data in the FIFO and no receiver + // FIFO activity for 4 character times + RxTimeout, + + // Transmitter FIFO interrupt enable. Generates interrupt + // when FIFO is at least half full. Half full is defined as FIFO + // count >= TXFIFOIRQTRG + TxFifoHalfFull, + // FIFO overflow error + TxError, + // Generate interrupt when transmit FIFO is empty and TXBUSY is 0 + TxEmpty, + // Interrupt when CTSn changes value + TxCts, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum Parity { + None, + Odd, + Even, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum StopBits { + One = 0, + Two = 1, +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum WordSize { + Five = 0, + Six = 1, + Seven = 2, + Eight = 3, +} + +pub struct Config { + pub baudrate: Hertz, + pub parity: Parity, + pub stopbits: StopBits, + // When false, use standard 16x baud clock, other 8x baud clock + pub baud8: bool, + pub wordsize: WordSize, + pub enable_tx: bool, + pub enable_rx: bool, +} + +impl Config { + pub fn baudrate(mut self, baudrate: Hertz) -> Self { + self.baudrate = baudrate; + self + } + + pub fn parity_none(mut self) -> Self { + self.parity = Parity::None; + self + } + + pub fn parity_even(mut self) -> Self { + self.parity = Parity::Even; + self + } + + pub fn parity_odd(mut self) -> Self { + self.parity = Parity::Odd; + self + } + + pub fn stopbits(mut self, stopbits: StopBits) -> Self { + self.stopbits = stopbits; + self + } + + pub fn wordsize(mut self, wordsize: WordSize) -> Self { + self.wordsize = wordsize; + self + } + + pub fn baud8(mut self, baud: bool) -> Self { + self.baud8 = baud; + self + } +} + +impl Default for Config { + fn default() -> Config { + let baudrate = 115_200_u32.Hz(); + Config { + baudrate, + parity: Parity::None, + stopbits: StopBits::One, + baud8: false, + wordsize: WordSize::Eight, + enable_tx: true, + enable_rx: true, + } + } +} + +impl From for Config { + fn from(baud: Hertz) -> Self { + Config::default().baudrate(baud) + } +} + +//================================================================================================== +// IRQ Definitions +//================================================================================================== + +struct IrqInfo { + rx_len: usize, + rx_idx: usize, + irq_cfg: IrqCfg, + mode: IrqReceptionMode, +} + +pub enum IrqResultMask { + Complete = 0, + Overflow = 1, + FramingError = 2, + ParityError = 3, + Break = 4, + Timeout = 5, + Addr9 = 6, + /// Should not happen + Unknown = 7, +} + +/// This struct is used to return the default IRQ handler result to the user +#[derive(Debug, Default)] +pub struct IrqResult { + raw_res: u32, + pub bytes_read: usize, +} + +impl IrqResult { + pub const fn new() -> Self { + IrqResult { + raw_res: 0, + bytes_read: 0, + } + } +} + +impl IrqResult { + #[inline] + pub fn raw_result(&self) -> u32 { + self.raw_res + } + + #[inline] + pub(crate) fn clear_result(&mut self) { + self.raw_res = 0; + } + #[inline] + pub(crate) fn set_result(&mut self, flag: IrqResultMask) { + self.raw_res |= 1 << flag as u32; + } + + #[inline] + pub fn complete(&self) -> bool { + if ((self.raw_res >> IrqResultMask::Complete as u32) & 0x01) == 0x01 { + return true; + } + false + } + + #[inline] + pub fn error(&self) -> bool { + if self.overflow_error() || self.framing_error() || self.parity_error() { + return true; + } + false + } + + #[inline] + pub fn overflow_error(&self) -> bool { + if ((self.raw_res >> IrqResultMask::Overflow as u32) & 0x01) == 0x01 { + return true; + } + false + } + + #[inline] + pub fn framing_error(&self) -> bool { + if ((self.raw_res >> IrqResultMask::FramingError as u32) & 0x01) == 0x01 { + return true; + } + false + } + + #[inline] + pub fn parity_error(&self) -> bool { + if ((self.raw_res >> IrqResultMask::ParityError as u32) & 0x01) == 0x01 { + return true; + } + false + } + + #[inline] + pub fn timeout(&self) -> bool { + if ((self.raw_res >> IrqResultMask::Timeout as u32) & 0x01) == 0x01 { + return true; + } + false + } +} + +#[derive(Debug, PartialEq)] +enum IrqReceptionMode { + Idle, + Pending, +} + +//================================================================================================== +// UART implementation +//================================================================================================== + +/// Type erased variant of a UART. Can be created with the [`Uart::downgrade`] function. +pub struct UartBase { + uart: Uart, + tx: Tx, + rx: Rx, +} +/// Serial abstraction. Entry point to create a new UART +pub struct Uart { + uart_base: UartBase, + pins: Pins, +} + +/// UART using the IRQ capabilities of the peripheral. Can be created with the +/// [`Uart::into_uart_with_irq`] function. +pub struct UartWithIrq { + irq_base: UartWithIrqBase, + pins: Pins, +} + +/// Type-erased UART using the IRQ capabilities of the peripheral. Can be created with the +/// [`UartWithIrq::downgrade`] function. +pub struct UartWithIrqBase { + pub uart: UartBase, + irq_info: IrqInfo, +} + +/// Serial receiver +pub struct Rx { + _usart: PhantomData, +} + +/// Serial transmitter +pub struct Tx { + _usart: PhantomData, +} + +impl Rx { + fn new() -> Self { + Self { + _usart: PhantomData, + } + } +} + +impl Tx { + fn new() -> Self { + Self { + _usart: PhantomData, + } + } +} + +pub trait Instance: Deref { + fn ptr() -> *const uart_base::RegisterBlock; + const IDX: u8; +} + +impl UartBase { + /// This function assumes that the peripheral clock was alredy enabled + /// in the SYSCONFIG register + fn init(self, config: Config, sys_clk: Hertz) -> Self { + let baud_multiplier = match config.baud8 { + false => 16, + true => 8, + }; + let x = sys_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32; + let integer_part = floorf(x) as u32; + let frac = floorf(64.0 * (x - integer_part as f32) + 0.5) as u32; + self.uart + .clkscale() + .write(|w| unsafe { w.bits(integer_part * 64 + frac) }); + + let (paren, pareven) = match config.parity { + Parity::None => (false, false), + Parity::Odd => (true, false), + Parity::Even => (true, true), + }; + let stopbits = match config.stopbits { + StopBits::One => false, + StopBits::Two => true, + }; + let wordsize = config.wordsize as u8; + let baud8 = config.baud8; + self.uart.ctrl().write(|w| { + w.paren().bit(paren); + w.pareven().bit(pareven); + w.stopbits().bit(stopbits); + w.baud8().bit(baud8); + unsafe { w.wordsize().bits(wordsize) } + }); + let (txenb, rxenb) = (config.enable_tx, config.enable_rx); + // Clear the FIFO + self.uart.fifo_clr().write(|w| { + w.rxfifo().set_bit(); + w.txfifo().set_bit() + }); + self.uart.enable().write(|w| { + w.rxenable().bit(rxenb); + w.txenable().bit(txenb) + }); + self + } + + #[inline] + pub fn enable_rx(&mut self) { + self.uart.enable().modify(|_, w| w.rxenable().set_bit()); + } + + #[inline] + pub fn disable_rx(&mut self) { + self.uart.enable().modify(|_, w| w.rxenable().clear_bit()); + } + + #[inline] + pub fn enable_tx(&mut self) { + self.uart.enable().modify(|_, w| w.txenable().set_bit()); + } + + #[inline] + pub fn disable_tx(&mut self) { + self.uart.enable().modify(|_, w| w.txenable().clear_bit()); + } + + #[inline] + pub fn clear_rx_fifo(&mut self) { + self.uart.fifo_clr().write(|w| w.rxfifo().set_bit()); + } + + #[inline] + pub fn clear_tx_fifo(&mut self) { + self.uart.fifo_clr().write(|w| w.txfifo().set_bit()); + } + + #[inline] + pub fn clear_rx_status(&mut self) { + self.uart.fifo_clr().write(|w| w.rxsts().set_bit()); + } + + #[inline] + pub fn clear_tx_status(&mut self) { + self.uart.fifo_clr().write(|w| w.txsts().set_bit()); + } + + pub fn listen(&self, event: Event) { + self.uart.irq_enb().modify(|_, w| match event { + Event::RxError => w.irq_rx_status().set_bit(), + Event::RxFifoHalfFull => w.irq_rx().set_bit(), + Event::RxTimeout => w.irq_rx_to().set_bit(), + Event::TxEmpty => w.irq_tx_empty().set_bit(), + Event::TxError => w.irq_tx_status().set_bit(), + Event::TxFifoHalfFull => w.irq_tx().set_bit(), + Event::TxCts => w.irq_tx_cts().set_bit(), + }); + } + + pub fn unlisten(&self, event: Event) { + self.uart.irq_enb().modify(|_, w| match event { + Event::RxError => w.irq_rx_status().clear_bit(), + Event::RxFifoHalfFull => w.irq_rx().clear_bit(), + Event::RxTimeout => w.irq_rx_to().clear_bit(), + Event::TxEmpty => w.irq_tx_empty().clear_bit(), + Event::TxError => w.irq_tx_status().clear_bit(), + Event::TxFifoHalfFull => w.irq_tx().clear_bit(), + Event::TxCts => w.irq_tx_cts().clear_bit(), + }); + } + + pub fn release(self) -> UART { + // Clear the FIFO + self.uart.fifo_clr().write(|w| { + w.rxfifo().set_bit(); + w.txfifo().set_bit() + }); + self.uart.enable().write(|w| { + w.rxenable().clear_bit(); + w.txenable().clear_bit() + }); + self.uart + } + + pub fn split(self) -> (Tx, Rx) { + (self.tx, self.rx) + } +} + +impl Uart +where + UART: Instance, +{ + /// This function assumes that the peripheral clock was alredy enabled + /// in the SYSCONFIG register + fn init(mut self, config: Config, sys_clk: Hertz) -> Self { + self.uart_base = self.uart_base.init(config, sys_clk); + self + } + + /// If the IRQ capabilities of the peripheral are used, the UART needs to be converted + /// with this function + pub fn into_uart_with_irq( + self, + irq_cfg: IrqCfg, + sys_cfg: Option<&mut pac::Sysconfig>, + irq_sel: Option<&mut pac::Irqsel>, + ) -> UartWithIrq { + let (uart, pins) = self.downgrade_internal(); + UartWithIrq { + pins, + irq_base: UartWithIrqBase { + uart, + irq_info: IrqInfo { + rx_len: 0, + rx_idx: 0, + irq_cfg, + mode: IrqReceptionMode::Idle, + }, + } + .init(sys_cfg, irq_sel), + } + } + + #[inline] + pub fn enable_rx(&mut self) { + self.uart_base.enable_rx(); + } + + #[inline] + pub fn disable_rx(&mut self) { + self.uart_base.enable_rx(); + } + + #[inline] + pub fn enable_tx(&mut self) { + self.uart_base.enable_tx(); + } + + #[inline] + pub fn disable_tx(&mut self) { + self.uart_base.disable_tx(); + } + + #[inline] + pub fn clear_rx_fifo(&mut self) { + self.uart_base.clear_rx_fifo(); + } + + #[inline] + pub fn clear_tx_fifo(&mut self) { + self.uart_base.clear_tx_fifo(); + } + + #[inline] + pub fn clear_rx_status(&mut self) { + self.uart_base.clear_rx_status(); + } + + #[inline] + pub fn clear_tx_status(&mut self) { + self.uart_base.clear_tx_status(); + } + + pub fn listen(&self, event: Event) { + self.uart_base.listen(event); + } + + pub fn unlisten(&self, event: Event) { + self.uart_base.unlisten(event); + } + + pub fn release(self) -> (UART, PINS) { + (self.uart_base.release(), self.pins) + } + + fn downgrade_internal(self) -> (UartBase, PINS) { + let base = UartBase { + uart: self.uart_base.uart, + tx: self.uart_base.tx, + rx: self.uart_base.rx, + }; + (base, self.pins) + } + + pub fn downgrade(self) -> UartBase { + UartBase { + uart: self.uart_base.uart, + tx: self.uart_base.tx, + rx: self.uart_base.rx, + } + } + + pub fn split(self) -> (Tx, Rx) { + self.uart_base.split() + } +} + +impl Instance for pac::Uarta { + fn ptr() -> *const uart_base::RegisterBlock { + pac::Uarta::ptr() as *const _ + } + const IDX: u8 = 0; +} + +impl Instance for pac::Uartb { + fn ptr() -> *const uart_base::RegisterBlock { + pac::Uartb::ptr() as *const _ + } + const IDX: u8 = 1; +} + +macro_rules! uart_impl { + ($($UARTX:path: ($uartx:ident, $clk_enb_enum:path),)+) => { + $( + + impl> Uart<$UARTX, PINS> { + pub fn $uartx( + uart: $UARTX, + pins: PINS, + config: impl Into, + syscfg: &mut pac::Sysconfig, + sys_clk: impl Into + ) -> Self + { + enable_peripheral_clock(syscfg, $clk_enb_enum); + Uart { + uart_base: UartBase { + uart, + tx: Tx::new(), + rx: Rx::new(), + }, + pins, + } + .init(config.into(), sys_clk.into()) + } + } + + )+ + } +} + +impl UartWithIrqBase { + fn init(self, sys_cfg: Option<&mut pac::Sysconfig>, irq_sel: Option<&mut pac::Irqsel>) -> Self { + if let Some(sys_cfg) = sys_cfg { + enable_peripheral_clock(sys_cfg, PeripheralClocks::Irqsel) + } + if let Some(irq_sel) = irq_sel { + if self.irq_info.irq_cfg.route { + irq_sel + .uart0(UART::IDX as usize) + .write(|w| unsafe { w.bits(self.irq_info.irq_cfg.irq as u32) }); + } + } + self + } + + /// This initializes a non-blocking read transfer using the IRQ capabilities of the UART + /// peripheral. + /// + /// The only required information is the maximum length for variable sized reception + /// or the expected length for fixed length reception. If variable sized packets are expected, + /// the timeout functionality of the IRQ should be enabled as well. After calling this function, + /// the [`irq_handler`](Self::irq_handler) function should be called in the user interrupt + /// handler to read the received packets and reinitiate another transfer if desired. + pub fn read_fixed_len_using_irq( + &mut self, + max_len: usize, + enb_timeout_irq: bool, + ) -> Result<(), Error> { + if self.irq_info.mode != IrqReceptionMode::Idle { + return Err(Error::TransferPending); + } + self.irq_info.mode = IrqReceptionMode::Pending; + self.irq_info.rx_idx = 0; + self.irq_info.rx_len = max_len; + self.uart.enable_rx(); + self.uart.enable_tx(); + self.enable_rx_irq_sources(enb_timeout_irq); + if self.irq_info.irq_cfg.enable { + unmask_irq(self.irq_info.irq_cfg.irq); + } + Ok(()) + } + + #[inline] + fn enable_rx_irq_sources(&mut self, timeout: bool) { + self.uart.uart.irq_enb().modify(|_, w| { + if timeout { + w.irq_rx_to().set_bit(); + } + w.irq_rx_status().set_bit(); + w.irq_rx().set_bit() + }); + } + + #[inline] + fn disable_rx_irq_sources(&mut self) { + self.uart.uart.irq_enb().modify(|_, w| { + w.irq_rx_to().clear_bit(); + w.irq_rx_status().clear_bit(); + w.irq_rx().clear_bit() + }); + } + + #[inline] + pub fn enable_tx(&mut self) { + self.uart.enable_tx() + } + + #[inline] + pub fn disable_tx(&mut self) { + self.uart.disable_tx() + } + + pub fn cancel_transfer(&mut self) { + // Disable IRQ + cortex_m::peripheral::NVIC::mask(self.irq_info.irq_cfg.irq); + self.disable_rx_irq_sources(); + self.uart.clear_tx_fifo(); + self.irq_info.rx_idx = 0; + self.irq_info.rx_len = 0; + } + + /// Default IRQ handler which can be used to read the packets arriving on the UART peripheral. + /// + /// If passed buffer is equal to or larger than the specified maximum length, an + /// [`Error::BufferTooShort`] will be returned + pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> { + if buf.len() < self.irq_info.rx_len { + return Err(Error::BufferTooShort); + } + + let irq_end = self.uart.uart.irq_end().read(); + let enb_status = self.uart.uart.enable().read(); + let rx_enabled = enb_status.rxenable().bit_is_set(); + let _tx_enabled = enb_status.txenable().bit_is_set(); + let read_handler = + |res: &mut IrqResult, read_res: nb::Result| -> Result, Error> { + match read_res { + Ok(byte) => Ok(Some(byte)), + Err(nb::Error::WouldBlock) => Ok(None), + Err(nb::Error::Other(e)) => match e { + Error::Overrun => { + res.set_result(IrqResultMask::Overflow); + Err(Error::IrqError) + } + Error::FramingError => { + res.set_result(IrqResultMask::FramingError); + Err(Error::IrqError) + } + Error::ParityError => { + res.set_result(IrqResultMask::ParityError); + Err(Error::IrqError) + } + _ => { + res.set_result(IrqResultMask::Unknown); + Err(Error::IrqError) + } + }, + } + }; + if irq_end.irq_rx().bit_is_set() { + // If this interrupt bit is set, the trigger level is available at the very least. + // Read everything as fast as possible + for _ in 0..core::cmp::min( + self.uart.uart.rxfifoirqtrg().read().bits() as usize, + self.irq_info.rx_len, + ) { + buf[self.irq_info.rx_idx] = (self.uart.uart.data().read().bits() & 0xff) as u8; + self.irq_info.rx_idx += 1; + } + + // While there is data in the FIFO, write it into the reception buffer + loop { + if self.irq_info.rx_idx == self.irq_info.rx_len { + self.irq_completion_handler(res); + return Ok(()); + } + if let Some(byte) = read_handler(res, self.uart.read())? { + buf[self.irq_info.rx_idx] = byte; + self.irq_info.rx_idx += 1; + } else { + break; + } + } + } + + // RX transfer not complete, check for RX errors + if (self.irq_info.rx_idx < self.irq_info.rx_len) && rx_enabled { + // Read status register again, might have changed since reading received data + let rx_status = self.uart.uart.rxstatus().read(); + res.clear_result(); + if rx_status.rxovr().bit_is_set() { + res.set_result(IrqResultMask::Overflow); + } + if rx_status.rxfrm().bit_is_set() { + res.set_result(IrqResultMask::FramingError); + } + if rx_status.rxpar().bit_is_set() { + res.set_result(IrqResultMask::ParityError); + } + if rx_status.rxbrk().bit_is_set() { + res.set_result(IrqResultMask::Break); + } + if rx_status.rxto().bit_is_set() { + // A timeout has occured but there might be some leftover data in the FIFO, + // so read that data as well + while let Some(byte) = read_handler(res, self.uart.read())? { + buf[self.irq_info.rx_idx] = byte; + self.irq_info.rx_idx += 1; + } + self.irq_completion_handler(res); + res.set_result(IrqResultMask::Timeout); + return Ok(()); + } + + // If it is not a timeout, it's an error + if res.raw_res != 0 { + self.disable_rx_irq_sources(); + return Err(Error::IrqError); + } + } + + // Clear the interrupt status bits + self.uart + .uart + .irq_clr() + .write(|w| unsafe { w.bits(irq_end.bits()) }); + Ok(()) + } + + fn irq_completion_handler(&mut self, res: &mut IrqResult) { + self.disable_rx_irq_sources(); + self.uart.disable_rx(); + res.bytes_read = self.irq_info.rx_idx; + res.clear_result(); + res.set_result(IrqResultMask::Complete); + self.irq_info.mode = IrqReceptionMode::Idle; + self.irq_info.rx_idx = 0; + self.irq_info.rx_len = 0; + } + + pub fn release(self) -> UART { + self.uart.release() + } +} + +impl UartWithIrq { + /// See [`UartWithIrqBase::read_fixed_len_using_irq`] doc + pub fn read_fixed_len_using_irq( + &mut self, + max_len: usize, + enb_timeout_irq: bool, + ) -> Result<(), Error> { + self.irq_base + .read_fixed_len_using_irq(max_len, enb_timeout_irq) + } + + pub fn cancel_transfer(&mut self) { + self.irq_base.cancel_transfer() + } + + /// See [`UartWithIrqBase::irq_handler`] doc + pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> { + self.irq_base.irq_handler(res, buf) + } + + pub fn release(self) -> (UART, PINS) { + (self.irq_base.release(), self.pins) + } + + pub fn downgrade(self) -> (UartWithIrqBase, PINS) { + (self.irq_base, self.pins) + } +} + +uart_impl! { + pac::Uarta: (uarta, clock::PeripheralClocks::Uart0), + pac::Uartb: (uartb, clock::PeripheralClocks::Uart1), +} + +impl Tx where Uart: Instance {} + +impl embedded_io::ErrorType for UartBase { + type Error = Error; +} + +impl embedded_hal_nb::serial::ErrorType for UartBase { + type Error = Error; +} + +impl embedded_hal_nb::serial::ErrorType for Rx { + type Error = Error; +} + +impl embedded_io::ErrorType for Rx { + type Error = Error; +} + +impl embedded_io::ErrorType for Tx { + type Error = Error; +} + +impl embedded_hal_nb::serial::ErrorType for Tx { + type Error = Error; +} + +impl embedded_hal_nb::serial::Write for Tx { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + let reader = unsafe { &(*Uart::ptr()) }.txstatus().read(); + if reader.wrrdy().bit_is_clear() { + return Err(nb::Error::WouldBlock); + } else { + // DPARITY bit not supported yet + unsafe { + // NOTE(unsafe) atomic write to data register + (*Uart::ptr()).data().write(|w| w.bits(word as u32)); + } + } + Ok(()) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + // SAFETY: Only TX related registers are used. + let reader = unsafe { &(*Uart::ptr()) }.txstatus().read(); + if reader.wrbusy().bit_is_set() { + return Err(nb::Error::WouldBlock); + } + Ok(()) + } +} + +impl embedded_io::Write for Tx { + fn write(&mut self, buf: &[u8]) -> Result { + if buf.is_empty() { + return Ok(0); + } + + for byte in buf.iter() { + nb::block!(>::write( + self, *byte + ))?; + } + + Ok(buf.len()) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + nb::block!(>::flush(self)) + } +} + +impl embedded_io::Write for UartBase { + fn write(&mut self, buf: &[u8]) -> Result { + self.tx.write(buf) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + self.tx.flush() + } +} + +impl embedded_hal_nb::serial::Read for UartBase { + fn read(&mut self) -> nb::Result { + self.rx.read() + } +} + +impl embedded_hal_nb::serial::Write for UartBase { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + self.tx.write(word) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.tx.flush() + } +} + +impl embedded_hal_nb::serial::Read for Rx { + fn read(&mut self) -> nb::Result { + let uart = unsafe { &(*Uart::ptr()) }; + let status_reader = uart.rxstatus().read(); + let err = if status_reader.rxovr().bit_is_set() { + Some(Error::Overrun) + } else if status_reader.rxfrm().bit_is_set() { + Some(Error::FramingError) + } else if status_reader.rxpar().bit_is_set() { + Some(Error::ParityError) + } else { + None + }; + if let Some(err) = err { + // The status code is always related to the next bit for the framing + // and parity status bits. We have to read the DATA register + // so that the next status reflects the next DATA word + // For overrun error, we read as well to clear the peripheral + uart.data().read().bits(); + Err(err.into()) + } else if status_reader.rdavl().bit_is_set() { + let data = uart.data().read().bits(); + Ok((data & 0xff) as u8) + } else { + Err(nb::Error::WouldBlock) + } + } +} + +impl embedded_io::Read for Rx { + fn read(&mut self, buf: &mut [u8]) -> Result { + if buf.is_empty() { + return Ok(0); + } + + for byte in buf.iter_mut() { + let w = nb::block!(>::read(self))?; + *byte = w; + } + + Ok(buf.len()) + } +} diff --git a/va108xx-hal/src/utility.rs b/va108xx-hal/src/utility.rs new file mode 100644 index 0000000..e23b586 --- /dev/null +++ b/va108xx-hal/src/utility.rs @@ -0,0 +1,16 @@ +//! # API for utility functions like the Error Detection and Correction (EDAC) block +//! +//! Some more information about the recommended scrub rates can be found on the +//! [Vorago White Paper website](https://www.voragotech.com/resources) in the +//! application note AN1212 +use crate::pac; + +/// Unmask and enable an IRQ with the given interrupt number +/// +/// ## Safety +/// +/// The unmask function can break mask-based critical sections +#[inline] +pub(crate) fn unmask_irq(irq: pac::Interrupt) { + unsafe { cortex_m::peripheral::NVIC::unmask(irq) }; +} diff --git a/va108xx-hal/tests/DueSerialTest/.gitignore b/va108xx-hal/tests/DueSerialTest/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/va108xx-hal/tests/DueSerialTest/.vscode/extensions.json b/va108xx-hal/tests/DueSerialTest/.vscode/extensions.json new file mode 100644 index 0000000..e80666b --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/va108xx-hal/tests/DueSerialTest/README.md b/va108xx-hal/tests/DueSerialTest/README.md new file mode 100644 index 0000000..c53cfa1 --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/README.md @@ -0,0 +1,2 @@ +This is a Platform IO test script for the Arduino Due which can be used to sent different kind +of strings via the serial interface (RX1 and TX1) to the Vorago board. diff --git a/va108xx-hal/tests/DueSerialTest/include/README b/va108xx-hal/tests/DueSerialTest/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/va108xx-hal/tests/DueSerialTest/lib/README b/va108xx-hal/tests/DueSerialTest/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/va108xx-hal/tests/DueSerialTest/platformio.ini b/va108xx-hal/tests/DueSerialTest/platformio.ini new file mode 100644 index 0000000..a448357 --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/platformio.ini @@ -0,0 +1,15 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:due] +platform = atmelsam +board = due +framework = arduino +monitor_speed = 115200 diff --git a/va108xx-hal/tests/DueSerialTest/src/main.cpp b/va108xx-hal/tests/DueSerialTest/src/main.cpp new file mode 100644 index 0000000..2fbed5f --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/src/main.cpp @@ -0,0 +1,78 @@ +#include + +enum SendModes { + ECHO, + ONLY_WRITE, + ONLY_READ, + WRITE_READ +}; + +enum StringModes { + FIXED, + VARIABLE +}; + +// Configure the test application here +SendModes SEND_MODE = SendModes::WRITE_READ; +StringModes STRING_MODE = StringModes::VARIABLE; +uint8_t STRING_IDX = 0; + +String STRINGS[4] = { + "$Hi\n", + "$Hello\n", + "$Hello World\n", + "$Hello and Merry Christmas to all of you!\n" +}; + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + Serial.println("Starting Arduino Serial Test script.."); + Serial1.begin(115200); + if(STRING_MODE == StringModes::VARIABLE) { + STRING_IDX = 0; + } + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + static byte ICOMING_BYTE = 0; + static uint32_t GLOBAL_IDX = 0; + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + // put your main code here, to run repeatedly: + // send data only when you receive data: + if (SEND_MODE == SendModes::ONLY_WRITE or SEND_MODE == SendModes::WRITE_READ) { + Serial.println("Sending string.."); + Serial1.write(STRINGS[STRING_IDX].c_str()); + if(STRING_MODE == StringModes::VARIABLE) { + STRING_IDX += 1; + if(STRING_IDX > 3) { + STRING_IDX = 0; + } + } + } + if( + SEND_MODE == SendModes::WRITE_READ or + SEND_MODE == SendModes::ONLY_READ or + SEND_MODE == SendModes::ECHO + ) { + if (Serial1.available() > 0) { + // read the incoming byte: + String readString = Serial1.readStringUntil('\n'); + + Serial.print(GLOBAL_IDX); + Serial.print(" - "); + GLOBAL_IDX++; + // say what you got: + Serial.print("I received: "); + Serial.println(readString); + if(SEND_MODE == SendModes::ECHO) { + delay(200); + Serial.println("Sending back echo message"); + String sendBack = readString + '\n'; + Serial1.write(sendBack.c_str()); + } + } + } + delay(3000); +} diff --git a/va108xx-hal/tests/DueSerialTest/test/README b/va108xx-hal/tests/DueSerialTest/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/va108xx-hal/tests/DueSerialTest/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/va108xx/.github/bors.toml b/va108xx/.github/bors.toml new file mode 100644 index 0000000..1779788 --- /dev/null +++ b/va108xx/.github/bors.toml @@ -0,0 +1,2 @@ +status = ["ci"] +delete_merged_branches = true diff --git a/va108xx/.github/workflows/changelog.yml b/va108xx/.github/workflows/changelog.yml new file mode 100644 index 0000000..dbba297 --- /dev/null +++ b/va108xx/.github/workflows/changelog.yml @@ -0,0 +1,20 @@ +on: + pull_request_target: + +name: Changelog check + +jobs: + changelog: + name: Changelog check + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Changelog updated + uses: Zomzog/changelog-checker@v1.2.0 + with: + fileName: CHANGELOG.md + noChangelogLabel: no changelog + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/va108xx/.github/workflows/ci.yml b/va108xx/.github/workflows/ci.yml new file mode 100644 index 0000000..393eecb --- /dev/null +++ b/va108xx/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +on: [push] + +name: build + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - uses: actions-rs/cargo@v1 + with: + command: check + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + + ci: + if: ${{ success() }} + # all new jobs must be added to this list + needs: [check, fmt, clippy] + runs-on: ubuntu-latest + steps: + - name: CI succeeded + run: exit 0 \ No newline at end of file diff --git a/va108xx/.gitignore b/va108xx/.gitignore new file mode 100644 index 0000000..f2e972d --- /dev/null +++ b/va108xx/.gitignore @@ -0,0 +1,6 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/va108xx/CHANGELOG.md b/va108xx/CHANGELOG.md new file mode 100644 index 0000000..4ec67ac --- /dev/null +++ b/va108xx/CHANGELOG.md @@ -0,0 +1,69 @@ +Change Log +======= + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [unreleased] + +## [v0.2.4] + +- Added missing bitfield `CSDTRG2` in `CSD_CTRL` register of `TIM0` peripheral + +## [v0.2.3] + +- Added peripheral reset fields for `PERIPHERAL_RESET` register + +## [v0.2.2] + +- README tweks + +## [v0.2.1] + +- Some README and Manifest weaks + +## [v0.2.0] + +- Authorative repository was transferred to https://egit.irs.uni-stuttgart.de/rust/va108xx-rs but + there still will be a GitHub mirror. Project relicensed as Apache-2.0 only + +## [v0.1.3] + +### Added + +- Added two missing bit fields for I2CA STATUS register: I2CIDLE and IDLE + +### Fixed + +- Made I2CA STATUS register read-only + +## [v0.1.2] + +### Fixed + +- Generated with patched version of `svd2rust`: See + https://github.com/rust-embedded/svd2rust/pull/549 for more details. + Some bitmasks were missing from register reader definitions. + +## [v0.1.1] + +- Relicensed under dual Apache-2.0 / MIT license + +### Changed + +- SVD file handling improved and new fields added for the peripheral + clock enable register + +### Added + +- Helper script to automate all steps for PAC generation +- Added badges for README + +## [v0.1.0] + +### Added + +- First version of the PAC which builds. Uses a patched version + of `svd2rust`: https://github.com/rust-embedded/svd2rust diff --git a/va108xx/Cargo.toml b/va108xx/Cargo.toml new file mode 100644 index 0000000..fbd2d35 --- /dev/null +++ b/va108xx/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "va108xx" +version = "0.3.0" +authors = ["Robin Mueller "] +edition = "2021" +description = "PAC for the Vorago VA108xx family of microcontrollers" +homepage = "https://egit.irs.uni-stuttgart.de/rust/va108xx" +repository = "https://egit.irs.uni-stuttgart.de/rust/va108xx" +license = "Apache-2.0" +keywords = ["no-std", "arm", "cortex-m", "vorago", "va108xx"] +categories = ["embedded", "no-std", "hardware-support"] + +[dependencies] +cortex-m = "0.7" +vcell = "0.1.3" +critical-section = { version = "1", optional = true } + +[dependencies.cortex-m-rt] +optional = true +version = ">=0.6.15,<0.8" + +[features] +rt = ["cortex-m-rt/device"] diff --git a/va108xx/LICENSE-APACHE b/va108xx/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/va108xx/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/va108xx/NOTICE b/va108xx/NOTICE new file mode 100644 index 0000000..35769f0 --- /dev/null +++ b/va108xx/NOTICE @@ -0,0 +1,3 @@ +Peripheral access crate for the Vorago VA108xx family microcontrollers + +This software contains code developed at the University of Stuttgart. \ No newline at end of file diff --git a/va108xx/README.md b/va108xx/README.md new file mode 100644 index 0000000..2b62b07 --- /dev/null +++ b/va108xx/README.md @@ -0,0 +1,64 @@ +[![Crates.io](https://img.shields.io/crates/v/va108xx)](https://crates.io/crates/va108xx) +[![build](https://github.com/us-irs/va108xx-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/us-irs/va108xx-rs/actions/workflows/ci.yml) +[![docs.rs](https://img.shields.io/docsrs/va108xx)](https://docs.rs/va108xx) + +# PAC for the Vorago VA108xx microcontroller family + +This repository contains the Peripheral Access Crate (PAC) for +Voragos VA108xx series of Cortex-M0 based microcontrollers. + +The crate was generated using [`svd2rust`](https://github.com/rust-embedded/svd2rust). + +If you are interested in higher-level abstractions, it is recommended you visit +the [`va108xx-hal` HAL crate](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal) and +the [`vorago-reb1` BSP crate](https://github.com/robamu-org/vorago-reb1-rs) which build on top of +this PAC and provide application examples as well. + +## Usage + +To use this crate, add this to your `Cargo.toml` + +```toml +[dependencies.va108xx] +version = "" +features = ["rt"] +``` + +The `rt` feature is optional and recommended. It brings in support for `cortex-m-rt`. + +For full details on the autgenerated API, please see the +[svd2rust documentation](https://docs.rs/svd2rust/0.19.0/svd2rust/#peripheral-api). + +## Regenerating the PAC + +If you want to re-generate the PAC, for example if the register file `va416xx.svd` changes +or the `svd2rust` version is updated, you can do some using the following these steps: + +1. Make sure all necessary tools are installed: [`svd2rust`](https://docs.rs/svd2rust/latest/svd2rust/), + [`svdtools`](https://github.com/rust-embedded/svdtools) and [`form`](https://crates.io/crates/form). + You can install all tools with `cargo`: + + ```sh + cargo install --locked svd2rust svdtools form + ``` + +2. Patch the vendor-provided SVD file `svd/va41xx.svd`. This can be done using `svdtools` in + conjunction with the `svd/va108xx-patch.yml` file. + + ```sh + svdtools patch svd/va108xx-patch.yml + ``` + +3. Use `svd2rust` to generate the Rust library + + ```sh + svd2rust -i svd/va108xx.svd.patched + ``` + +4. Use the `form` tool to split the generated `lib.rs` into individual modules. + + ```sh + form -i lib.rs -o src/ + ``` + +The `gen-helper.sh` automates steps 2-4. diff --git a/va108xx/automation/Dockerfile b/va108xx/automation/Dockerfile new file mode 100644 index 0000000..5fb8a3d --- /dev/null +++ b/va108xx/automation/Dockerfile @@ -0,0 +1,11 @@ +# Run the following commands from root directory to build and run locally +# docker build -f automation/Dockerfile -t . +# docker run -it +FROM rust:latest +RUN apt-get update +RUN apt-get --yes upgrade +# tzdata is a dependency, won't install otherwise +ARG DEBIAN_FRONTEND=noninteractive + +RUN rustup target add thumbv6m-none-eabi && \ + rustup component add rustfmt clippy diff --git a/va108xx/automation/Jenkinsfile b/va108xx/automation/Jenkinsfile new file mode 100644 index 0000000..cad5b57 --- /dev/null +++ b/va108xx/automation/Jenkinsfile @@ -0,0 +1,39 @@ +pipeline { + agent any + + stages { + stage('Clippy') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo clippy' + } + } + stage('Rustfmt') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo fmt' + } + } + stage('Check') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo check --target thumbv6m-none-eabi' + } + } + } +} \ No newline at end of file diff --git a/va108xx/build.rs b/va108xx/build.rs new file mode 100644 index 0000000..d0781ac --- /dev/null +++ b/va108xx/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/va108xx/device.x b/va108xx/device.x new file mode 100644 index 0000000..a191a90 --- /dev/null +++ b/va108xx/device.x @@ -0,0 +1,33 @@ +PROVIDE(OC0 = DefaultHandler); +PROVIDE(OC1 = DefaultHandler); +PROVIDE(OC2 = DefaultHandler); +PROVIDE(OC3 = DefaultHandler); +PROVIDE(OC4 = DefaultHandler); +PROVIDE(OC5 = DefaultHandler); +PROVIDE(OC6 = DefaultHandler); +PROVIDE(OC7 = DefaultHandler); +PROVIDE(OC8 = DefaultHandler); +PROVIDE(OC9 = DefaultHandler); +PROVIDE(OC10 = DefaultHandler); +PROVIDE(OC11 = DefaultHandler); +PROVIDE(OC12 = DefaultHandler); +PROVIDE(OC13 = DefaultHandler); +PROVIDE(OC14 = DefaultHandler); +PROVIDE(OC15 = DefaultHandler); +PROVIDE(OC16 = DefaultHandler); +PROVIDE(OC17 = DefaultHandler); +PROVIDE(OC18 = DefaultHandler); +PROVIDE(OC19 = DefaultHandler); +PROVIDE(OC20 = DefaultHandler); +PROVIDE(OC21 = DefaultHandler); +PROVIDE(OC22 = DefaultHandler); +PROVIDE(OC23 = DefaultHandler); +PROVIDE(OC24 = DefaultHandler); +PROVIDE(OC25 = DefaultHandler); +PROVIDE(OC26 = DefaultHandler); +PROVIDE(OC27 = DefaultHandler); +PROVIDE(OC28 = DefaultHandler); +PROVIDE(OC29 = DefaultHandler); +PROVIDE(OC30 = DefaultHandler); +PROVIDE(OC31 = DefaultHandler); + diff --git a/va108xx/gen-helper.sh b/va108xx/gen-helper.sh new file mode 100755 index 0000000..ed8cfb9 --- /dev/null +++ b/va108xx/gen-helper.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# 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 + +svdtools patch svd/va108xx-patch.yml +# See https://github.com/rust-embedded/svd2rust/issues/830 for required re-export. +${svd2rust_bin} --reexport-interrupt -i svd/va108xx.svd.patched + +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/va108xx/src/generic.rs b/va108xx/src/generic.rs new file mode 100644 index 0000000..45ebed1 --- /dev/null +++ b/va108xx/src/generic.rs @@ -0,0 +1,618 @@ +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 = " 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) + where + F: FnOnce(&mut W) -> &mut W, + { + self.register.set( + f(&mut W { + bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP + | REG::ZERO_TO_MODIFY_FIELDS_BITMAP, + _reg: marker::PhantomData, + }) + .bits, + ); + } +} +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) + where + F: FnOnce(&mut W) -> &mut W, + { + self.register.set( + f(&mut W { + bits: REG::Ux::default(), + _reg: marker::PhantomData, + }) + .bits, + ); + } +} +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) + where + for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W, + { + let bits = self.register.get(); + self.register.set( + 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, + ); + } +} +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) + } +} +#[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<'a, REG, const WI: u8, FI, Safety> FieldWriter<'a, 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 + } +} diff --git a/va108xx/src/generic/raw.rs b/va108xx/src/generic/raw.rs new file mode 100644 index 0000000..81f5779 --- /dev/null +++ b/va108xx/src/generic/raw.rs @@ -0,0 +1,93 @@ +use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable}; +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, + } + } +} +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, + } + } +} +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/va108xx/src/i2ca.rs b/va108xx/src/i2ca.rs new file mode 100644 index 0000000..7c03e50 --- /dev/null +++ b/va108xx/src/i2ca.rs @@ -0,0 +1,452 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + ctrl: Ctrl, + clkscale: Clkscale, + words: Words, + address: Address, + data: Data, + cmd: Cmd, + status: Status, + state: State, + txcount: Txcount, + rxcount: Rxcount, + irq_enb: IrqEnb, + irq_raw: IrqRaw, + irq_end: IrqEnd, + irq_clr: IrqClr, + rxfifoirqtrg: Rxfifoirqtrg, + txfifoirqtrg: Txfifoirqtrg, + fifo_clr: FifoClr, + tmconfig: Tmconfig, + clktolimit: Clktolimit, + _reserved19: [u8; 0xb4], + s0_ctrl: S0Ctrl, + s0_maxwords: S0Maxwords, + s0_address: S0Address, + s0_addressmask: S0Addressmask, + s0_data: S0Data, + s0_lastaddress: S0Lastaddress, + s0_status: S0Status, + s0_state: S0State, + s0_txcount: S0Txcount, + s0_rxcount: S0Rxcount, + s0_irq_enb: S0IrqEnb, + s0_irq_raw: S0IrqRaw, + s0_irq_end: S0IrqEnd, + s0_irq_clr: S0IrqClr, + s0_rxfifoirqtrg: S0Rxfifoirqtrg, + s0_txfifoirqtrg: S0Txfifoirqtrg, + s0_fifo_clr: S0FifoClr, + s0_addressb: S0Addressb, + s0_addressmaskb: S0Addressmaskb, + _reserved38: [u8; 0x0eb0], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Control Register"] + #[inline(always)] + pub const fn ctrl(&self) -> &Ctrl { + &self.ctrl + } + #[doc = "0x04 - Clock Scale divide value"] + #[inline(always)] + pub const fn clkscale(&self) -> &Clkscale { + &self.clkscale + } + #[doc = "0x08 - Word Count value"] + #[inline(always)] + pub const fn words(&self) -> &Words { + &self.words + } + #[doc = "0x0c - I2C Address value"] + #[inline(always)] + pub const fn address(&self) -> &Address { + &self.address + } + #[doc = "0x10 - Data Input/Output"] + #[inline(always)] + pub const fn data(&self) -> &Data { + &self.data + } + #[doc = "0x14 - Command Register"] + #[inline(always)] + pub const fn cmd(&self) -> &Cmd { + &self.cmd + } + #[doc = "0x18 - I2C Controller Status Register"] + #[inline(always)] + pub const fn status(&self) -> &Status { + &self.status + } + #[doc = "0x1c - Internal STATE of I2C Master Controller"] + #[inline(always)] + pub const fn state(&self) -> &State { + &self.state + } + #[doc = "0x20 - TX Count Register"] + #[inline(always)] + pub const fn txcount(&self) -> &Txcount { + &self.txcount + } + #[doc = "0x24 - RX Count Register"] + #[inline(always)] + pub const fn rxcount(&self) -> &Rxcount { + &self.rxcount + } + #[doc = "0x28 - Interrupt Enable Register"] + #[inline(always)] + pub const fn irq_enb(&self) -> &IrqEnb { + &self.irq_enb + } + #[doc = "0x2c - Raw Interrupt Status Register"] + #[inline(always)] + pub const fn irq_raw(&self) -> &IrqRaw { + &self.irq_raw + } + #[doc = "0x30 - Enabled Interrupt Status Register"] + #[inline(always)] + pub const fn irq_end(&self) -> &IrqEnd { + &self.irq_end + } + #[doc = "0x34 - Clear Interrupt Status Register"] + #[inline(always)] + pub const fn irq_clr(&self) -> &IrqClr { + &self.irq_clr + } + #[doc = "0x38 - Rx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn rxfifoirqtrg(&self) -> &Rxfifoirqtrg { + &self.rxfifoirqtrg + } + #[doc = "0x3c - Tx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn txfifoirqtrg(&self) -> &Txfifoirqtrg { + &self.txfifoirqtrg + } + #[doc = "0x40 - Clear FIFO Register"] + #[inline(always)] + pub const fn fifo_clr(&self) -> &FifoClr { + &self.fifo_clr + } + #[doc = "0x44 - Timing Config Register"] + #[inline(always)] + pub const fn tmconfig(&self) -> &Tmconfig { + &self.tmconfig + } + #[doc = "0x48 - Clock Low Timeout Limit Register"] + #[inline(always)] + pub const fn clktolimit(&self) -> &Clktolimit { + &self.clktolimit + } + #[doc = "0x100 - Slave Control Register"] + #[inline(always)] + pub const fn s0_ctrl(&self) -> &S0Ctrl { + &self.s0_ctrl + } + #[doc = "0x104 - Slave MaxWords Register"] + #[inline(always)] + pub const fn s0_maxwords(&self) -> &S0Maxwords { + &self.s0_maxwords + } + #[doc = "0x108 - Slave I2C Address Value"] + #[inline(always)] + pub const fn s0_address(&self) -> &S0Address { + &self.s0_address + } + #[doc = "0x10c - Slave I2C Address Mask value"] + #[inline(always)] + pub const fn s0_addressmask(&self) -> &S0Addressmask { + &self.s0_addressmask + } + #[doc = "0x110 - Slave Data Input/Output"] + #[inline(always)] + pub const fn s0_data(&self) -> &S0Data { + &self.s0_data + } + #[doc = "0x114 - Slave I2C Last Address value"] + #[inline(always)] + pub const fn s0_lastaddress(&self) -> &S0Lastaddress { + &self.s0_lastaddress + } + #[doc = "0x118 - Slave I2C Controller Status Register"] + #[inline(always)] + pub const fn s0_status(&self) -> &S0Status { + &self.s0_status + } + #[doc = "0x11c - Internal STATE of I2C Slave Controller"] + #[inline(always)] + pub const fn s0_state(&self) -> &S0State { + &self.s0_state + } + #[doc = "0x120 - Slave TX Count Register"] + #[inline(always)] + pub const fn s0_txcount(&self) -> &S0Txcount { + &self.s0_txcount + } + #[doc = "0x124 - Slave RX Count Register"] + #[inline(always)] + pub const fn s0_rxcount(&self) -> &S0Rxcount { + &self.s0_rxcount + } + #[doc = "0x128 - Slave Interrupt Enable Register"] + #[inline(always)] + pub const fn s0_irq_enb(&self) -> &S0IrqEnb { + &self.s0_irq_enb + } + #[doc = "0x12c - Slave Raw Interrupt Status Register"] + #[inline(always)] + pub const fn s0_irq_raw(&self) -> &S0IrqRaw { + &self.s0_irq_raw + } + #[doc = "0x130 - Slave Enabled Interrupt Status Register"] + #[inline(always)] + pub const fn s0_irq_end(&self) -> &S0IrqEnd { + &self.s0_irq_end + } + #[doc = "0x134 - Slave Clear Interrupt Status Register"] + #[inline(always)] + pub const fn s0_irq_clr(&self) -> &S0IrqClr { + &self.s0_irq_clr + } + #[doc = "0x138 - Slave Rx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn s0_rxfifoirqtrg(&self) -> &S0Rxfifoirqtrg { + &self.s0_rxfifoirqtrg + } + #[doc = "0x13c - Slave Tx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn s0_txfifoirqtrg(&self) -> &S0Txfifoirqtrg { + &self.s0_txfifoirqtrg + } + #[doc = "0x140 - Slave Clear FIFO Register"] + #[inline(always)] + pub const fn s0_fifo_clr(&self) -> &S0FifoClr { + &self.s0_fifo_clr + } + #[doc = "0x144 - Slave I2C Address B Value"] + #[inline(always)] + pub const fn s0_addressb(&self) -> &S0Addressb { + &self.s0_addressb + } + #[doc = "0x148 - Slave I2C Address B Mask value"] + #[inline(always)] + pub const fn s0_addressmaskb(&self) -> &S0Addressmaskb { + &self.s0_addressmaskb + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "CTRL (rw) register accessor: Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ctrl`] +module"] +#[doc(alias = "CTRL")] +pub type Ctrl = crate::Reg; +#[doc = "Control Register"] +pub mod ctrl; +#[doc = "CLKSCALE (rw) register accessor: Clock Scale divide value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkscale::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkscale::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@clkscale`] +module"] +#[doc(alias = "CLKSCALE")] +pub type Clkscale = crate::Reg; +#[doc = "Clock Scale divide value"] +pub mod clkscale; +#[doc = "WORDS (rw) register accessor: Word Count value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`words::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`words::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@words`] +module"] +#[doc(alias = "WORDS")] +pub type Words = crate::Reg; +#[doc = "Word Count value"] +pub mod words; +#[doc = "ADDRESS (rw) register accessor: I2C Address value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`address::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`address::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@address`] +module"] +#[doc(alias = "ADDRESS")] +pub type Address = crate::Reg; +#[doc = "I2C Address value"] +pub mod address; +#[doc = "DATA (rw) register accessor: Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@data`] +module"] +#[doc(alias = "DATA")] +pub type Data = crate::Reg; +#[doc = "Data Input/Output"] +pub mod data; +#[doc = "CMD (rw) register accessor: Command Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cmd::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cmd::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@cmd`] +module"] +#[doc(alias = "CMD")] +pub type Cmd = crate::Reg; +#[doc = "Command Register"] +pub mod cmd; +#[doc = "STATUS (r) register accessor: I2C Controller Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`status::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@status`] +module"] +#[doc(alias = "STATUS")] +pub type Status = crate::Reg; +#[doc = "I2C Controller Status Register"] +pub mod status; +#[doc = "STATE (r) register accessor: Internal STATE of I2C Master Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@state`] +module"] +#[doc(alias = "STATE")] +pub type State = crate::Reg; +#[doc = "Internal STATE of I2C Master Controller"] +pub mod state; +#[doc = "TXCOUNT (r) register accessor: TX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txcount::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txcount`] +module"] +#[doc(alias = "TXCOUNT")] +pub type Txcount = crate::Reg; +#[doc = "TX Count Register"] +pub mod txcount; +#[doc = "RXCOUNT (r) register accessor: RX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxcount::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxcount`] +module"] +#[doc(alias = "RXCOUNT")] +pub type Rxcount = crate::Reg; +#[doc = "RX Count Register"] +pub mod rxcount; +#[doc = "IRQ_ENB (rw) register accessor: Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_enb`] +module"] +#[doc(alias = "IRQ_ENB")] +pub type IrqEnb = crate::Reg; +#[doc = "Interrupt Enable Register"] +pub mod irq_enb; +pub use irq_enb as irq_raw; +pub use irq_enb as irq_end; +pub use irq_enb as irq_clr; +pub use IrqEnb as IrqRaw; +pub use IrqEnb as IrqEnd; +pub use IrqEnb as IrqClr; +#[doc = "RXFIFOIRQTRG (rw) register accessor: Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxfifoirqtrg`] +module"] +#[doc(alias = "RXFIFOIRQTRG")] +pub type Rxfifoirqtrg = crate::Reg; +#[doc = "Rx FIFO IRQ Trigger Level"] +pub mod rxfifoirqtrg; +#[doc = "TXFIFOIRQTRG (rw) register accessor: Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txfifoirqtrg`] +module"] +#[doc(alias = "TXFIFOIRQTRG")] +pub type Txfifoirqtrg = crate::Reg; +#[doc = "Tx FIFO IRQ Trigger Level"] +pub mod txfifoirqtrg; +#[doc = "FIFO_CLR (w) register accessor: Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@fifo_clr`] +module"] +#[doc(alias = "FIFO_CLR")] +pub type FifoClr = crate::Reg; +#[doc = "Clear FIFO Register"] +pub mod fifo_clr; +#[doc = "TMCONFIG (rw) register accessor: Timing Config Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tmconfig::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tmconfig::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@tmconfig`] +module"] +#[doc(alias = "TMCONFIG")] +pub type Tmconfig = crate::Reg; +#[doc = "Timing Config Register"] +pub mod tmconfig; +#[doc = "CLKTOLIMIT (rw) register accessor: Clock Low Timeout Limit Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clktolimit::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clktolimit::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@clktolimit`] +module"] +#[doc(alias = "CLKTOLIMIT")] +pub type Clktolimit = crate::Reg; +#[doc = "Clock Low Timeout Limit Register"] +pub mod clktolimit; +#[doc = "S0_CTRL (rw) register accessor: Slave Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_ctrl::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_ctrl::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_ctrl`] +module"] +#[doc(alias = "S0_CTRL")] +pub type S0Ctrl = crate::Reg; +#[doc = "Slave Control Register"] +pub mod s0_ctrl; +#[doc = "S0_MAXWORDS (rw) register accessor: Slave MaxWords Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_maxwords::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_maxwords::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_maxwords`] +module"] +#[doc(alias = "S0_MAXWORDS")] +pub type S0Maxwords = crate::Reg; +#[doc = "Slave MaxWords Register"] +pub mod s0_maxwords; +#[doc = "S0_ADDRESS (rw) register accessor: Slave I2C Address Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_address::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_address::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_address`] +module"] +#[doc(alias = "S0_ADDRESS")] +pub type S0Address = crate::Reg; +#[doc = "Slave I2C Address Value"] +pub mod s0_address; +#[doc = "S0_ADDRESSMASK (rw) register accessor: Slave I2C Address Mask value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressmask::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressmask::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_addressmask`] +module"] +#[doc(alias = "S0_ADDRESSMASK")] +pub type S0Addressmask = crate::Reg; +#[doc = "Slave I2C Address Mask value"] +pub mod s0_addressmask; +#[doc = "S0_DATA (rw) register accessor: Slave Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_data::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_data::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_data`] +module"] +#[doc(alias = "S0_DATA")] +pub type S0Data = crate::Reg; +#[doc = "Slave Data Input/Output"] +pub mod s0_data; +#[doc = "S0_LASTADDRESS (r) register accessor: Slave I2C Last Address value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_lastaddress::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_lastaddress`] +module"] +#[doc(alias = "S0_LASTADDRESS")] +pub type S0Lastaddress = crate::Reg; +#[doc = "Slave I2C Last Address value"] +pub mod s0_lastaddress; +#[doc = "S0_STATUS (r) register accessor: Slave I2C Controller Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_status::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_status`] +module"] +#[doc(alias = "S0_STATUS")] +pub type S0Status = crate::Reg; +#[doc = "Slave I2C Controller Status Register"] +pub mod s0_status; +#[doc = "S0_STATE (r) register accessor: Internal STATE of I2C Slave Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_state::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_state`] +module"] +#[doc(alias = "S0_STATE")] +pub type S0State = crate::Reg; +#[doc = "Internal STATE of I2C Slave Controller"] +pub mod s0_state; +#[doc = "S0_TXCOUNT (r) register accessor: Slave TX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_txcount::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_txcount`] +module"] +#[doc(alias = "S0_TXCOUNT")] +pub type S0Txcount = crate::Reg; +#[doc = "Slave TX Count Register"] +pub mod s0_txcount; +#[doc = "S0_RXCOUNT (r) register accessor: Slave RX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_rxcount::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_rxcount`] +module"] +#[doc(alias = "S0_RXCOUNT")] +pub type S0Rxcount = crate::Reg; +#[doc = "Slave RX Count Register"] +pub mod s0_rxcount; +#[doc = "S0_IRQ_ENB (rw) register accessor: Slave Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_irq_enb`] +module"] +#[doc(alias = "S0_IRQ_ENB")] +pub type S0IrqEnb = crate::Reg; +#[doc = "Slave Interrupt Enable Register"] +pub mod s0_irq_enb; +pub use s0_irq_enb as s0_irq_raw; +pub use s0_irq_enb as s0_irq_end; +pub use s0_irq_enb as s0_irq_clr; +pub use S0IrqEnb as S0IrqRaw; +pub use S0IrqEnb as S0IrqEnd; +pub use S0IrqEnb as S0IrqClr; +#[doc = "S0_RXFIFOIRQTRG (rw) register accessor: Slave Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_rxfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_rxfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_rxfifoirqtrg`] +module"] +#[doc(alias = "S0_RXFIFOIRQTRG")] +pub type S0Rxfifoirqtrg = crate::Reg; +#[doc = "Slave Rx FIFO IRQ Trigger Level"] +pub mod s0_rxfifoirqtrg; +#[doc = "S0_TXFIFOIRQTRG (rw) register accessor: Slave Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_txfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_txfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_txfifoirqtrg`] +module"] +#[doc(alias = "S0_TXFIFOIRQTRG")] +pub type S0Txfifoirqtrg = crate::Reg; +#[doc = "Slave Tx FIFO IRQ Trigger Level"] +pub mod s0_txfifoirqtrg; +#[doc = "S0_FIFO_CLR (w) register accessor: Slave Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_fifo_clr::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_fifo_clr`] +module"] +#[doc(alias = "S0_FIFO_CLR")] +pub type S0FifoClr = crate::Reg; +#[doc = "Slave Clear FIFO Register"] +pub mod s0_fifo_clr; +#[doc = "S0_ADDRESSB (rw) register accessor: Slave I2C Address B Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_addressb`] +module"] +#[doc(alias = "S0_ADDRESSB")] +pub type S0Addressb = crate::Reg; +#[doc = "Slave I2C Address B Value"] +pub mod s0_addressb; +#[doc = "S0_ADDRESSMASKB (rw) register accessor: Slave I2C Address B Mask value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressmaskb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressmaskb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@s0_addressmaskb`] +module"] +#[doc(alias = "S0_ADDRESSMASKB")] +pub type S0Addressmaskb = crate::Reg; +#[doc = "Slave I2C Address B Mask value"] +pub mod s0_addressmaskb; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/i2ca/address.rs b/va108xx/src/i2ca/address.rs new file mode 100644 index 0000000..4733ce9 --- /dev/null +++ b/va108xx/src/i2ca/address.rs @@ -0,0 +1,27 @@ +#[doc = "Register `ADDRESS` reader"] +pub type R = crate::R; +#[doc = "Register `ADDRESS` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "I2C Address value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`address::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`address::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct AddressSpec; +impl crate::RegisterSpec for AddressSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`address::R`](R) reader structure"] +impl crate::Readable for AddressSpec {} +#[doc = "`write(|w| ..)` method takes [`address::W`](W) writer structure"] +impl crate::Writable for AddressSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ADDRESS to value 0"] +impl crate::Resettable for AddressSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/clkscale.rs b/va108xx/src/i2ca/clkscale.rs new file mode 100644 index 0000000..ad9dbd5 --- /dev/null +++ b/va108xx/src/i2ca/clkscale.rs @@ -0,0 +1,55 @@ +#[doc = "Register `CLKSCALE` reader"] +pub type R = crate::R; +#[doc = "Register `CLKSCALE` writer"] +pub type W = crate::W; +#[doc = "Field `VALUE` reader - Enable FastMode"] +pub type ValueR = crate::FieldReader; +#[doc = "Field `VALUE` writer - Enable FastMode"] +pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 31, u32>; +#[doc = "Field `FASTMODE` reader - Enable FastMode"] +pub type FastmodeR = crate::BitReader; +#[doc = "Field `FASTMODE` writer - Enable FastMode"] +pub type FastmodeW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bits 0:30 - Enable FastMode"] + #[inline(always)] + pub fn value(&self) -> ValueR { + ValueR::new(self.bits & 0x7fff_ffff) + } + #[doc = "Bit 31 - Enable FastMode"] + #[inline(always)] + pub fn fastmode(&self) -> FastmodeR { + FastmodeR::new(((self.bits >> 31) & 1) != 0) + } +} +impl W { + #[doc = "Bits 0:30 - Enable FastMode"] + #[inline(always)] + #[must_use] + pub fn value(&mut self) -> ValueW { + ValueW::new(self, 0) + } + #[doc = "Bit 31 - Enable FastMode"] + #[inline(always)] + #[must_use] + pub fn fastmode(&mut self) -> FastmodeW { + FastmodeW::new(self, 31) + } +} +#[doc = "Clock Scale divide value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkscale::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkscale::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ClkscaleSpec; +impl crate::RegisterSpec for ClkscaleSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`clkscale::R`](R) reader structure"] +impl crate::Readable for ClkscaleSpec {} +#[doc = "`write(|w| ..)` method takes [`clkscale::W`](W) writer structure"] +impl crate::Writable for ClkscaleSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CLKSCALE to value 0"] +impl crate::Resettable for ClkscaleSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/clktolimit.rs b/va108xx/src/i2ca/clktolimit.rs new file mode 100644 index 0000000..2c0569d --- /dev/null +++ b/va108xx/src/i2ca/clktolimit.rs @@ -0,0 +1,27 @@ +#[doc = "Register `CLKTOLIMIT` reader"] +pub type R = crate::R; +#[doc = "Register `CLKTOLIMIT` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Clock Low Timeout Limit Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clktolimit::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clktolimit::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ClktolimitSpec; +impl crate::RegisterSpec for ClktolimitSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`clktolimit::R`](R) reader structure"] +impl crate::Readable for ClktolimitSpec {} +#[doc = "`write(|w| ..)` method takes [`clktolimit::W`](W) writer structure"] +impl crate::Writable for ClktolimitSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CLKTOLIMIT to value 0"] +impl crate::Resettable for ClktolimitSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/cmd.rs b/va108xx/src/i2ca/cmd.rs new file mode 100644 index 0000000..aee7ef2 --- /dev/null +++ b/va108xx/src/i2ca/cmd.rs @@ -0,0 +1,27 @@ +#[doc = "Register `CMD` reader"] +pub type R = crate::R; +#[doc = "Register `CMD` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Command Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cmd::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cmd::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CmdSpec; +impl crate::RegisterSpec for CmdSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`cmd::R`](R) reader structure"] +impl crate::Readable for CmdSpec {} +#[doc = "`write(|w| ..)` method takes [`cmd::W`](W) writer structure"] +impl crate::Writable for CmdSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CMD to value 0"] +impl crate::Resettable for CmdSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/ctrl.rs b/va108xx/src/i2ca/ctrl.rs new file mode 100644 index 0000000..203c9d3 --- /dev/null +++ b/va108xx/src/i2ca/ctrl.rs @@ -0,0 +1,160 @@ +#[doc = "Register `CTRL` reader"] +pub type R = crate::R; +#[doc = "Register `CTRL` writer"] +pub type W = crate::W; +#[doc = "Field `CLKENABLED` reader - I2C CLK Enabled"] +pub type ClkenabledR = crate::BitReader; +#[doc = "Field `CLKENABLED` writer - I2C CLK Enabled"] +pub type ClkenabledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ENABLED` reader - I2C Activated"] +pub type EnabledR = crate::BitReader; +#[doc = "Field `ENABLED` writer - I2C Activated"] +pub type EnabledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ENABLE` reader - I2C Active"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - I2C Active"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFEMD` reader - TX FIFIO Empty Mode"] +pub type TxfemdR = crate::BitReader; +#[doc = "Field `TXFEMD` writer - TX FIFIO Empty Mode"] +pub type TxfemdW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXFFMD` reader - RX FIFO Full Mode"] +pub type RxffmdR = crate::BitReader; +#[doc = "Field `RXFFMD` writer - RX FIFO Full Mode"] +pub type RxffmdW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ALGFILTER` reader - Enable Input Analog Glitch Filter"] +pub type AlgfilterR = crate::BitReader; +#[doc = "Field `ALGFILTER` writer - Enable Input Analog Glitch Filter"] +pub type AlgfilterW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `DLGFILTER` reader - Enable Input Digital Glitch Filter"] +pub type DlgfilterR = crate::BitReader; +#[doc = "Field `DLGFILTER` writer - Enable Input Digital Glitch Filter"] +pub type DlgfilterW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `LOOPBACK` reader - Enable LoopBack Mode"] +pub type LoopbackR = crate::BitReader; +#[doc = "Field `LOOPBACK` writer - Enable LoopBack Mode"] +pub type LoopbackW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TMCONFIGENB` reader - Enable Timing Config Register"] +pub type TmconfigenbR = crate::BitReader; +#[doc = "Field `TMCONFIGENB` writer - Enable Timing Config Register"] +pub type TmconfigenbW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - I2C CLK Enabled"] + #[inline(always)] + pub fn clkenabled(&self) -> ClkenabledR { + ClkenabledR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - I2C Activated"] + #[inline(always)] + pub fn enabled(&self) -> EnabledR { + EnabledR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - I2C Active"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - TX FIFIO Empty Mode"] + #[inline(always)] + pub fn txfemd(&self) -> TxfemdR { + TxfemdR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - RX FIFO Full Mode"] + #[inline(always)] + pub fn rxffmd(&self) -> RxffmdR { + RxffmdR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - Enable Input Analog Glitch Filter"] + #[inline(always)] + pub fn algfilter(&self) -> AlgfilterR { + AlgfilterR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - Enable Input Digital Glitch Filter"] + #[inline(always)] + pub fn dlgfilter(&self) -> DlgfilterR { + DlgfilterR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 8 - Enable LoopBack Mode"] + #[inline(always)] + pub fn loopback(&self) -> LoopbackR { + LoopbackR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Enable Timing Config Register"] + #[inline(always)] + pub fn tmconfigenb(&self) -> TmconfigenbR { + TmconfigenbR::new(((self.bits >> 9) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - I2C CLK Enabled"] + #[inline(always)] + #[must_use] + pub fn clkenabled(&mut self) -> ClkenabledW { + ClkenabledW::new(self, 0) + } + #[doc = "Bit 1 - I2C Activated"] + #[inline(always)] + #[must_use] + pub fn enabled(&mut self) -> EnabledW { + EnabledW::new(self, 1) + } + #[doc = "Bit 2 - I2C Active"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 2) + } + #[doc = "Bit 3 - TX FIFIO Empty Mode"] + #[inline(always)] + #[must_use] + pub fn txfemd(&mut self) -> TxfemdW { + TxfemdW::new(self, 3) + } + #[doc = "Bit 4 - RX FIFO Full Mode"] + #[inline(always)] + #[must_use] + pub fn rxffmd(&mut self) -> RxffmdW { + RxffmdW::new(self, 4) + } + #[doc = "Bit 5 - Enable Input Analog Glitch Filter"] + #[inline(always)] + #[must_use] + pub fn algfilter(&mut self) -> AlgfilterW { + AlgfilterW::new(self, 5) + } + #[doc = "Bit 6 - Enable Input Digital Glitch Filter"] + #[inline(always)] + #[must_use] + pub fn dlgfilter(&mut self) -> DlgfilterW { + DlgfilterW::new(self, 6) + } + #[doc = "Bit 8 - Enable LoopBack Mode"] + #[inline(always)] + #[must_use] + pub fn loopback(&mut self) -> LoopbackW { + LoopbackW::new(self, 8) + } + #[doc = "Bit 9 - Enable Timing Config Register"] + #[inline(always)] + #[must_use] + pub fn tmconfigenb(&mut self) -> TmconfigenbW { + TmconfigenbW::new(self, 9) + } +} +#[doc = "Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CtrlSpec; +impl crate::RegisterSpec for CtrlSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ctrl::R`](R) reader structure"] +impl crate::Readable for CtrlSpec {} +#[doc = "`write(|w| ..)` method takes [`ctrl::W`](W) writer structure"] +impl crate::Writable for CtrlSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CTRL to value 0"] +impl crate::Resettable for CtrlSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/data.rs b/va108xx/src/i2ca/data.rs new file mode 100644 index 0000000..30b85c9 --- /dev/null +++ b/va108xx/src/i2ca/data.rs @@ -0,0 +1,27 @@ +#[doc = "Register `DATA` reader"] +pub type R = crate::R; +#[doc = "Register `DATA` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DataSpec; +impl crate::RegisterSpec for DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`data::R`](R) reader structure"] +impl crate::Readable for DataSpec {} +#[doc = "`write(|w| ..)` method takes [`data::W`](W) writer structure"] +impl crate::Writable for DataSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets DATA to value 0"] +impl crate::Resettable for DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/fifo_clr.rs b/va108xx/src/i2ca/fifo_clr.rs new file mode 100644 index 0000000..156da87 --- /dev/null +++ b/va108xx/src/i2ca/fifo_clr.rs @@ -0,0 +1,35 @@ +#[doc = "Register `FIFO_CLR` writer"] +pub type W = crate::W; +#[doc = "Field `RXFIFO` writer - Clear Rx FIFO"] +pub type RxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFIFO` writer - Clear Tx FIFO"] +pub type TxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +impl W { + #[doc = "Bit 0 - Clear Rx FIFO"] + #[inline(always)] + #[must_use] + pub fn rxfifo(&mut self) -> RxfifoW { + RxfifoW::new(self, 0) + } + #[doc = "Bit 1 - Clear Tx FIFO"] + #[inline(always)] + #[must_use] + pub fn txfifo(&mut self) -> TxfifoW { + TxfifoW::new(self, 1) + } +} +#[doc = "Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct FifoClrSpec; +impl crate::RegisterSpec for FifoClrSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`fifo_clr::W`](W) writer structure"] +impl crate::Writable for FifoClrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets FIFO_CLR to value 0"] +impl crate::Resettable for FifoClrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/irq_enb.rs b/va108xx/src/i2ca/irq_enb.rs new file mode 100644 index 0000000..4eba067 --- /dev/null +++ b/va108xx/src/i2ca/irq_enb.rs @@ -0,0 +1,235 @@ +#[doc = "Register `IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_ENB` writer"] +pub type W = crate::W; +#[doc = "Field `I2CIDLE` reader - I2C Bus is Idle"] +pub type I2cidleR = crate::BitReader; +#[doc = "Field `I2CIDLE` writer - I2C Bus is Idle"] +pub type I2cidleW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IDLE` reader - Controller is Idle"] +pub type IdleR = crate::BitReader; +#[doc = "Field `IDLE` writer - Controller is Idle"] +pub type IdleW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `WAITING` reader - Controller is Waiting"] +pub type WaitingR = crate::BitReader; +#[doc = "Field `WAITING` writer - Controller is Waiting"] +pub type WaitingW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `STALLED` reader - Controller is Stalled"] +pub type StalledR = crate::BitReader; +#[doc = "Field `STALLED` writer - Controller is Stalled"] +pub type StalledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ARBLOST` reader - I2C Arbitration was lost"] +pub type ArblostR = crate::BitReader; +#[doc = "Field `ARBLOST` writer - I2C Arbitration was lost"] +pub type ArblostW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `NACKADDR` reader - I2C Address was not Acknowledged"] +pub type NackaddrR = crate::BitReader; +#[doc = "Field `NACKADDR` writer - I2C Address was not Acknowledged"] +pub type NackaddrW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `NACKDATA` reader - I2C Data was not Acknowledged"] +pub type NackdataR = crate::BitReader; +#[doc = "Field `NACKDATA` writer - I2C Data was not Acknowledged"] +pub type NackdataW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CLKLOTO` reader - I2C Clock Low Timeout"] +pub type ClklotoR = crate::BitReader; +#[doc = "Field `CLKLOTO` writer - I2C Clock Low Timeout"] +pub type ClklotoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXOVERFLOW` reader - TX FIFO Overflowed"] +pub type TxoverflowR = crate::BitReader; +#[doc = "Field `TXOVERFLOW` writer - TX FIFO Overflowed"] +pub type TxoverflowW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXOVERFLOW` reader - TX FIFO Overflowed"] +pub type RxoverflowR = crate::BitReader; +#[doc = "Field `RXOVERFLOW` writer - TX FIFO Overflowed"] +pub type RxoverflowW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXREADY` reader - TX FIFO Ready"] +pub type TxreadyR = crate::BitReader; +#[doc = "Field `TXREADY` writer - TX FIFO Ready"] +pub type TxreadyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXREADY` reader - RX FIFO Ready"] +pub type RxreadyR = crate::BitReader; +#[doc = "Field `RXREADY` writer - RX FIFO Ready"] +pub type RxreadyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXEMPTY` reader - TX FIFO Empty"] +pub type TxemptyR = crate::BitReader; +#[doc = "Field `TXEMPTY` writer - TX FIFO Empty"] +pub type TxemptyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXFULL` reader - RX FIFO Full"] +pub type RxfullR = crate::BitReader; +#[doc = "Field `RXFULL` writer - RX FIFO Full"] +pub type RxfullW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - I2C Bus is Idle"] + #[inline(always)] + pub fn i2cidle(&self) -> I2cidleR { + I2cidleR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + pub fn idle(&self) -> IdleR { + IdleR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + pub fn waiting(&self) -> WaitingR { + WaitingR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Controller is Stalled"] + #[inline(always)] + pub fn stalled(&self) -> StalledR { + StalledR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - I2C Arbitration was lost"] + #[inline(always)] + pub fn arblost(&self) -> ArblostR { + ArblostR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - I2C Address was not Acknowledged"] + #[inline(always)] + pub fn nackaddr(&self) -> NackaddrR { + NackaddrR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + pub fn nackdata(&self) -> NackdataR { + NackdataR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - I2C Clock Low Timeout"] + #[inline(always)] + pub fn clkloto(&self) -> ClklotoR { + ClklotoR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 10 - TX FIFO Overflowed"] + #[inline(always)] + pub fn txoverflow(&self) -> TxoverflowR { + TxoverflowR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - TX FIFO Overflowed"] + #[inline(always)] + pub fn rxoverflow(&self) -> RxoverflowR { + RxoverflowR::new(((self.bits >> 11) & 1) != 0) + } + #[doc = "Bit 12 - TX FIFO Ready"] + #[inline(always)] + pub fn txready(&self) -> TxreadyR { + TxreadyR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bit 13 - RX FIFO Ready"] + #[inline(always)] + pub fn rxready(&self) -> RxreadyR { + RxreadyR::new(((self.bits >> 13) & 1) != 0) + } + #[doc = "Bit 14 - TX FIFO Empty"] + #[inline(always)] + pub fn txempty(&self) -> TxemptyR { + TxemptyR::new(((self.bits >> 14) & 1) != 0) + } + #[doc = "Bit 15 - RX FIFO Full"] + #[inline(always)] + pub fn rxfull(&self) -> RxfullR { + RxfullR::new(((self.bits >> 15) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - I2C Bus is Idle"] + #[inline(always)] + #[must_use] + pub fn i2cidle(&mut self) -> I2cidleW { + I2cidleW::new(self, 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + #[must_use] + pub fn idle(&mut self) -> IdleW { + IdleW::new(self, 1) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + #[must_use] + pub fn waiting(&mut self) -> WaitingW { + WaitingW::new(self, 2) + } + #[doc = "Bit 3 - Controller is Stalled"] + #[inline(always)] + #[must_use] + pub fn stalled(&mut self) -> StalledW { + StalledW::new(self, 3) + } + #[doc = "Bit 4 - I2C Arbitration was lost"] + #[inline(always)] + #[must_use] + pub fn arblost(&mut self) -> ArblostW { + ArblostW::new(self, 4) + } + #[doc = "Bit 5 - I2C Address was not Acknowledged"] + #[inline(always)] + #[must_use] + pub fn nackaddr(&mut self) -> NackaddrW { + NackaddrW::new(self, 5) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + #[must_use] + pub fn nackdata(&mut self) -> NackdataW { + NackdataW::new(self, 6) + } + #[doc = "Bit 7 - I2C Clock Low Timeout"] + #[inline(always)] + #[must_use] + pub fn clkloto(&mut self) -> ClklotoW { + ClklotoW::new(self, 7) + } + #[doc = "Bit 10 - TX FIFO Overflowed"] + #[inline(always)] + #[must_use] + pub fn txoverflow(&mut self) -> TxoverflowW { + TxoverflowW::new(self, 10) + } + #[doc = "Bit 11 - TX FIFO Overflowed"] + #[inline(always)] + #[must_use] + pub fn rxoverflow(&mut self) -> RxoverflowW { + RxoverflowW::new(self, 11) + } + #[doc = "Bit 12 - TX FIFO Ready"] + #[inline(always)] + #[must_use] + pub fn txready(&mut self) -> TxreadyW { + TxreadyW::new(self, 12) + } + #[doc = "Bit 13 - RX FIFO Ready"] + #[inline(always)] + #[must_use] + pub fn rxready(&mut self) -> RxreadyW { + RxreadyW::new(self, 13) + } + #[doc = "Bit 14 - TX FIFO Empty"] + #[inline(always)] + #[must_use] + pub fn txempty(&mut self) -> TxemptyW { + TxemptyW::new(self, 14) + } + #[doc = "Bit 15 - RX FIFO Full"] + #[inline(always)] + #[must_use] + pub fn rxfull(&mut self) -> RxfullW { + RxfullW::new(self, 15) + } +} +#[doc = "Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEnbSpec; +impl crate::RegisterSpec for IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_enb::R`](R) reader structure"] +impl crate::Readable for IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_enb::W`](W) writer structure"] +impl crate::Writable for IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_ENB to value 0"] +impl crate::Resettable for IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/perid.rs b/va108xx/src/i2ca/perid.rs new file mode 100644 index 0000000..38c66fd --- /dev/null +++ b/va108xx/src/i2ca/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0014_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0014_07e1; +} diff --git a/va108xx/src/i2ca/rxcount.rs b/va108xx/src/i2ca/rxcount.rs new file mode 100644 index 0000000..b7b6d5a --- /dev/null +++ b/va108xx/src/i2ca/rxcount.rs @@ -0,0 +1,18 @@ +#[doc = "Register `RXCOUNT` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "RX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxcount::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxcountSpec; +impl crate::RegisterSpec for RxcountSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxcount::R`](R) reader structure"] +impl crate::Readable for RxcountSpec {} +#[doc = "`reset()` method sets RXCOUNT to value 0"] +impl crate::Resettable for RxcountSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/rxfifoirqtrg.rs b/va108xx/src/i2ca/rxfifoirqtrg.rs new file mode 100644 index 0000000..46124d5 --- /dev/null +++ b/va108xx/src/i2ca/rxfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `RXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxfifoirqtrgSpec; +impl crate::RegisterSpec for RxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for RxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`rxfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for RxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RXFIFOIRQTRG to value 0"] +impl crate::Resettable for RxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_address.rs b/va108xx/src/i2ca/s0_address.rs new file mode 100644 index 0000000..a6e6eef --- /dev/null +++ b/va108xx/src/i2ca/s0_address.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_ADDRESS` reader"] +pub type R = crate::R; +#[doc = "Register `S0_ADDRESS` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave I2C Address Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_address::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_address::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0AddressSpec; +impl crate::RegisterSpec for S0AddressSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_address::R`](R) reader structure"] +impl crate::Readable for S0AddressSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_address::W`](W) writer structure"] +impl crate::Writable for S0AddressSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_ADDRESS to value 0"] +impl crate::Resettable for S0AddressSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_addressb.rs b/va108xx/src/i2ca/s0_addressb.rs new file mode 100644 index 0000000..38e3c77 --- /dev/null +++ b/va108xx/src/i2ca/s0_addressb.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_ADDRESSB` reader"] +pub type R = crate::R; +#[doc = "Register `S0_ADDRESSB` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave I2C Address B Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0AddressbSpec; +impl crate::RegisterSpec for S0AddressbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_addressb::R`](R) reader structure"] +impl crate::Readable for S0AddressbSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_addressb::W`](W) writer structure"] +impl crate::Writable for S0AddressbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_ADDRESSB to value 0"] +impl crate::Resettable for S0AddressbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_addressmask.rs b/va108xx/src/i2ca/s0_addressmask.rs new file mode 100644 index 0000000..b858f8e --- /dev/null +++ b/va108xx/src/i2ca/s0_addressmask.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_ADDRESSMASK` reader"] +pub type R = crate::R; +#[doc = "Register `S0_ADDRESSMASK` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave I2C Address Mask value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressmask::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressmask::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0AddressmaskSpec; +impl crate::RegisterSpec for S0AddressmaskSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_addressmask::R`](R) reader structure"] +impl crate::Readable for S0AddressmaskSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_addressmask::W`](W) writer structure"] +impl crate::Writable for S0AddressmaskSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_ADDRESSMASK to value 0"] +impl crate::Resettable for S0AddressmaskSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_addressmaskb.rs b/va108xx/src/i2ca/s0_addressmaskb.rs new file mode 100644 index 0000000..e79e241 --- /dev/null +++ b/va108xx/src/i2ca/s0_addressmaskb.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_ADDRESSMASKB` reader"] +pub type R = crate::R; +#[doc = "Register `S0_ADDRESSMASKB` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave I2C Address B Mask value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_addressmaskb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_addressmaskb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0AddressmaskbSpec; +impl crate::RegisterSpec for S0AddressmaskbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_addressmaskb::R`](R) reader structure"] +impl crate::Readable for S0AddressmaskbSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_addressmaskb::W`](W) writer structure"] +impl crate::Writable for S0AddressmaskbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_ADDRESSMASKB to value 0"] +impl crate::Resettable for S0AddressmaskbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_ctrl.rs b/va108xx/src/i2ca/s0_ctrl.rs new file mode 100644 index 0000000..c22d6de --- /dev/null +++ b/va108xx/src/i2ca/s0_ctrl.rs @@ -0,0 +1,100 @@ +#[doc = "Register `S0_CTRL` reader"] +pub type R = crate::R; +#[doc = "Register `S0_CTRL` writer"] +pub type W = crate::W; +#[doc = "Field `CLKENABLED` reader - I2C Enabled"] +pub type ClkenabledR = crate::BitReader; +#[doc = "Field `CLKENABLED` writer - I2C Enabled"] +pub type ClkenabledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ENABLED` reader - I2C Activated"] +pub type EnabledR = crate::BitReader; +#[doc = "Field `ENABLED` writer - I2C Activated"] +pub type EnabledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ENABLE` reader - I2C Active"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - I2C Active"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFEMD` reader - TX FIFIO Empty Mode"] +pub type TxfemdR = crate::BitReader; +#[doc = "Field `TXFEMD` writer - TX FIFIO Empty Mode"] +pub type TxfemdW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXFFMD` reader - RX FIFO Full Mode"] +pub type RxffmdR = crate::BitReader; +#[doc = "Field `RXFFMD` writer - RX FIFO Full Mode"] +pub type RxffmdW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - I2C Enabled"] + #[inline(always)] + pub fn clkenabled(&self) -> ClkenabledR { + ClkenabledR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - I2C Activated"] + #[inline(always)] + pub fn enabled(&self) -> EnabledR { + EnabledR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - I2C Active"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - TX FIFIO Empty Mode"] + #[inline(always)] + pub fn txfemd(&self) -> TxfemdR { + TxfemdR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - RX FIFO Full Mode"] + #[inline(always)] + pub fn rxffmd(&self) -> RxffmdR { + RxffmdR::new(((self.bits >> 4) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - I2C Enabled"] + #[inline(always)] + #[must_use] + pub fn clkenabled(&mut self) -> ClkenabledW { + ClkenabledW::new(self, 0) + } + #[doc = "Bit 1 - I2C Activated"] + #[inline(always)] + #[must_use] + pub fn enabled(&mut self) -> EnabledW { + EnabledW::new(self, 1) + } + #[doc = "Bit 2 - I2C Active"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 2) + } + #[doc = "Bit 3 - TX FIFIO Empty Mode"] + #[inline(always)] + #[must_use] + pub fn txfemd(&mut self) -> TxfemdW { + TxfemdW::new(self, 3) + } + #[doc = "Bit 4 - RX FIFO Full Mode"] + #[inline(always)] + #[must_use] + pub fn rxffmd(&mut self) -> RxffmdW { + RxffmdW::new(self, 4) + } +} +#[doc = "Slave Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_ctrl::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_ctrl::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0CtrlSpec; +impl crate::RegisterSpec for S0CtrlSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_ctrl::R`](R) reader structure"] +impl crate::Readable for S0CtrlSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_ctrl::W`](W) writer structure"] +impl crate::Writable for S0CtrlSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_CTRL to value 0"] +impl crate::Resettable for S0CtrlSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_data.rs b/va108xx/src/i2ca/s0_data.rs new file mode 100644 index 0000000..6e7375b --- /dev/null +++ b/va108xx/src/i2ca/s0_data.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_DATA` reader"] +pub type R = crate::R; +#[doc = "Register `S0_DATA` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_data::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_data::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0DataSpec; +impl crate::RegisterSpec for S0DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_data::R`](R) reader structure"] +impl crate::Readable for S0DataSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_data::W`](W) writer structure"] +impl crate::Writable for S0DataSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_DATA to value 0"] +impl crate::Resettable for S0DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_fifo_clr.rs b/va108xx/src/i2ca/s0_fifo_clr.rs new file mode 100644 index 0000000..0d5dd60 --- /dev/null +++ b/va108xx/src/i2ca/s0_fifo_clr.rs @@ -0,0 +1,35 @@ +#[doc = "Register `S0_FIFO_CLR` writer"] +pub type W = crate::W; +#[doc = "Field `RXFIFO` writer - Clear Rx FIFO"] +pub type RxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFIFO` writer - Clear Tx FIFO"] +pub type TxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +impl W { + #[doc = "Bit 0 - Clear Rx FIFO"] + #[inline(always)] + #[must_use] + pub fn rxfifo(&mut self) -> RxfifoW { + RxfifoW::new(self, 0) + } + #[doc = "Bit 1 - Clear Tx FIFO"] + #[inline(always)] + #[must_use] + pub fn txfifo(&mut self) -> TxfifoW { + TxfifoW::new(self, 1) + } +} +#[doc = "Slave Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_fifo_clr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0FifoClrSpec; +impl crate::RegisterSpec for S0FifoClrSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`s0_fifo_clr::W`](W) writer structure"] +impl crate::Writable for S0FifoClrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_FIFO_CLR to value 0"] +impl crate::Resettable for S0FifoClrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_irq_enb.rs b/va108xx/src/i2ca/s0_irq_enb.rs new file mode 100644 index 0000000..a6a30e2 --- /dev/null +++ b/va108xx/src/i2ca/s0_irq_enb.rs @@ -0,0 +1,265 @@ +#[doc = "Register `S0_IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `S0_IRQ_ENB` writer"] +pub type W = crate::W; +#[doc = "Field `COMPLETED` reader - Controller Complted a Transaction"] +pub type CompletedR = crate::BitReader; +#[doc = "Field `COMPLETED` writer - Controller Complted a Transaction"] +pub type CompletedW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IDLE` reader - Controller is Idle"] +pub type IdleR = crate::BitReader; +#[doc = "Field `IDLE` writer - Controller is Idle"] +pub type IdleW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `WAITING` reader - Controller is Waiting"] +pub type WaitingR = crate::BitReader; +#[doc = "Field `WAITING` writer - Controller is Waiting"] +pub type WaitingW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXSTALLED` reader - Controller is Tx Stalled"] +pub type TxstalledR = crate::BitReader; +#[doc = "Field `TXSTALLED` writer - Controller is Tx Stalled"] +pub type TxstalledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXSTALLED` reader - Controller is Rx Stalled"] +pub type RxstalledR = crate::BitReader; +#[doc = "Field `RXSTALLED` writer - Controller is Rx Stalled"] +pub type RxstalledW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ADDRESSMATCH` reader - I2C Address Match"] +pub type AddressmatchR = crate::BitReader; +#[doc = "Field `ADDRESSMATCH` writer - I2C Address Match"] +pub type AddressmatchW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `NACKDATA` reader - I2C Data was not Acknowledged"] +pub type NackdataR = crate::BitReader; +#[doc = "Field `NACKDATA` writer - I2C Data was not Acknowledged"] +pub type NackdataW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXDATAFIRST` reader - Pending Data is first Byte following Address"] +pub type RxdatafirstR = crate::BitReader; +#[doc = "Field `RXDATAFIRST` writer - Pending Data is first Byte following Address"] +pub type RxdatafirstW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_START` reader - I2C Start Condition"] +pub type I2cStartR = crate::BitReader; +#[doc = "Field `I2C_START` writer - I2C Start Condition"] +pub type I2cStartW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_STOP` reader - I2C Stop Condition"] +pub type I2cStopR = crate::BitReader; +#[doc = "Field `I2C_STOP` writer - I2C Stop Condition"] +pub type I2cStopW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXUNDERFLOW` reader - TX FIFO Underflowed"] +pub type TxunderflowR = crate::BitReader; +#[doc = "Field `TXUNDERFLOW` writer - TX FIFO Underflowed"] +pub type TxunderflowW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXOVERFLOW` reader - TX FIFO Overflowed"] +pub type RxoverflowR = crate::BitReader; +#[doc = "Field `RXOVERFLOW` writer - TX FIFO Overflowed"] +pub type RxoverflowW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXREADY` reader - TX FIFO Ready"] +pub type TxreadyR = crate::BitReader; +#[doc = "Field `TXREADY` writer - TX FIFO Ready"] +pub type TxreadyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXREADY` reader - RX FIFO Ready"] +pub type RxreadyR = crate::BitReader; +#[doc = "Field `RXREADY` writer - RX FIFO Ready"] +pub type RxreadyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXEMPTY` reader - TX FIFO Empty"] +pub type TxemptyR = crate::BitReader; +#[doc = "Field `TXEMPTY` writer - TX FIFO Empty"] +pub type TxemptyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXFULL` reader - RX FIFO Full"] +pub type RxfullR = crate::BitReader; +#[doc = "Field `RXFULL` writer - RX FIFO Full"] +pub type RxfullW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Controller Complted a Transaction"] + #[inline(always)] + pub fn completed(&self) -> CompletedR { + CompletedR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + pub fn idle(&self) -> IdleR { + IdleR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + pub fn waiting(&self) -> WaitingR { + WaitingR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Controller is Tx Stalled"] + #[inline(always)] + pub fn txstalled(&self) -> TxstalledR { + TxstalledR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Controller is Rx Stalled"] + #[inline(always)] + pub fn rxstalled(&self) -> RxstalledR { + RxstalledR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - I2C Address Match"] + #[inline(always)] + pub fn addressmatch(&self) -> AddressmatchR { + AddressmatchR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + pub fn nackdata(&self) -> NackdataR { + NackdataR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - Pending Data is first Byte following Address"] + #[inline(always)] + pub fn rxdatafirst(&self) -> RxdatafirstR { + RxdatafirstR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - I2C Start Condition"] + #[inline(always)] + pub fn i2c_start(&self) -> I2cStartR { + I2cStartR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - I2C Stop Condition"] + #[inline(always)] + pub fn i2c_stop(&self) -> I2cStopR { + I2cStopR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - TX FIFO Underflowed"] + #[inline(always)] + pub fn txunderflow(&self) -> TxunderflowR { + TxunderflowR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - TX FIFO Overflowed"] + #[inline(always)] + pub fn rxoverflow(&self) -> RxoverflowR { + RxoverflowR::new(((self.bits >> 11) & 1) != 0) + } + #[doc = "Bit 12 - TX FIFO Ready"] + #[inline(always)] + pub fn txready(&self) -> TxreadyR { + TxreadyR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bit 13 - RX FIFO Ready"] + #[inline(always)] + pub fn rxready(&self) -> RxreadyR { + RxreadyR::new(((self.bits >> 13) & 1) != 0) + } + #[doc = "Bit 14 - TX FIFO Empty"] + #[inline(always)] + pub fn txempty(&self) -> TxemptyR { + TxemptyR::new(((self.bits >> 14) & 1) != 0) + } + #[doc = "Bit 15 - RX FIFO Full"] + #[inline(always)] + pub fn rxfull(&self) -> RxfullR { + RxfullR::new(((self.bits >> 15) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Controller Complted a Transaction"] + #[inline(always)] + #[must_use] + pub fn completed(&mut self) -> CompletedW { + CompletedW::new(self, 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + #[must_use] + pub fn idle(&mut self) -> IdleW { + IdleW::new(self, 1) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + #[must_use] + pub fn waiting(&mut self) -> WaitingW { + WaitingW::new(self, 2) + } + #[doc = "Bit 3 - Controller is Tx Stalled"] + #[inline(always)] + #[must_use] + pub fn txstalled(&mut self) -> TxstalledW { + TxstalledW::new(self, 3) + } + #[doc = "Bit 4 - Controller is Rx Stalled"] + #[inline(always)] + #[must_use] + pub fn rxstalled(&mut self) -> RxstalledW { + RxstalledW::new(self, 4) + } + #[doc = "Bit 5 - I2C Address Match"] + #[inline(always)] + #[must_use] + pub fn addressmatch(&mut self) -> AddressmatchW { + AddressmatchW::new(self, 5) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + #[must_use] + pub fn nackdata(&mut self) -> NackdataW { + NackdataW::new(self, 6) + } + #[doc = "Bit 7 - Pending Data is first Byte following Address"] + #[inline(always)] + #[must_use] + pub fn rxdatafirst(&mut self) -> RxdatafirstW { + RxdatafirstW::new(self, 7) + } + #[doc = "Bit 8 - I2C Start Condition"] + #[inline(always)] + #[must_use] + pub fn i2c_start(&mut self) -> I2cStartW { + I2cStartW::new(self, 8) + } + #[doc = "Bit 9 - I2C Stop Condition"] + #[inline(always)] + #[must_use] + pub fn i2c_stop(&mut self) -> I2cStopW { + I2cStopW::new(self, 9) + } + #[doc = "Bit 10 - TX FIFO Underflowed"] + #[inline(always)] + #[must_use] + pub fn txunderflow(&mut self) -> TxunderflowW { + TxunderflowW::new(self, 10) + } + #[doc = "Bit 11 - TX FIFO Overflowed"] + #[inline(always)] + #[must_use] + pub fn rxoverflow(&mut self) -> RxoverflowW { + RxoverflowW::new(self, 11) + } + #[doc = "Bit 12 - TX FIFO Ready"] + #[inline(always)] + #[must_use] + pub fn txready(&mut self) -> TxreadyW { + TxreadyW::new(self, 12) + } + #[doc = "Bit 13 - RX FIFO Ready"] + #[inline(always)] + #[must_use] + pub fn rxready(&mut self) -> RxreadyW { + RxreadyW::new(self, 13) + } + #[doc = "Bit 14 - TX FIFO Empty"] + #[inline(always)] + #[must_use] + pub fn txempty(&mut self) -> TxemptyW { + TxemptyW::new(self, 14) + } + #[doc = "Bit 15 - RX FIFO Full"] + #[inline(always)] + #[must_use] + pub fn rxfull(&mut self) -> RxfullW { + RxfullW::new(self, 15) + } +} +#[doc = "Slave Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0IrqEnbSpec; +impl crate::RegisterSpec for S0IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_irq_enb::R`](R) reader structure"] +impl crate::Readable for S0IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_irq_enb::W`](W) writer structure"] +impl crate::Writable for S0IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_IRQ_ENB to value 0"] +impl crate::Resettable for S0IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_lastaddress.rs b/va108xx/src/i2ca/s0_lastaddress.rs new file mode 100644 index 0000000..4bf751f --- /dev/null +++ b/va108xx/src/i2ca/s0_lastaddress.rs @@ -0,0 +1,18 @@ +#[doc = "Register `S0_LASTADDRESS` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Slave I2C Last Address value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_lastaddress::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0LastaddressSpec; +impl crate::RegisterSpec for S0LastaddressSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_lastaddress::R`](R) reader structure"] +impl crate::Readable for S0LastaddressSpec {} +#[doc = "`reset()` method sets S0_LASTADDRESS to value 0"] +impl crate::Resettable for S0LastaddressSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_maxwords.rs b/va108xx/src/i2ca/s0_maxwords.rs new file mode 100644 index 0000000..b079396 --- /dev/null +++ b/va108xx/src/i2ca/s0_maxwords.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_MAXWORDS` reader"] +pub type R = crate::R; +#[doc = "Register `S0_MAXWORDS` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave MaxWords Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_maxwords::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_maxwords::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0MaxwordsSpec; +impl crate::RegisterSpec for S0MaxwordsSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_maxwords::R`](R) reader structure"] +impl crate::Readable for S0MaxwordsSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_maxwords::W`](W) writer structure"] +impl crate::Writable for S0MaxwordsSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_MAXWORDS to value 0"] +impl crate::Resettable for S0MaxwordsSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_rxcount.rs b/va108xx/src/i2ca/s0_rxcount.rs new file mode 100644 index 0000000..b1dbc2c --- /dev/null +++ b/va108xx/src/i2ca/s0_rxcount.rs @@ -0,0 +1,18 @@ +#[doc = "Register `S0_RXCOUNT` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Slave RX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_rxcount::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0RxcountSpec; +impl crate::RegisterSpec for S0RxcountSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_rxcount::R`](R) reader structure"] +impl crate::Readable for S0RxcountSpec {} +#[doc = "`reset()` method sets S0_RXCOUNT to value 0"] +impl crate::Resettable for S0RxcountSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_rxfifoirqtrg.rs b/va108xx/src/i2ca/s0_rxfifoirqtrg.rs new file mode 100644 index 0000000..b2a5632 --- /dev/null +++ b/va108xx/src/i2ca/s0_rxfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_RXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `S0_RXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_rxfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_rxfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0RxfifoirqtrgSpec; +impl crate::RegisterSpec for S0RxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_rxfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for S0RxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_rxfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for S0RxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_RXFIFOIRQTRG to value 0"] +impl crate::Resettable for S0RxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_state.rs b/va108xx/src/i2ca/s0_state.rs new file mode 100644 index 0000000..473fd77 --- /dev/null +++ b/va108xx/src/i2ca/s0_state.rs @@ -0,0 +1,18 @@ +#[doc = "Register `S0_STATE` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Internal STATE of I2C Slave Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_state::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0StateSpec; +impl crate::RegisterSpec for S0StateSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_state::R`](R) reader structure"] +impl crate::Readable for S0StateSpec {} +#[doc = "`reset()` method sets S0_STATE to value 0"] +impl crate::Resettable for S0StateSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_status.rs b/va108xx/src/i2ca/s0_status.rs new file mode 100644 index 0000000..1a79596 --- /dev/null +++ b/va108xx/src/i2ca/s0_status.rs @@ -0,0 +1,134 @@ +#[doc = "Register `S0_STATUS` reader"] +pub type R = crate::R; +#[doc = "Field `COMPLETED` reader - Controller Complted a Transaction"] +pub type CompletedR = crate::BitReader; +#[doc = "Field `IDLE` reader - Controller is Idle"] +pub type IdleR = crate::BitReader; +#[doc = "Field `WAITING` reader - Controller is Waiting"] +pub type WaitingR = crate::BitReader; +#[doc = "Field `TXSTALLED` reader - Controller is Tx Stalled"] +pub type TxstalledR = crate::BitReader; +#[doc = "Field `RXSTALLED` reader - Controller is Rx Stalled"] +pub type RxstalledR = crate::BitReader; +#[doc = "Field `ADDRESSMATCH` reader - I2C Address Match"] +pub type AddressmatchR = crate::BitReader; +#[doc = "Field `NACKDATA` reader - I2C Data was not Acknowledged"] +pub type NackdataR = crate::BitReader; +#[doc = "Field `RXDATAFIRST` reader - Pending Data is first Byte following Address"] +pub type RxdatafirstR = crate::BitReader; +#[doc = "Field `RXNEMPTY` reader - RX FIFO is Not Empty"] +pub type RxnemptyR = crate::BitReader; +#[doc = "Field `RXFULL` reader - RX FIFO is Full"] +pub type RxfullR = crate::BitReader; +#[doc = "Field `RXTRIGGER` reader - RX FIFO Above Trigger Level"] +pub type RxtriggerR = crate::BitReader; +#[doc = "Field `TXEMPTY` reader - TX FIFO is Empty"] +pub type TxemptyR = crate::BitReader; +#[doc = "Field `TXNFULL` reader - TX FIFO is Full"] +pub type TxnfullR = crate::BitReader; +#[doc = "Field `TXTRIGGER` reader - TX FIFO Below Trigger Level"] +pub type TxtriggerR = crate::BitReader; +#[doc = "Field `RAW_BUSY` reader - I2C Raw Busy value"] +pub type RawBusyR = crate::BitReader; +#[doc = "Field `RAW_SDA` reader - I2C Raw SDA value"] +pub type RawSdaR = crate::BitReader; +#[doc = "Field `RAW_SCL` reader - I2C Raw SCL value"] +pub type RawSclR = crate::BitReader; +impl R { + #[doc = "Bit 0 - Controller Complted a Transaction"] + #[inline(always)] + pub fn completed(&self) -> CompletedR { + CompletedR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + pub fn idle(&self) -> IdleR { + IdleR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + pub fn waiting(&self) -> WaitingR { + WaitingR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Controller is Tx Stalled"] + #[inline(always)] + pub fn txstalled(&self) -> TxstalledR { + TxstalledR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Controller is Rx Stalled"] + #[inline(always)] + pub fn rxstalled(&self) -> RxstalledR { + RxstalledR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - I2C Address Match"] + #[inline(always)] + pub fn addressmatch(&self) -> AddressmatchR { + AddressmatchR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + pub fn nackdata(&self) -> NackdataR { + NackdataR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - Pending Data is first Byte following Address"] + #[inline(always)] + pub fn rxdatafirst(&self) -> RxdatafirstR { + RxdatafirstR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - RX FIFO is Not Empty"] + #[inline(always)] + pub fn rxnempty(&self) -> RxnemptyR { + RxnemptyR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - RX FIFO is Full"] + #[inline(always)] + pub fn rxfull(&self) -> RxfullR { + RxfullR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 11 - RX FIFO Above Trigger Level"] + #[inline(always)] + pub fn rxtrigger(&self) -> RxtriggerR { + RxtriggerR::new(((self.bits >> 11) & 1) != 0) + } + #[doc = "Bit 12 - TX FIFO is Empty"] + #[inline(always)] + pub fn txempty(&self) -> TxemptyR { + TxemptyR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bit 13 - TX FIFO is Full"] + #[inline(always)] + pub fn txnfull(&self) -> TxnfullR { + TxnfullR::new(((self.bits >> 13) & 1) != 0) + } + #[doc = "Bit 15 - TX FIFO Below Trigger Level"] + #[inline(always)] + pub fn txtrigger(&self) -> TxtriggerR { + TxtriggerR::new(((self.bits >> 15) & 1) != 0) + } + #[doc = "Bit 29 - I2C Raw Busy value"] + #[inline(always)] + pub fn raw_busy(&self) -> RawBusyR { + RawBusyR::new(((self.bits >> 29) & 1) != 0) + } + #[doc = "Bit 30 - I2C Raw SDA value"] + #[inline(always)] + pub fn raw_sda(&self) -> RawSdaR { + RawSdaR::new(((self.bits >> 30) & 1) != 0) + } + #[doc = "Bit 31 - I2C Raw SCL value"] + #[inline(always)] + pub fn raw_scl(&self) -> RawSclR { + RawSclR::new(((self.bits >> 31) & 1) != 0) + } +} +#[doc = "Slave I2C Controller Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_status::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0StatusSpec; +impl crate::RegisterSpec for S0StatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_status::R`](R) reader structure"] +impl crate::Readable for S0StatusSpec {} +#[doc = "`reset()` method sets S0_STATUS to value 0"] +impl crate::Resettable for S0StatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_txcount.rs b/va108xx/src/i2ca/s0_txcount.rs new file mode 100644 index 0000000..a125c56 --- /dev/null +++ b/va108xx/src/i2ca/s0_txcount.rs @@ -0,0 +1,18 @@ +#[doc = "Register `S0_TXCOUNT` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Slave TX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_txcount::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0TxcountSpec; +impl crate::RegisterSpec for S0TxcountSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_txcount::R`](R) reader structure"] +impl crate::Readable for S0TxcountSpec {} +#[doc = "`reset()` method sets S0_TXCOUNT to value 0"] +impl crate::Resettable for S0TxcountSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/s0_txfifoirqtrg.rs b/va108xx/src/i2ca/s0_txfifoirqtrg.rs new file mode 100644 index 0000000..1c8f27a --- /dev/null +++ b/va108xx/src/i2ca/s0_txfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `S0_TXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `S0_TXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Slave Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`s0_txfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`s0_txfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct S0TxfifoirqtrgSpec; +impl crate::RegisterSpec for S0TxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`s0_txfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for S0TxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`s0_txfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for S0TxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets S0_TXFIFOIRQTRG to value 0"] +impl crate::Resettable for S0TxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/state.rs b/va108xx/src/i2ca/state.rs new file mode 100644 index 0000000..fe3c04e --- /dev/null +++ b/va108xx/src/i2ca/state.rs @@ -0,0 +1,18 @@ +#[doc = "Register `STATE` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Internal STATE of I2C Master Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct StateSpec; +impl crate::RegisterSpec for StateSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`state::R`](R) reader structure"] +impl crate::Readable for StateSpec {} +#[doc = "`reset()` method sets STATE to value 0"] +impl crate::Resettable for StateSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/status.rs b/va108xx/src/i2ca/status.rs new file mode 100644 index 0000000..f8f340e --- /dev/null +++ b/va108xx/src/i2ca/status.rs @@ -0,0 +1,120 @@ +#[doc = "Register `STATUS` reader"] +pub type R = crate::R; +#[doc = "Field `I2C_IDLE` reader - I2C bus is Idle"] +pub type I2cIdleR = crate::BitReader; +#[doc = "Field `IDLE` reader - Controller is Idle"] +pub type IdleR = crate::BitReader; +#[doc = "Field `WAITING` reader - Controller is Waiting"] +pub type WaitingR = crate::BitReader; +#[doc = "Field `STALLED` reader - Controller is Stalled"] +pub type StalledR = crate::BitReader; +#[doc = "Field `ARBLOST` reader - I2C Arbitration was lost"] +pub type ArblostR = crate::BitReader; +#[doc = "Field `NACKADDR` reader - I2C Address was not Acknowledged"] +pub type NackaddrR = crate::BitReader; +#[doc = "Field `NACKDATA` reader - I2C Data was not Acknowledged"] +pub type NackdataR = crate::BitReader; +#[doc = "Field `RXNEMPTY` reader - RX FIFO is Not Empty"] +pub type RxnemptyR = crate::BitReader; +#[doc = "Field `RXFULL` reader - RX FIFO is Full"] +pub type RxfullR = crate::BitReader; +#[doc = "Field `RXTRIGGER` reader - RX FIFO Above Trigger Level"] +pub type RxtriggerR = crate::BitReader; +#[doc = "Field `TXEMPTY` reader - TX FIFO is Empty"] +pub type TxemptyR = crate::BitReader; +#[doc = "Field `TXNFULL` reader - TX FIFO is Full"] +pub type TxnfullR = crate::BitReader; +#[doc = "Field `TXTRIGGER` reader - TX FIFO Below Trigger Level"] +pub type TxtriggerR = crate::BitReader; +#[doc = "Field `RAW_SDA` reader - I2C Raw SDA value"] +pub type RawSdaR = crate::BitReader; +#[doc = "Field `RAW_SCL` reader - I2C Raw SCL value"] +pub type RawSclR = crate::BitReader; +impl R { + #[doc = "Bit 0 - I2C bus is Idle"] + #[inline(always)] + pub fn i2c_idle(&self) -> I2cIdleR { + I2cIdleR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Controller is Idle"] + #[inline(always)] + pub fn idle(&self) -> IdleR { + IdleR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Controller is Waiting"] + #[inline(always)] + pub fn waiting(&self) -> WaitingR { + WaitingR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Controller is Stalled"] + #[inline(always)] + pub fn stalled(&self) -> StalledR { + StalledR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - I2C Arbitration was lost"] + #[inline(always)] + pub fn arblost(&self) -> ArblostR { + ArblostR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - I2C Address was not Acknowledged"] + #[inline(always)] + pub fn nackaddr(&self) -> NackaddrR { + NackaddrR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - I2C Data was not Acknowledged"] + #[inline(always)] + pub fn nackdata(&self) -> NackdataR { + NackdataR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 8 - RX FIFO is Not Empty"] + #[inline(always)] + pub fn rxnempty(&self) -> RxnemptyR { + RxnemptyR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - RX FIFO is Full"] + #[inline(always)] + pub fn rxfull(&self) -> RxfullR { + RxfullR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 11 - RX FIFO Above Trigger Level"] + #[inline(always)] + pub fn rxtrigger(&self) -> RxtriggerR { + RxtriggerR::new(((self.bits >> 11) & 1) != 0) + } + #[doc = "Bit 12 - TX FIFO is Empty"] + #[inline(always)] + pub fn txempty(&self) -> TxemptyR { + TxemptyR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bit 13 - TX FIFO is Full"] + #[inline(always)] + pub fn txnfull(&self) -> TxnfullR { + TxnfullR::new(((self.bits >> 13) & 1) != 0) + } + #[doc = "Bit 15 - TX FIFO Below Trigger Level"] + #[inline(always)] + pub fn txtrigger(&self) -> TxtriggerR { + TxtriggerR::new(((self.bits >> 15) & 1) != 0) + } + #[doc = "Bit 30 - I2C Raw SDA value"] + #[inline(always)] + pub fn raw_sda(&self) -> RawSdaR { + RawSdaR::new(((self.bits >> 30) & 1) != 0) + } + #[doc = "Bit 31 - I2C Raw SCL value"] + #[inline(always)] + pub fn raw_scl(&self) -> RawSclR { + RawSclR::new(((self.bits >> 31) & 1) != 0) + } +} +#[doc = "I2C Controller Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`status::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct StatusSpec; +impl crate::RegisterSpec for StatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`status::R`](R) reader structure"] +impl crate::Readable for StatusSpec {} +#[doc = "`reset()` method sets STATUS to value 0"] +impl crate::Resettable for StatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/tmconfig.rs b/va108xx/src/i2ca/tmconfig.rs new file mode 100644 index 0000000..2d0e025 --- /dev/null +++ b/va108xx/src/i2ca/tmconfig.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TMCONFIG` reader"] +pub type R = crate::R; +#[doc = "Register `TMCONFIG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Timing Config Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tmconfig::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tmconfig::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TmconfigSpec; +impl crate::RegisterSpec for TmconfigSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`tmconfig::R`](R) reader structure"] +impl crate::Readable for TmconfigSpec {} +#[doc = "`write(|w| ..)` method takes [`tmconfig::W`](W) writer structure"] +impl crate::Writable for TmconfigSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TMCONFIG to value 0"] +impl crate::Resettable for TmconfigSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/txcount.rs b/va108xx/src/i2ca/txcount.rs new file mode 100644 index 0000000..ae64e43 --- /dev/null +++ b/va108xx/src/i2ca/txcount.rs @@ -0,0 +1,18 @@ +#[doc = "Register `TXCOUNT` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "TX Count Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txcount::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxcountSpec; +impl crate::RegisterSpec for TxcountSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`txcount::R`](R) reader structure"] +impl crate::Readable for TxcountSpec {} +#[doc = "`reset()` method sets TXCOUNT to value 0"] +impl crate::Resettable for TxcountSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/txfifoirqtrg.rs b/va108xx/src/i2ca/txfifoirqtrg.rs new file mode 100644 index 0000000..0d13e54 --- /dev/null +++ b/va108xx/src/i2ca/txfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `TXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxfifoirqtrgSpec; +impl crate::RegisterSpec for TxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`txfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for TxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`txfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for TxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TXFIFOIRQTRG to value 0"] +impl crate::Resettable for TxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/i2ca/words.rs b/va108xx/src/i2ca/words.rs new file mode 100644 index 0000000..9aedb52 --- /dev/null +++ b/va108xx/src/i2ca/words.rs @@ -0,0 +1,27 @@ +#[doc = "Register `WORDS` reader"] +pub type R = crate::R; +#[doc = "Register `WORDS` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Word Count value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`words::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`words::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct WordsSpec; +impl crate::RegisterSpec for WordsSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`words::R`](R) reader structure"] +impl crate::Readable for WordsSpec {} +#[doc = "`write(|w| ..)` method takes [`words::W`](W) writer structure"] +impl crate::Writable for WordsSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets WORDS to value 0"] +impl crate::Resettable for WordsSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/ioconfig.rs b/va108xx/src/ioconfig.rs new file mode 100644 index 0000000..3e06b07 --- /dev/null +++ b/va108xx/src/ioconfig.rs @@ -0,0 +1,51 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + porta: [Porta; 32], + portb0: [Portb; 32], + _reserved2: [u8; 0x0efc], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00..0x80 - PORTA Pin Configuration Register"] + #[inline(always)] + pub const fn porta(&self, n: usize) -> &Porta { + &self.porta[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x00..0x80 - PORTA Pin Configuration Register"] + #[inline(always)] + pub fn porta_iter(&self) -> impl Iterator { + self.porta.iter() + } + #[doc = "0x80..0x100 - PORTB Pin Configuration Register"] + #[inline(always)] + pub const fn portb0(&self, n: usize) -> &Portb { + &self.portb0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x80..0x100 - PORTB Pin Configuration Register"] + #[inline(always)] + pub fn portb0_iter(&self) -> impl Iterator { + self.portb0.iter() + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "PORTA (rw) register accessor: PORTA Pin Configuration Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`porta::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`porta::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@porta`] +module"] +#[doc(alias = "PORTA")] +pub type Porta = crate::Reg; +#[doc = "PORTA Pin Configuration Register"] +pub mod porta; +pub use porta as portb; +pub use Porta as Portb; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/ioconfig/perid.rs b/va108xx/src/ioconfig/perid.rs new file mode 100644 index 0000000..7b4aa79 --- /dev/null +++ b/va108xx/src/ioconfig/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0082_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0082_07e1; +} diff --git a/va108xx/src/ioconfig/porta.rs b/va108xx/src/ioconfig/porta.rs new file mode 100644 index 0000000..b068faa --- /dev/null +++ b/va108xx/src/ioconfig/porta.rs @@ -0,0 +1,299 @@ +#[doc = "Register `PORTA[%s]` reader"] +pub type R = crate::R; +#[doc = "Register `PORTA[%s]` writer"] +pub type W = crate::W; +#[doc = "Input Filter Selectoin\n\nValue on reset: 0"] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum Flttype { + #[doc = "0: Synchronize to system clock"] + Sync = 0, + #[doc = "1: Direct input, no synchronization"] + Direct = 1, + #[doc = "2: Require 2 samples to have the same value"] + Filter1 = 2, + #[doc = "3: Require 3 samples to have the same value"] + Filter2 = 3, + #[doc = "4: Require 4 samples to have the same value"] + Filter3 = 4, + #[doc = "5: Require 5 samples to have the same value"] + Filter4 = 5, +} +impl From for u8 { + #[inline(always)] + fn from(variant: Flttype) -> Self { + variant as _ + } +} +impl crate::FieldSpec for Flttype { + type Ux = u8; +} +impl crate::IsEnum for Flttype {} +#[doc = "Field `FLTTYPE` reader - Input Filter Selectoin"] +pub type FlttypeR = crate::FieldReader; +impl FlttypeR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(Flttype::Sync), + 1 => Some(Flttype::Direct), + 2 => Some(Flttype::Filter1), + 3 => Some(Flttype::Filter2), + 4 => Some(Flttype::Filter3), + 5 => Some(Flttype::Filter4), + _ => None, + } + } + #[doc = "Synchronize to system clock"] + #[inline(always)] + pub fn is_sync(&self) -> bool { + *self == Flttype::Sync + } + #[doc = "Direct input, no synchronization"] + #[inline(always)] + pub fn is_direct(&self) -> bool { + *self == Flttype::Direct + } + #[doc = "Require 2 samples to have the same value"] + #[inline(always)] + pub fn is_filter1(&self) -> bool { + *self == Flttype::Filter1 + } + #[doc = "Require 3 samples to have the same value"] + #[inline(always)] + pub fn is_filter2(&self) -> bool { + *self == Flttype::Filter2 + } + #[doc = "Require 4 samples to have the same value"] + #[inline(always)] + pub fn is_filter3(&self) -> bool { + *self == Flttype::Filter3 + } + #[doc = "Require 5 samples to have the same value"] + #[inline(always)] + pub fn is_filter4(&self) -> bool { + *self == Flttype::Filter4 + } +} +#[doc = "Field `FLTTYPE` writer - Input Filter Selectoin"] +pub type FlttypeW<'a, REG> = crate::FieldWriter<'a, REG, 3, Flttype>; +impl<'a, REG> FlttypeW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Synchronize to system clock"] + #[inline(always)] + pub fn sync(self) -> &'a mut crate::W { + self.variant(Flttype::Sync) + } + #[doc = "Direct input, no synchronization"] + #[inline(always)] + pub fn direct(self) -> &'a mut crate::W { + self.variant(Flttype::Direct) + } + #[doc = "Require 2 samples to have the same value"] + #[inline(always)] + pub fn filter1(self) -> &'a mut crate::W { + self.variant(Flttype::Filter1) + } + #[doc = "Require 3 samples to have the same value"] + #[inline(always)] + pub fn filter2(self) -> &'a mut crate::W { + self.variant(Flttype::Filter2) + } + #[doc = "Require 4 samples to have the same value"] + #[inline(always)] + pub fn filter3(self) -> &'a mut crate::W { + self.variant(Flttype::Filter3) + } + #[doc = "Require 5 samples to have the same value"] + #[inline(always)] + pub fn filter4(self) -> &'a mut crate::W { + self.variant(Flttype::Filter4) + } +} +#[doc = "Field `FLTCLK` reader - Input Filter Clock Selection"] +pub type FltclkR = crate::FieldReader; +#[doc = "Field `FLTCLK` writer - Input Filter Clock Selection"] +pub type FltclkW<'a, REG> = crate::FieldWriter<'a, REG, 3>; +#[doc = "Field `INVINP` reader - Input Invert Selection"] +pub type InvinpR = crate::BitReader; +#[doc = "Field `INVINP` writer - Input Invert Selection"] +pub type InvinpW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IEWO` reader - Input Enable While Output enabled"] +pub type IewoR = crate::BitReader; +#[doc = "Field `IEWO` writer - Input Enable While Output enabled"] +pub type IewoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `OPENDRN` reader - Output Open Drain Mode"] +pub type OpendrnR = crate::BitReader; +#[doc = "Field `OPENDRN` writer - Output Open Drain Mode"] +pub type OpendrnW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `INVOUT` reader - Output Invert Selection"] +pub type InvoutR = crate::BitReader; +#[doc = "Field `INVOUT` writer - Output Invert Selection"] +pub type InvoutW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PLEVEL` reader - Internal Pull up/down level"] +pub type PlevelR = crate::BitReader; +#[doc = "Field `PLEVEL` writer - Internal Pull up/down level"] +pub type PlevelW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PEN` reader - Enable Internal Pull up/down"] +pub type PenR = crate::BitReader; +#[doc = "Field `PEN` writer - Enable Internal Pull up/down"] +pub type PenW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PWOA` reader - Enable Pull when output active"] +pub type PwoaR = crate::BitReader; +#[doc = "Field `PWOA` writer - Enable Pull when output active"] +pub type PwoaW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `FUNSEL` reader - Pin Function Selection"] +pub type FunselR = crate::FieldReader; +#[doc = "Field `FUNSEL` writer - Pin Function Selection"] +pub type FunselW<'a, REG> = crate::FieldWriter<'a, REG, 3>; +#[doc = "Field `IODIS` reader - IO Pin Disable"] +pub type IodisR = crate::BitReader; +#[doc = "Field `IODIS` writer - IO Pin Disable"] +pub type IodisW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bits 0:2 - Input Filter Selectoin"] + #[inline(always)] + pub fn flttype(&self) -> FlttypeR { + FlttypeR::new((self.bits & 7) as u8) + } + #[doc = "Bits 3:5 - Input Filter Clock Selection"] + #[inline(always)] + pub fn fltclk(&self) -> FltclkR { + FltclkR::new(((self.bits >> 3) & 7) as u8) + } + #[doc = "Bit 6 - Input Invert Selection"] + #[inline(always)] + pub fn invinp(&self) -> InvinpR { + InvinpR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - Input Enable While Output enabled"] + #[inline(always)] + pub fn iewo(&self) -> IewoR { + IewoR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - Output Open Drain Mode"] + #[inline(always)] + pub fn opendrn(&self) -> OpendrnR { + OpendrnR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Output Invert Selection"] + #[inline(always)] + pub fn invout(&self) -> InvoutR { + InvoutR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - Internal Pull up/down level"] + #[inline(always)] + pub fn plevel(&self) -> PlevelR { + PlevelR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - Enable Internal Pull up/down"] + #[inline(always)] + pub fn pen(&self) -> PenR { + PenR::new(((self.bits >> 11) & 1) != 0) + } + #[doc = "Bit 12 - Enable Pull when output active"] + #[inline(always)] + pub fn pwoa(&self) -> PwoaR { + PwoaR::new(((self.bits >> 12) & 1) != 0) + } + #[doc = "Bits 13:15 - Pin Function Selection"] + #[inline(always)] + pub fn funsel(&self) -> FunselR { + FunselR::new(((self.bits >> 13) & 7) as u8) + } + #[doc = "Bit 16 - IO Pin Disable"] + #[inline(always)] + pub fn iodis(&self) -> IodisR { + IodisR::new(((self.bits >> 16) & 1) != 0) + } +} +impl W { + #[doc = "Bits 0:2 - Input Filter Selectoin"] + #[inline(always)] + #[must_use] + pub fn flttype(&mut self) -> FlttypeW { + FlttypeW::new(self, 0) + } + #[doc = "Bits 3:5 - Input Filter Clock Selection"] + #[inline(always)] + #[must_use] + pub fn fltclk(&mut self) -> FltclkW { + FltclkW::new(self, 3) + } + #[doc = "Bit 6 - Input Invert Selection"] + #[inline(always)] + #[must_use] + pub fn invinp(&mut self) -> InvinpW { + InvinpW::new(self, 6) + } + #[doc = "Bit 7 - Input Enable While Output enabled"] + #[inline(always)] + #[must_use] + pub fn iewo(&mut self) -> IewoW { + IewoW::new(self, 7) + } + #[doc = "Bit 8 - Output Open Drain Mode"] + #[inline(always)] + #[must_use] + pub fn opendrn(&mut self) -> OpendrnW { + OpendrnW::new(self, 8) + } + #[doc = "Bit 9 - Output Invert Selection"] + #[inline(always)] + #[must_use] + pub fn invout(&mut self) -> InvoutW { + InvoutW::new(self, 9) + } + #[doc = "Bit 10 - Internal Pull up/down level"] + #[inline(always)] + #[must_use] + pub fn plevel(&mut self) -> PlevelW { + PlevelW::new(self, 10) + } + #[doc = "Bit 11 - Enable Internal Pull up/down"] + #[inline(always)] + #[must_use] + pub fn pen(&mut self) -> PenW { + PenW::new(self, 11) + } + #[doc = "Bit 12 - Enable Pull when output active"] + #[inline(always)] + #[must_use] + pub fn pwoa(&mut self) -> PwoaW { + PwoaW::new(self, 12) + } + #[doc = "Bits 13:15 - Pin Function Selection"] + #[inline(always)] + #[must_use] + pub fn funsel(&mut self) -> FunselW { + FunselW::new(self, 13) + } + #[doc = "Bit 16 - IO Pin Disable"] + #[inline(always)] + #[must_use] + pub fn iodis(&mut self) -> IodisW { + IodisW::new(self, 16) + } +} +#[doc = "PORTA Pin Configuration Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`porta::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`porta::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PortaSpec; +impl crate::RegisterSpec for PortaSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`porta::R`](R) reader structure"] +impl crate::Readable for PortaSpec {} +#[doc = "`write(|w| ..)` method takes [`porta::W`](W) writer structure"] +impl crate::Writable for PortaSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PORTA[%s] +to value 0"] +impl crate::Resettable for PortaSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/irqsel.rs b/va108xx/src/irqsel.rs new file mode 100644 index 0000000..c90a7e0 --- /dev/null +++ b/va108xx/src/irqsel.rs @@ -0,0 +1,221 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + porta0: [Porta; 32], + portb0: [Portb; 32], + tim0: [Tim; 32], + uart0: [Uart; 4], + spi0: [Spi; 4], + i2c_ms0: [I2cMs; 4], + i2c_sl0: [I2cSl; 4], + int_ram_sbe: IntRamSbe, + int_ram_mbe: IntRamMbe, + int_rom_sbe: IntRomSbe, + int_rom_mbe: IntRomMbe, + txev: Txev, + _reserved12: [u8; 0x062c], + irqs0: [Irqs; 32], + _reserved13: [u8; 0x68], + edbgrq: Edbgrq, + mereset: Mereset, + watchdog: Watchdog, + rxev: Rxev, + nmi: Nmi, + _reserved18: [u8; 0x0700], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00..0x80 - PORTA Interrupt Redirect Selection"] + #[inline(always)] + pub const fn porta0(&self, n: usize) -> &Porta { + &self.porta0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x00..0x80 - PORTA Interrupt Redirect Selection"] + #[inline(always)] + pub fn porta0_iter(&self) -> impl Iterator { + self.porta0.iter() + } + #[doc = "0x80..0x100 - PORTB Interrupt Redirect Selection"] + #[inline(always)] + pub const fn portb0(&self, n: usize) -> &Portb { + &self.portb0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x80..0x100 - PORTB Interrupt Redirect Selection"] + #[inline(always)] + pub fn portb0_iter(&self) -> impl Iterator { + self.portb0.iter() + } + #[doc = "0x100..0x180 - TIM Interrupt Redirect Selection"] + #[inline(always)] + pub const fn tim0(&self, n: usize) -> &Tim { + &self.tim0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x100..0x180 - TIM Interrupt Redirect Selection"] + #[inline(always)] + pub fn tim0_iter(&self) -> impl Iterator { + self.tim0.iter() + } + #[doc = "0x180..0x190 - UART Interrupt Redirect Selection"] + #[inline(always)] + pub const fn uart0(&self, n: usize) -> &Uart { + &self.uart0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x180..0x190 - UART Interrupt Redirect Selection"] + #[inline(always)] + pub fn uart0_iter(&self) -> impl Iterator { + self.uart0.iter() + } + #[doc = "0x190..0x1a0 - SPI Interrupt Redirect Selection"] + #[inline(always)] + pub const fn spi0(&self, n: usize) -> &Spi { + &self.spi0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x190..0x1a0 - SPI Interrupt Redirect Selection"] + #[inline(always)] + pub fn spi0_iter(&self) -> impl Iterator { + self.spi0.iter() + } + #[doc = "0x1a0..0x1b0 - Master I2C Interrupt Redirect Selection"] + #[inline(always)] + pub const fn i2c_ms0(&self, n: usize) -> &I2cMs { + &self.i2c_ms0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x1a0..0x1b0 - Master I2C Interrupt Redirect Selection"] + #[inline(always)] + pub fn i2c_ms0_iter(&self) -> impl Iterator { + self.i2c_ms0.iter() + } + #[doc = "0x1b0..0x1c0 - Slave I2C Interrupt Redirect Selection"] + #[inline(always)] + pub const fn i2c_sl0(&self, n: usize) -> &I2cSl { + &self.i2c_sl0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x1b0..0x1c0 - Slave I2C Interrupt Redirect Selection"] + #[inline(always)] + pub fn i2c_sl0_iter(&self) -> impl Iterator { + self.i2c_sl0.iter() + } + #[doc = "0x1c0 - Internal Memory RAM SBE Interrupt Redirect Selection"] + #[inline(always)] + pub const fn int_ram_sbe(&self) -> &IntRamSbe { + &self.int_ram_sbe + } + #[doc = "0x1c4 - Internal Memory RAM MBE Interrupt Redirect Selection"] + #[inline(always)] + pub const fn int_ram_mbe(&self) -> &IntRamMbe { + &self.int_ram_mbe + } + #[doc = "0x1c8 - Internal Memory ROM SBE Interrupt Redirect Selection"] + #[inline(always)] + pub const fn int_rom_sbe(&self) -> &IntRomSbe { + &self.int_rom_sbe + } + #[doc = "0x1cc - Internal Memory ROM MBE Interrupt Redirect Selection"] + #[inline(always)] + pub const fn int_rom_mbe(&self) -> &IntRomMbe { + &self.int_rom_mbe + } + #[doc = "0x1d0 - Processor TXEV Interrupt Redirect Selection"] + #[inline(always)] + pub const fn txev(&self) -> &Txev { + &self.txev + } + #[doc = "0x800..0x880 - Interrupt Status Register"] + #[inline(always)] + pub const fn irqs0(&self, n: usize) -> &Irqs { + &self.irqs0[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x800..0x880 - Interrupt Status Register"] + #[inline(always)] + pub fn irqs0_iter(&self) -> impl Iterator { + self.irqs0.iter() + } + #[doc = "0x8e8 - EDBGRQ Status Register"] + #[inline(always)] + pub const fn edbgrq(&self) -> &Edbgrq { + &self.edbgrq + } + #[doc = "0x8ec - MERESET Status Register"] + #[inline(always)] + pub const fn mereset(&self) -> &Mereset { + &self.mereset + } + #[doc = "0x8f0 - WATCHDOG Status Register"] + #[inline(always)] + pub const fn watchdog(&self) -> &Watchdog { + &self.watchdog + } + #[doc = "0x8f4 - RXEV Status Register"] + #[inline(always)] + pub const fn rxev(&self) -> &Rxev { + &self.rxev + } + #[doc = "0x8f8 - NMI Status Register"] + #[inline(always)] + pub const fn nmi(&self) -> &Nmi { + &self.nmi + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "INT_RAM_SBE (rw) register accessor: Internal Memory RAM SBE Interrupt Redirect Selection\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`int_ram_sbe::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`int_ram_sbe::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@int_ram_sbe`] +module"] +#[doc(alias = "INT_RAM_SBE")] +pub type IntRamSbe = crate::Reg; +#[doc = "Internal Memory RAM SBE Interrupt Redirect Selection"] +pub mod int_ram_sbe; +pub use int_ram_sbe as porta; +pub use int_ram_sbe as portb; +pub use int_ram_sbe as tim; +pub use int_ram_sbe as uart; +pub use int_ram_sbe as spi; +pub use int_ram_sbe as i2c_ms; +pub use int_ram_sbe as i2c_sl; +pub use int_ram_sbe as int_ram_mbe; +pub use int_ram_sbe as int_rom_sbe; +pub use int_ram_sbe as int_rom_mbe; +pub use int_ram_sbe as txev; +pub use IntRamSbe as Porta; +pub use IntRamSbe as Portb; +pub use IntRamSbe as Tim; +pub use IntRamSbe as Uart; +pub use IntRamSbe as Spi; +pub use IntRamSbe as I2cMs; +pub use IntRamSbe as I2cSl; +pub use IntRamSbe as IntRamMbe; +pub use IntRamSbe as IntRomSbe; +pub use IntRamSbe as IntRomMbe; +pub use IntRamSbe as Txev; +#[doc = "NMI (r) register accessor: NMI Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`nmi::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@nmi`] +module"] +#[doc(alias = "NMI")] +pub type Nmi = crate::Reg; +#[doc = "NMI Status Register"] +pub mod nmi; +pub use nmi as rxev; +pub use nmi as watchdog; +pub use nmi as mereset; +pub use nmi as edbgrq; +pub use nmi as irqs; +pub use Nmi as Rxev; +pub use Nmi as Watchdog; +pub use Nmi as Mereset; +pub use Nmi as Edbgrq; +pub use Nmi as Irqs; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/irqsel/int_ram_sbe.rs b/va108xx/src/irqsel/int_ram_sbe.rs new file mode 100644 index 0000000..5d1f412 --- /dev/null +++ b/va108xx/src/irqsel/int_ram_sbe.rs @@ -0,0 +1,27 @@ +#[doc = "Register `INT_RAM_SBE` reader"] +pub type R = crate::R; +#[doc = "Register `INT_RAM_SBE` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Internal Memory RAM SBE Interrupt Redirect Selection\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`int_ram_sbe::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`int_ram_sbe::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IntRamSbeSpec; +impl crate::RegisterSpec for IntRamSbeSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`int_ram_sbe::R`](R) reader structure"] +impl crate::Readable for IntRamSbeSpec {} +#[doc = "`write(|w| ..)` method takes [`int_ram_sbe::W`](W) writer structure"] +impl crate::Writable for IntRamSbeSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets INT_RAM_SBE to value 0xffff_ffff"] +impl crate::Resettable for IntRamSbeSpec { + const RESET_VALUE: u32 = 0xffff_ffff; +} diff --git a/va108xx/src/irqsel/nmi.rs b/va108xx/src/irqsel/nmi.rs new file mode 100644 index 0000000..9dde175 --- /dev/null +++ b/va108xx/src/irqsel/nmi.rs @@ -0,0 +1,22 @@ +#[doc = "Register `NMI` reader"] +pub type R = crate::R; +#[doc = "Field `ACTIVE` reader - Active"] +pub type ActiveR = crate::BitReader; +impl R { + #[doc = "Bit 0 - Active"] + #[inline(always)] + pub fn active(&self) -> ActiveR { + ActiveR::new((self.bits & 1) != 0) + } +} +#[doc = "NMI Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`nmi::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct NmiSpec; +impl crate::RegisterSpec for NmiSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`nmi::R`](R) reader structure"] +impl crate::Readable for NmiSpec {} +#[doc = "`reset()` method sets NMI to value 0"] +impl crate::Resettable for NmiSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/irqsel/perid.rs b/va108xx/src/irqsel/perid.rs new file mode 100644 index 0000000..5a84e29 --- /dev/null +++ b/va108xx/src/irqsel/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0080_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0080_07e1; +} diff --git a/va108xx/src/lib.rs b/va108xx/src/lib.rs new file mode 100644 index 0000000..15bab0c --- /dev/null +++ b/va108xx/src/lib.rs @@ -0,0 +1,2088 @@ +#![doc = "Peripheral access API for VA108XX microcontrollers (generated using svd2rust v0.33.3 ( ))\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.33.3/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 = 2; +#[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 OC0(); + fn OC1(); + fn OC2(); + fn OC3(); + fn OC4(); + fn OC5(); + fn OC6(); + fn OC7(); + fn OC8(); + fn OC9(); + fn OC10(); + fn OC11(); + fn OC12(); + fn OC13(); + fn OC14(); + fn OC15(); + fn OC16(); + fn OC17(); + fn OC18(); + fn OC19(); + fn OC20(); + fn OC21(); + fn OC22(); + fn OC23(); + fn OC24(); + fn OC25(); + fn OC26(); + fn OC27(); + fn OC28(); + fn OC29(); + fn OC30(); + fn OC31(); +} +#[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; 32] = [ + Vector { _handler: OC0 }, + Vector { _handler: OC1 }, + Vector { _handler: OC2 }, + Vector { _handler: OC3 }, + Vector { _handler: OC4 }, + Vector { _handler: OC5 }, + Vector { _handler: OC6 }, + Vector { _handler: OC7 }, + Vector { _handler: OC8 }, + Vector { _handler: OC9 }, + Vector { _handler: OC10 }, + Vector { _handler: OC11 }, + Vector { _handler: OC12 }, + Vector { _handler: OC13 }, + Vector { _handler: OC14 }, + Vector { _handler: OC15 }, + Vector { _handler: OC16 }, + Vector { _handler: OC17 }, + Vector { _handler: OC18 }, + Vector { _handler: OC19 }, + Vector { _handler: OC20 }, + Vector { _handler: OC21 }, + Vector { _handler: OC22 }, + Vector { _handler: OC23 }, + Vector { _handler: OC24 }, + Vector { _handler: OC25 }, + Vector { _handler: OC26 }, + Vector { _handler: OC27 }, + Vector { _handler: OC28 }, + Vector { _handler: OC29 }, + Vector { _handler: OC30 }, + Vector { _handler: OC31 }, +]; +#[doc = r"Enumeration of all the interrupts."] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u16)] +pub enum Interrupt { + #[doc = "0 - OC0"] + OC0 = 0, + #[doc = "1 - OC1"] + OC1 = 1, + #[doc = "2 - OC2"] + OC2 = 2, + #[doc = "3 - OC3"] + OC3 = 3, + #[doc = "4 - OC4"] + OC4 = 4, + #[doc = "5 - OC5"] + OC5 = 5, + #[doc = "6 - OC6"] + OC6 = 6, + #[doc = "7 - OC7"] + OC7 = 7, + #[doc = "8 - OC8"] + OC8 = 8, + #[doc = "9 - OC9"] + OC9 = 9, + #[doc = "10 - OC10"] + OC10 = 10, + #[doc = "11 - OC11"] + OC11 = 11, + #[doc = "12 - OC12"] + OC12 = 12, + #[doc = "13 - OC13"] + OC13 = 13, + #[doc = "14 - OC14"] + OC14 = 14, + #[doc = "15 - OC15"] + OC15 = 15, + #[doc = "16 - OC16"] + OC16 = 16, + #[doc = "17 - OC17"] + OC17 = 17, + #[doc = "18 - OC18"] + OC18 = 18, + #[doc = "19 - OC19"] + OC19 = 19, + #[doc = "20 - OC20"] + OC20 = 20, + #[doc = "21 - OC21"] + OC21 = 21, + #[doc = "22 - OC22"] + OC22 = 22, + #[doc = "23 - OC23"] + OC23 = 23, + #[doc = "24 - OC24"] + OC24 = 24, + #[doc = "25 - OC25"] + OC25 = 25, + #[doc = "26 - OC26"] + OC26 = 26, + #[doc = "27 - OC27"] + OC27 = 27, + #[doc = "28 - OC28"] + OC28 = 28, + #[doc = "29 - OC29"] + OC29 = 29, + #[doc = "30 - OC30"] + OC30 = 30, + #[doc = "31 - OC31"] + OC31 = 31, +} +unsafe impl cortex_m::interrupt::InterruptNumber for Interrupt { + #[inline(always)] + fn number(self) -> u16 { + self as u16 + } +} +#[doc = "System Configuration Peripheral"] +pub struct Sysconfig { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Sysconfig {} +impl Sysconfig { + #[doc = r"Pointer to the register block"] + pub const PTR: *const sysconfig::RegisterBlock = 0x4000_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const sysconfig::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 Sysconfig { + type Target = sysconfig::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Sysconfig { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Sysconfig").finish() + } +} +#[doc = "System Configuration Peripheral"] +pub mod sysconfig; +#[doc = "Interrupt Selector Peripheral"] +pub struct Irqsel { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Irqsel {} +impl Irqsel { + #[doc = r"Pointer to the register block"] + pub const PTR: *const irqsel::RegisterBlock = 0x4000_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const irqsel::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 Irqsel { + type Target = irqsel::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Irqsel { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Irqsel").finish() + } +} +#[doc = "Interrupt Selector Peripheral"] +pub mod irqsel; +#[doc = "IO Pin Configuration Peripheral"] +pub struct Ioconfig { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Ioconfig {} +impl Ioconfig { + #[doc = r"Pointer to the register block"] + pub const PTR: *const ioconfig::RegisterBlock = 0x4000_2000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const ioconfig::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 Ioconfig { + type Target = ioconfig::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Ioconfig { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Ioconfig").finish() + } +} +#[doc = "IO Pin Configuration Peripheral"] +pub mod ioconfig; +#[doc = "Utility Peripheral"] +pub struct Utility { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Utility {} +impl Utility { + #[doc = r"Pointer to the register block"] + pub const PTR: *const utility::RegisterBlock = 0x4000_3000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const utility::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 Utility { + type Target = utility::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Utility { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Utility").finish() + } +} +#[doc = "Utility Peripheral"] +pub mod utility; +#[doc = "GPIO Peripheral"] +pub struct Porta { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Porta {} +impl Porta { + #[doc = r"Pointer to the register block"] + pub const PTR: *const porta::RegisterBlock = 0x5000_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const porta::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 Porta { + type Target = porta::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Porta { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Porta").finish() + } +} +#[doc = "GPIO Peripheral"] +pub mod porta; +#[doc = "GPIO Peripheral"] +pub struct Portb { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Portb {} +impl Portb { + #[doc = r"Pointer to the register block"] + pub const PTR: *const porta::RegisterBlock = 0x5000_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const porta::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 Portb { + type Target = porta::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Portb { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Portb").finish() + } +} +#[doc = "GPIO Peripheral"] +pub use self::porta as portb; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim0 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim0 {} +impl Tim0 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim0 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim0 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim0").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub mod tim0; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim1 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim1 {} +impl Tim1 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim1 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim1 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim1").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim1; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim2 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim2 {} +impl Tim2 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_2000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim2 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim2 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim2").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim2; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim3 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim3 {} +impl Tim3 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_3000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim3 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim3 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim3").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim3; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim4 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim4 {} +impl Tim4 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_4000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim4 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim4 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim4").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim4; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim5 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim5 {} +impl Tim5 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_5000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim5 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim5 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim5").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim5; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim6 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim6 {} +impl Tim6 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_6000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim6 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim6 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim6").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim6; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim7 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim7 {} +impl Tim7 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_7000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim7 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim7 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim7").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim7; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim8 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim8 {} +impl Tim8 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_8000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim8 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim8 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim8").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim8; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim9 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim9 {} +impl Tim9 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_9000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim9 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim9 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim9").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim9; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim10 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim10 {} +impl Tim10 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_a000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim10 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim10 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim10").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim10; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim11 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim11 {} +impl Tim11 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_b000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim11 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim11 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim11").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim11; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim12 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim12 {} +impl Tim12 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_c000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim12 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim12 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim12").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim12; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim13 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim13 {} +impl Tim13 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_d000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim13 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim13 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim13").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim13; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim14 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim14 {} +impl Tim14 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_e000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim14 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim14 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim14").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim14; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim15 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim15 {} +impl Tim15 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4002_f000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim15 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim15 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim15").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim15; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim16 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim16 {} +impl Tim16 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim16 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim16 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim16").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim16; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim17 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim17 {} +impl Tim17 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim17 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim17 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim17").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim17; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim18 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim18 {} +impl Tim18 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_2000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim18 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim18 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim18").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim18; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim19 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim19 {} +impl Tim19 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_3000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim19 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim19 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim19").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim19; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim20 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim20 {} +impl Tim20 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_4000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim20 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim20 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim20").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim20; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim21 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim21 {} +impl Tim21 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_5000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim21 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim21 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim21").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim21; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim22 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim22 {} +impl Tim22 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_6000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim22 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim22 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim22").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim22; +#[doc = "Timer/Counter Peripheral"] +pub struct Tim23 { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Tim23 {} +impl Tim23 { + #[doc = r"Pointer to the register block"] + pub const PTR: *const tim0::RegisterBlock = 0x4003_7000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const tim0::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 Tim23 { + type Target = tim0::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Tim23 { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Tim23").finish() + } +} +#[doc = "Timer/Counter Peripheral"] +pub use self::tim0 as tim23; +#[doc = "UART Peripheral"] +pub struct Uarta { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Uarta {} +impl Uarta { + #[doc = r"Pointer to the register block"] + pub const PTR: *const uarta::RegisterBlock = 0x4004_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const uarta::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 Uarta { + type Target = uarta::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Uarta { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Uarta").finish() + } +} +#[doc = "UART Peripheral"] +pub mod uarta; +#[doc = "UART Peripheral"] +pub struct Uartb { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Uartb {} +impl Uartb { + #[doc = r"Pointer to the register block"] + pub const PTR: *const uarta::RegisterBlock = 0x4004_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const uarta::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 Uartb { + type Target = uarta::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Uartb { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Uartb").finish() + } +} +#[doc = "UART Peripheral"] +pub use self::uarta as uartb; +#[doc = "SPI Peripheral"] +pub struct Spia { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Spia {} +impl Spia { + #[doc = r"Pointer to the register block"] + pub const PTR: *const spia::RegisterBlock = 0x4005_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const spia::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 Spia { + type Target = spia::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Spia { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Spia").finish() + } +} +#[doc = "SPI Peripheral"] +pub mod spia; +#[doc = "SPI Peripheral"] +pub struct Spib { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Spib {} +impl Spib { + #[doc = r"Pointer to the register block"] + pub const PTR: *const spia::RegisterBlock = 0x4005_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const spia::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 Spib { + type Target = spia::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Spib { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Spib").finish() + } +} +#[doc = "SPI Peripheral"] +pub use self::spia as spib; +#[doc = "SPI Peripheral"] +pub struct Spic { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for Spic {} +impl Spic { + #[doc = r"Pointer to the register block"] + pub const PTR: *const spia::RegisterBlock = 0x4005_2000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const spia::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 Spic { + type Target = spia::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for Spic { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Spic").finish() + } +} +#[doc = "SPI Peripheral"] +pub use self::spia as spic; +#[doc = "I2C Peripheral"] +pub struct I2ca { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for I2ca {} +impl I2ca { + #[doc = r"Pointer to the register block"] + pub const PTR: *const i2ca::RegisterBlock = 0x4006_0000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const i2ca::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 I2ca { + type Target = i2ca::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for I2ca { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("I2ca").finish() + } +} +#[doc = "I2C Peripheral"] +pub mod i2ca; +#[doc = "I2C Peripheral"] +pub struct I2cb { + _marker: PhantomData<*const ()>, +} +unsafe impl Send for I2cb {} +impl I2cb { + #[doc = r"Pointer to the register block"] + pub const PTR: *const i2ca::RegisterBlock = 0x4006_1000 as *const _; + #[doc = r"Return the pointer to the register block"] + #[inline(always)] + pub const fn ptr() -> *const i2ca::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 I2cb { + type Target = i2ca::RegisterBlock; + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { &*Self::PTR } + } +} +impl core::fmt::Debug for I2cb { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("I2cb").finish() + } +} +#[doc = "I2C Peripheral"] +pub use self::i2ca as i2cb; +#[no_mangle] +static mut DEVICE_PERIPHERALS: bool = false; +#[doc = r" All the peripherals."] +#[allow(non_snake_case)] +pub struct Peripherals { + #[doc = "SYSCONFIG"] + pub sysconfig: Sysconfig, + #[doc = "IRQSEL"] + pub irqsel: Irqsel, + #[doc = "IOCONFIG"] + pub ioconfig: Ioconfig, + #[doc = "UTILITY"] + pub utility: Utility, + #[doc = "PORTA"] + pub porta: Porta, + #[doc = "PORTB"] + pub portb: Portb, + #[doc = "TIM0"] + pub tim0: Tim0, + #[doc = "TIM1"] + pub tim1: Tim1, + #[doc = "TIM2"] + pub tim2: Tim2, + #[doc = "TIM3"] + pub tim3: Tim3, + #[doc = "TIM4"] + pub tim4: Tim4, + #[doc = "TIM5"] + pub tim5: Tim5, + #[doc = "TIM6"] + pub tim6: Tim6, + #[doc = "TIM7"] + pub tim7: Tim7, + #[doc = "TIM8"] + pub tim8: Tim8, + #[doc = "TIM9"] + pub tim9: Tim9, + #[doc = "TIM10"] + pub tim10: Tim10, + #[doc = "TIM11"] + pub tim11: Tim11, + #[doc = "TIM12"] + pub tim12: Tim12, + #[doc = "TIM13"] + pub tim13: Tim13, + #[doc = "TIM14"] + pub tim14: Tim14, + #[doc = "TIM15"] + pub tim15: Tim15, + #[doc = "TIM16"] + pub tim16: Tim16, + #[doc = "TIM17"] + pub tim17: Tim17, + #[doc = "TIM18"] + pub tim18: Tim18, + #[doc = "TIM19"] + pub tim19: Tim19, + #[doc = "TIM20"] + pub tim20: Tim20, + #[doc = "TIM21"] + pub tim21: Tim21, + #[doc = "TIM22"] + pub tim22: Tim22, + #[doc = "TIM23"] + pub tim23: Tim23, + #[doc = "UARTA"] + pub uarta: Uarta, + #[doc = "UARTB"] + pub uartb: Uartb, + #[doc = "SPIA"] + pub spia: Spia, + #[doc = "SPIB"] + pub spib: Spib, + #[doc = "SPIC"] + pub spic: Spic, + #[doc = "I2CA"] + pub i2ca: I2ca, + #[doc = "I2CB"] + pub i2cb: I2cb, +} +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 { + sysconfig: Sysconfig { + _marker: PhantomData, + }, + irqsel: Irqsel { + _marker: PhantomData, + }, + ioconfig: Ioconfig { + _marker: PhantomData, + }, + utility: Utility { + _marker: PhantomData, + }, + porta: Porta { + _marker: PhantomData, + }, + portb: Portb { + _marker: PhantomData, + }, + tim0: Tim0 { + _marker: PhantomData, + }, + tim1: Tim1 { + _marker: PhantomData, + }, + tim2: Tim2 { + _marker: PhantomData, + }, + tim3: Tim3 { + _marker: PhantomData, + }, + tim4: Tim4 { + _marker: PhantomData, + }, + tim5: Tim5 { + _marker: PhantomData, + }, + tim6: Tim6 { + _marker: PhantomData, + }, + tim7: Tim7 { + _marker: PhantomData, + }, + tim8: Tim8 { + _marker: PhantomData, + }, + tim9: Tim9 { + _marker: PhantomData, + }, + tim10: Tim10 { + _marker: PhantomData, + }, + tim11: Tim11 { + _marker: PhantomData, + }, + tim12: Tim12 { + _marker: PhantomData, + }, + tim13: Tim13 { + _marker: PhantomData, + }, + tim14: Tim14 { + _marker: PhantomData, + }, + tim15: Tim15 { + _marker: PhantomData, + }, + tim16: Tim16 { + _marker: PhantomData, + }, + tim17: Tim17 { + _marker: PhantomData, + }, + tim18: Tim18 { + _marker: PhantomData, + }, + tim19: Tim19 { + _marker: PhantomData, + }, + tim20: Tim20 { + _marker: PhantomData, + }, + tim21: Tim21 { + _marker: PhantomData, + }, + tim22: Tim22 { + _marker: PhantomData, + }, + tim23: Tim23 { + _marker: PhantomData, + }, + uarta: Uarta { + _marker: PhantomData, + }, + uartb: Uartb { + _marker: PhantomData, + }, + spia: Spia { + _marker: PhantomData, + }, + spib: Spib { + _marker: PhantomData, + }, + spic: Spic { + _marker: PhantomData, + }, + i2ca: I2ca { + _marker: PhantomData, + }, + i2cb: I2cb { + _marker: PhantomData, + }, + } + } +} diff --git a/va108xx/src/porta.rs b/va108xx/src/porta.rs new file mode 100644 index 0000000..a909f4b --- /dev/null +++ b/va108xx/src/porta.rs @@ -0,0 +1,439 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + _reserved_0_datain: [u8; 0x04], + _reserved_1_datainraw: [u8; 0x04], + _reserved_2_dataout: [u8; 0x04], + _reserved_3_dataoutraw: [u8; 0x04], + _reserved_4_setout: [u8; 0x04], + _reserved_5_clrout: [u8; 0x04], + _reserved_6_togout: [u8; 0x04], + _reserved_7_datamask: [u8; 0x04], + _reserved_8_dir: [u8; 0x04], + _reserved_9_pulse: [u8; 0x04], + _reserved_10_pulsebase: [u8; 0x04], + _reserved_11_delay: [u8; 0x04], + _reserved_12_delay: [u8; 0x04], + irq_sen: IrqSen, + irq_edge: IrqEdge, + irq_evt: IrqEvt, + irq_enb: IrqEnb, + irq_raw: IrqRaw, + irq_end: IrqEnd, + edge_status: EdgeStatus, + _reserved20: [u8; 0x0fac], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Data In Register by Byte"] + #[inline(always)] + pub const fn datainbyte(&self, n: usize) -> &Datainbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(0).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x00 - Data In Register by Byte"] + #[inline(always)] + pub fn datainbyte_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(0).add(1 * n).cast() }) + } + #[doc = "0x00 - Data In Register"] + #[inline(always)] + pub const fn datain(&self) -> &Datain { + unsafe { &*(self as *const Self).cast::().add(0).cast() } + } + #[doc = "0x04 - Data In Raw Register by Byte"] + #[inline(always)] + pub const fn datainrawbyte0(&self, n: usize) -> &Datainrawbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(4).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x04 - Data In Raw Register by Byte"] + #[inline(always)] + pub fn datainrawbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(4).add(1 * n).cast() }) + } + #[doc = "0x04 - Data In Raw Register"] + #[inline(always)] + pub const fn datainraw(&self) -> &Datainraw { + unsafe { &*(self as *const Self).cast::().add(4).cast() } + } + #[doc = "0x08 - Data Out Register by Byte"] + #[inline(always)] + pub const fn dataoutbyte(&self, n: usize) -> &Dataoutbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(8).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x08 - Data Out Register by Byte"] + #[inline(always)] + pub fn dataoutbyte_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(8).add(1 * n).cast() }) + } + #[doc = "0x08 - Data Out Register"] + #[inline(always)] + pub const fn dataout(&self) -> &Dataout { + unsafe { &*(self as *const Self).cast::().add(8).cast() } + } + #[doc = "0x0c - Data Out Register by Byte"] + #[inline(always)] + pub const fn dataoutrawbyte0(&self, n: usize) -> &Dataoutrawbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(12).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x0c - Data Out Register by Byte"] + #[inline(always)] + pub fn dataoutrawbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(12).add(1 * n).cast() }) + } + #[doc = "0x0c - Data Out Register"] + #[inline(always)] + pub const fn dataoutraw(&self) -> &Dataoutraw { + unsafe { &*(self as *const Self).cast::().add(12).cast() } + } + #[doc = "0x10 - Set Out Register by Byte"] + #[inline(always)] + pub const fn setoutbyte0(&self, n: usize) -> &Setoutbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(16).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x10 - Set Out Register by Byte"] + #[inline(always)] + pub fn setoutbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(16).add(1 * n).cast() }) + } + #[doc = "0x10 - Set Out Register"] + #[inline(always)] + pub const fn setout(&self) -> &Setout { + unsafe { &*(self as *const Self).cast::().add(16).cast() } + } + #[doc = "0x14 - Clear Out Register by Byte"] + #[inline(always)] + pub const fn clroutbyte0(&self, n: usize) -> &Clroutbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(20).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x14 - Clear Out Register by Byte"] + #[inline(always)] + pub fn clroutbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(20).add(1 * n).cast() }) + } + #[doc = "0x14 - Clear Out Register"] + #[inline(always)] + pub const fn clrout(&self) -> &Clrout { + unsafe { &*(self as *const Self).cast::().add(20).cast() } + } + #[doc = "0x18 - Toggle Out Register by Byte"] + #[inline(always)] + pub const fn togoutbyte0(&self, n: usize) -> &Togoutbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(24).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x18 - Toggle Out Register by Byte"] + #[inline(always)] + pub fn togoutbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(24).add(1 * n).cast() }) + } + #[doc = "0x18 - Toggle Out Register"] + #[inline(always)] + pub const fn togout(&self) -> &Togout { + unsafe { &*(self as *const Self).cast::().add(24).cast() } + } + #[doc = "0x1c - Data Out Register by Byte"] + #[inline(always)] + pub const fn datamaskbyte(&self, n: usize) -> &Datamaskbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(28).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x1c - Data Out Register by Byte"] + #[inline(always)] + pub fn datamaskbyte_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(28).add(1 * n).cast() }) + } + #[doc = "0x1c - Data mask Register"] + #[inline(always)] + pub const fn datamask(&self) -> &Datamask { + unsafe { &*(self as *const Self).cast::().add(28).cast() } + } + #[doc = "0x20 - Direction Register by Byte"] + #[inline(always)] + pub const fn dirbyte0(&self, n: usize) -> &Dirbyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(32).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x20 - Direction Register by Byte"] + #[inline(always)] + pub fn dirbyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(32).add(1 * n).cast() }) + } + #[doc = "0x20 - Direction Register (1:Output, 0:Input)"] + #[inline(always)] + pub const fn dir(&self) -> &Dir { + unsafe { &*(self as *const Self).cast::().add(32).cast() } + } + #[doc = "0x24 - Pulse Mode Register by Byte"] + #[inline(always)] + pub const fn pulsebyte0(&self, n: usize) -> &Pulsebyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(36).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x24 - Pulse Mode Register by Byte"] + #[inline(always)] + pub fn pulsebyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(36).add(1 * n).cast() }) + } + #[doc = "0x24 - Pulse Mode Register"] + #[inline(always)] + pub const fn pulse(&self) -> &Pulse { + unsafe { &*(self as *const Self).cast::().add(36).cast() } + } + #[doc = "0x28 - Pulse Base Mode Register by Byte"] + #[inline(always)] + pub const fn pulsebasebyte0(&self, n: usize) -> &Pulsebasebyte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(40).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x28 - Pulse Base Mode Register by Byte"] + #[inline(always)] + pub fn pulsebasebyte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(40).add(1 * n).cast() }) + } + #[doc = "0x28 - Pulse Base Value Register"] + #[inline(always)] + pub const fn pulsebase(&self) -> &Pulsebase { + unsafe { &*(self as *const Self).cast::().add(40).cast() } + } + #[doc = "0x2c - Delay1 Register by Byte"] + #[inline(always)] + pub const fn delay1byte0(&self, n: usize) -> &Delay1byte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(44).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x2c - Delay1 Register by Byte"] + #[inline(always)] + pub fn delay1byte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(44).add(1 * n).cast() }) + } + #[doc = "0x2c - Delay1 Register"] + #[inline(always)] + pub const fn delay1(&self) -> &Delay1 { + unsafe { &*(self as *const Self).cast::().add(44).cast() } + } + #[doc = "0x30 - Delay2 Register by Byte"] + #[inline(always)] + pub const fn delay2byte0(&self, n: usize) -> &Delay2byte { + #[allow(clippy::no_effect)] + [(); 4][n]; + unsafe { &*(self as *const Self).cast::().add(48).add(1 * n).cast() } + } + #[doc = "Iterator for array of:"] + #[doc = "0x30 - Delay2 Register by Byte"] + #[inline(always)] + pub fn delay2byte0_iter(&self) -> impl Iterator { + (0..4) + .map(move |n| unsafe { &*(self as *const Self).cast::().add(48).add(1 * n).cast() }) + } + #[doc = "0x30 - Delay2 Register"] + #[inline(always)] + pub const fn delay2(&self) -> &Delay2 { + unsafe { &*(self as *const Self).cast::().add(48).cast() } + } + #[doc = "0x34 - Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive)"] + #[inline(always)] + pub const fn irq_sen(&self) -> &IrqSen { + &self.irq_sen + } + #[doc = "0x38 - Interrupt Both Edge Register (1:Both Edges, 0:Single Edge)"] + #[inline(always)] + pub const fn irq_edge(&self) -> &IrqEdge { + &self.irq_edge + } + #[doc = "0x3c - Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge)"] + #[inline(always)] + pub const fn irq_evt(&self) -> &IrqEvt { + &self.irq_evt + } + #[doc = "0x40 - Interrupt Enable Register"] + #[inline(always)] + pub const fn irq_enb(&self) -> &IrqEnb { + &self.irq_enb + } + #[doc = "0x44 - Raw Interrupt Status"] + #[inline(always)] + pub const fn irq_raw(&self) -> &IrqRaw { + &self.irq_raw + } + #[doc = "0x48 - Masked Interrupt Status"] + #[inline(always)] + pub const fn irq_end(&self) -> &IrqEnd { + &self.irq_end + } + #[doc = "0x4c - Edge Status Register"] + #[inline(always)] + pub const fn edge_status(&self) -> &EdgeStatus { + &self.edge_status + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "DATAIN (r) register accessor: Data In Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datain::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@datain`] +module"] +#[doc(alias = "DATAIN")] +pub type Datain = crate::Reg; +#[doc = "Data In Register"] +pub mod datain; +#[doc = "DATAINBYTE (r) register accessor: Data In Register by Byte\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datainbyte::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@datainbyte`] +module"] +#[doc(alias = "DATAINBYTE")] +pub type Datainbyte = crate::Reg; +#[doc = "Data In Register by Byte"] +pub mod datainbyte; +pub use datain as datainraw; +pub use datainbyte as datainrawbyte; +pub use Datain as Datainraw; +pub use Datainbyte as Datainrawbyte; +#[doc = "DATAOUT (w) register accessor: Data Out Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`dataout::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@dataout`] +module"] +#[doc(alias = "DATAOUT")] +pub type Dataout = crate::Reg; +#[doc = "Data Out Register"] +pub mod dataout; +#[doc = "DATAOUTBYTE (w) register accessor: Data Out Register by Byte\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`dataoutbyte::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@dataoutbyte`] +module"] +#[doc(alias = "DATAOUTBYTE")] +pub type Dataoutbyte = crate::Reg; +#[doc = "Data Out Register by Byte"] +pub mod dataoutbyte; +pub use dataout as dataoutraw; +pub use dataout as setout; +pub use dataout as clrout; +pub use dataout as togout; +pub use dataoutbyte as dataoutrawbyte; +pub use dataoutbyte as setoutbyte; +pub use dataoutbyte as clroutbyte; +pub use dataoutbyte as togoutbyte; +pub use Dataout as Dataoutraw; +pub use Dataout as Setout; +pub use Dataout as Clrout; +pub use Dataout as Togout; +pub use Dataoutbyte as Dataoutrawbyte; +pub use Dataoutbyte as Setoutbyte; +pub use Dataoutbyte as Clroutbyte; +pub use Dataoutbyte as Togoutbyte; +#[doc = "DATAMASK (rw) register accessor: Data mask Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datamask::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`datamask::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@datamask`] +module"] +#[doc(alias = "DATAMASK")] +pub type Datamask = crate::Reg; +#[doc = "Data mask Register"] +pub mod datamask; +#[doc = "DATAMASKBYTE (rw) register accessor: Data Out Register by Byte\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datamaskbyte::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`datamaskbyte::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@datamaskbyte`] +module"] +#[doc(alias = "DATAMASKBYTE")] +pub type Datamaskbyte = crate::Reg; +#[doc = "Data Out Register by Byte"] +pub mod datamaskbyte; +pub use datamask as dir; +pub use datamask as pulse; +pub use datamask as pulsebase; +pub use datamask as delay1; +pub use datamask as delay2; +pub use datamaskbyte as dirbyte; +pub use datamaskbyte as pulsebyte; +pub use datamaskbyte as pulsebasebyte; +pub use datamaskbyte as delay1byte; +pub use datamaskbyte as delay2byte; +pub use Datamask as Dir; +pub use Datamask as Pulse; +pub use Datamask as Pulsebase; +pub use Datamask as Delay1; +pub use Datamask as Delay2; +pub use Datamaskbyte as Dirbyte; +pub use Datamaskbyte as Pulsebyte; +pub use Datamaskbyte as Pulsebasebyte; +pub use Datamaskbyte as Delay1byte; +pub use Datamaskbyte as Delay2byte; +#[doc = "IRQ_SEN (rw) register accessor: Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_sen::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_sen::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_sen`] +module"] +#[doc(alias = "IRQ_SEN")] +pub type IrqSen = crate::Reg; +#[doc = "Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive)"] +pub mod irq_sen; +#[doc = "IRQ_EDGE (rw) register accessor: Interrupt Both Edge Register (1:Both Edges, 0:Single Edge)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_edge::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_edge::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_edge`] +module"] +#[doc(alias = "IRQ_EDGE")] +pub type IrqEdge = crate::Reg; +#[doc = "Interrupt Both Edge Register (1:Both Edges, 0:Single Edge)"] +pub mod irq_edge; +#[doc = "IRQ_EVT (rw) register accessor: Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_evt::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_evt::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_evt`] +module"] +#[doc(alias = "IRQ_EVT")] +pub type IrqEvt = crate::Reg; +#[doc = "Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge)"] +pub mod irq_evt; +#[doc = "IRQ_ENB (rw) register accessor: Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_enb`] +module"] +#[doc(alias = "IRQ_ENB")] +pub type IrqEnb = crate::Reg; +#[doc = "Interrupt Enable Register"] +pub mod irq_enb; +#[doc = "IRQ_RAW (r) register accessor: Raw Interrupt Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_raw::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_raw`] +module"] +#[doc(alias = "IRQ_RAW")] +pub type IrqRaw = crate::Reg; +#[doc = "Raw Interrupt Status"] +pub mod irq_raw; +#[doc = "IRQ_END (r) register accessor: Masked Interrupt Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_end::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_end`] +module"] +#[doc(alias = "IRQ_END")] +pub type IrqEnd = crate::Reg; +#[doc = "Masked Interrupt Status"] +pub mod irq_end; +#[doc = "EDGE_STATUS (rw) register accessor: Edge Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`edge_status::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`edge_status::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@edge_status`] +module"] +#[doc(alias = "EDGE_STATUS")] +pub type EdgeStatus = crate::Reg; +#[doc = "Edge Status Register"] +pub mod edge_status; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/porta/datain.rs b/va108xx/src/porta/datain.rs new file mode 100644 index 0000000..5f6a720 --- /dev/null +++ b/va108xx/src/porta/datain.rs @@ -0,0 +1,18 @@ +#[doc = "Register `DATAIN` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Data In Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datain::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DatainSpec; +impl crate::RegisterSpec for DatainSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`datain::R`](R) reader structure"] +impl crate::Readable for DatainSpec {} +#[doc = "`reset()` method sets DATAIN to value 0"] +impl crate::Resettable for DatainSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/datainbyte.rs b/va108xx/src/porta/datainbyte.rs new file mode 100644 index 0000000..06d7f67 --- /dev/null +++ b/va108xx/src/porta/datainbyte.rs @@ -0,0 +1,19 @@ +#[doc = "Register `DATAINBYTE[%s]` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Data In Register by Byte\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datainbyte::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DatainbyteSpec; +impl crate::RegisterSpec for DatainbyteSpec { + type Ux = u8; +} +#[doc = "`read()` method returns [`datainbyte::R`](R) reader structure"] +impl crate::Readable for DatainbyteSpec {} +#[doc = "`reset()` method sets DATAINBYTE[%s] +to value 0"] +impl crate::Resettable for DatainbyteSpec { + const RESET_VALUE: u8 = 0; +} diff --git a/va108xx/src/porta/datamask.rs b/va108xx/src/porta/datamask.rs new file mode 100644 index 0000000..6df9aac --- /dev/null +++ b/va108xx/src/porta/datamask.rs @@ -0,0 +1,27 @@ +#[doc = "Register `DATAMASK` reader"] +pub type R = crate::R; +#[doc = "Register `DATAMASK` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Data mask Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datamask::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`datamask::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DatamaskSpec; +impl crate::RegisterSpec for DatamaskSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`datamask::R`](R) reader structure"] +impl crate::Readable for DatamaskSpec {} +#[doc = "`write(|w| ..)` method takes [`datamask::W`](W) writer structure"] +impl crate::Writable for DatamaskSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets DATAMASK to value 0"] +impl crate::Resettable for DatamaskSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/datamaskbyte.rs b/va108xx/src/porta/datamaskbyte.rs new file mode 100644 index 0000000..29ecd88 --- /dev/null +++ b/va108xx/src/porta/datamaskbyte.rs @@ -0,0 +1,28 @@ +#[doc = "Register `DATAMASKBYTE[%s]` reader"] +pub type R = crate::R; +#[doc = "Register `DATAMASKBYTE[%s]` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Data Out Register by Byte\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`datamaskbyte::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`datamaskbyte::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DatamaskbyteSpec; +impl crate::RegisterSpec for DatamaskbyteSpec { + type Ux = u8; +} +#[doc = "`read()` method returns [`datamaskbyte::R`](R) reader structure"] +impl crate::Readable for DatamaskbyteSpec {} +#[doc = "`write(|w| ..)` method takes [`datamaskbyte::W`](W) writer structure"] +impl crate::Writable for DatamaskbyteSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u8 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u8 = 0; +} +#[doc = "`reset()` method sets DATAMASKBYTE[%s] +to value 0"] +impl crate::Resettable for DatamaskbyteSpec { + const RESET_VALUE: u8 = 0; +} diff --git a/va108xx/src/porta/dataout.rs b/va108xx/src/porta/dataout.rs new file mode 100644 index 0000000..6250016 --- /dev/null +++ b/va108xx/src/porta/dataout.rs @@ -0,0 +1,23 @@ +#[doc = "Register `DATAOUT` writer"] +pub type W = crate::W; +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 = "Data Out Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`dataout::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DataoutSpec; +impl crate::RegisterSpec for DataoutSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`dataout::W`](W) writer structure"] +impl crate::Writable for DataoutSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets DATAOUT to value 0"] +impl crate::Resettable for DataoutSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/dataoutbyte.rs b/va108xx/src/porta/dataoutbyte.rs new file mode 100644 index 0000000..a712f13 --- /dev/null +++ b/va108xx/src/porta/dataoutbyte.rs @@ -0,0 +1,24 @@ +#[doc = "Register `DATAOUTBYTE[%s]` writer"] +pub type W = crate::W; +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 = "Data Out Register by Byte\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`dataoutbyte::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DataoutbyteSpec; +impl crate::RegisterSpec for DataoutbyteSpec { + type Ux = u8; +} +#[doc = "`write(|w| ..)` method takes [`dataoutbyte::W`](W) writer structure"] +impl crate::Writable for DataoutbyteSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u8 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u8 = 0; +} +#[doc = "`reset()` method sets DATAOUTBYTE[%s] +to value 0"] +impl crate::Resettable for DataoutbyteSpec { + const RESET_VALUE: u8 = 0; +} diff --git a/va108xx/src/porta/edge_status.rs b/va108xx/src/porta/edge_status.rs new file mode 100644 index 0000000..0a90d70 --- /dev/null +++ b/va108xx/src/porta/edge_status.rs @@ -0,0 +1,27 @@ +#[doc = "Register `EDGE_STATUS` reader"] +pub type R = crate::R; +#[doc = "Register `EDGE_STATUS` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Edge Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`edge_status::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`edge_status::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct EdgeStatusSpec; +impl crate::RegisterSpec for EdgeStatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`edge_status::R`](R) reader structure"] +impl crate::Readable for EdgeStatusSpec {} +#[doc = "`write(|w| ..)` method takes [`edge_status::W`](W) writer structure"] +impl crate::Writable for EdgeStatusSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets EDGE_STATUS to value 0"] +impl crate::Resettable for EdgeStatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_edge.rs b/va108xx/src/porta/irq_edge.rs new file mode 100644 index 0000000..fddfc1c --- /dev/null +++ b/va108xx/src/porta/irq_edge.rs @@ -0,0 +1,27 @@ +#[doc = "Register `IRQ_EDGE` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_EDGE` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Interrupt Both Edge Register (1:Both Edges, 0:Single Edge)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_edge::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_edge::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEdgeSpec; +impl crate::RegisterSpec for IrqEdgeSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_edge::R`](R) reader structure"] +impl crate::Readable for IrqEdgeSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_edge::W`](W) writer structure"] +impl crate::Writable for IrqEdgeSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_EDGE to value 0"] +impl crate::Resettable for IrqEdgeSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_enb.rs b/va108xx/src/porta/irq_enb.rs new file mode 100644 index 0000000..2696b81 --- /dev/null +++ b/va108xx/src/porta/irq_enb.rs @@ -0,0 +1,27 @@ +#[doc = "Register `IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_ENB` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEnbSpec; +impl crate::RegisterSpec for IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_enb::R`](R) reader structure"] +impl crate::Readable for IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_enb::W`](W) writer structure"] +impl crate::Writable for IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_ENB to value 0"] +impl crate::Resettable for IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_end.rs b/va108xx/src/porta/irq_end.rs new file mode 100644 index 0000000..cf88a8a --- /dev/null +++ b/va108xx/src/porta/irq_end.rs @@ -0,0 +1,18 @@ +#[doc = "Register `IRQ_END` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Masked Interrupt Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_end::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEndSpec; +impl crate::RegisterSpec for IrqEndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_end::R`](R) reader structure"] +impl crate::Readable for IrqEndSpec {} +#[doc = "`reset()` method sets IRQ_END to value 0"] +impl crate::Resettable for IrqEndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_evt.rs b/va108xx/src/porta/irq_evt.rs new file mode 100644 index 0000000..1e98fa4 --- /dev/null +++ b/va108xx/src/porta/irq_evt.rs @@ -0,0 +1,27 @@ +#[doc = "Register `IRQ_EVT` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_EVT` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_evt::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_evt::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEvtSpec; +impl crate::RegisterSpec for IrqEvtSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_evt::R`](R) reader structure"] +impl crate::Readable for IrqEvtSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_evt::W`](W) writer structure"] +impl crate::Writable for IrqEvtSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_EVT to value 0"] +impl crate::Resettable for IrqEvtSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_raw.rs b/va108xx/src/porta/irq_raw.rs new file mode 100644 index 0000000..0e153ef --- /dev/null +++ b/va108xx/src/porta/irq_raw.rs @@ -0,0 +1,18 @@ +#[doc = "Register `IRQ_RAW` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Raw Interrupt Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_raw::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqRawSpec; +impl crate::RegisterSpec for IrqRawSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_raw::R`](R) reader structure"] +impl crate::Readable for IrqRawSpec {} +#[doc = "`reset()` method sets IRQ_RAW to value 0"] +impl crate::Resettable for IrqRawSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/irq_sen.rs b/va108xx/src/porta/irq_sen.rs new file mode 100644 index 0000000..5b4c44a --- /dev/null +++ b/va108xx/src/porta/irq_sen.rs @@ -0,0 +1,27 @@ +#[doc = "Register `IRQ_SEN` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_SEN` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive)\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_sen::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_sen::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqSenSpec; +impl crate::RegisterSpec for IrqSenSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_sen::R`](R) reader structure"] +impl crate::Readable for IrqSenSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_sen::W`](W) writer structure"] +impl crate::Writable for IrqSenSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_SEN to value 0"] +impl crate::Resettable for IrqSenSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/porta/perid.rs b/va108xx/src/porta/perid.rs new file mode 100644 index 0000000..7c53b75 --- /dev/null +++ b/va108xx/src/porta/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0010_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0010_07e1; +} diff --git a/va108xx/src/spia.rs b/va108xx/src/spia.rs new file mode 100644 index 0000000..9b6a264 --- /dev/null +++ b/va108xx/src/spia.rs @@ -0,0 +1,163 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + ctrl0: Ctrl0, + ctrl1: Ctrl1, + data: Data, + status: Status, + clkprescale: Clkprescale, + irq_enb: IrqEnb, + irq_raw: IrqRaw, + irq_end: IrqEnd, + irq_clr: IrqClr, + rxfifoirqtrg: Rxfifoirqtrg, + txfifoirqtrg: Txfifoirqtrg, + fifo_clr: FifoClr, + state: State, + _reserved13: [u8; 0x0fc8], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Control Register 0"] + #[inline(always)] + pub const fn ctrl0(&self) -> &Ctrl0 { + &self.ctrl0 + } + #[doc = "0x04 - Control Register 1"] + #[inline(always)] + pub const fn ctrl1(&self) -> &Ctrl1 { + &self.ctrl1 + } + #[doc = "0x08 - Data Input/Output"] + #[inline(always)] + pub const fn data(&self) -> &Data { + &self.data + } + #[doc = "0x0c - Status Register"] + #[inline(always)] + pub const fn status(&self) -> &Status { + &self.status + } + #[doc = "0x10 - Clock Pre Scale divide value"] + #[inline(always)] + pub const fn clkprescale(&self) -> &Clkprescale { + &self.clkprescale + } + #[doc = "0x14 - Interrupt Enable Register"] + #[inline(always)] + pub const fn irq_enb(&self) -> &IrqEnb { + &self.irq_enb + } + #[doc = "0x18 - Raw Interrupt Status Register"] + #[inline(always)] + pub const fn irq_raw(&self) -> &IrqRaw { + &self.irq_raw + } + #[doc = "0x1c - Enabled Interrupt Status Register"] + #[inline(always)] + pub const fn irq_end(&self) -> &IrqEnd { + &self.irq_end + } + #[doc = "0x20 - Clear Interrupt Status Register"] + #[inline(always)] + pub const fn irq_clr(&self) -> &IrqClr { + &self.irq_clr + } + #[doc = "0x24 - Rx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn rxfifoirqtrg(&self) -> &Rxfifoirqtrg { + &self.rxfifoirqtrg + } + #[doc = "0x28 - Tx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn txfifoirqtrg(&self) -> &Txfifoirqtrg { + &self.txfifoirqtrg + } + #[doc = "0x2c - Clear FIFO Register"] + #[inline(always)] + pub const fn fifo_clr(&self) -> &FifoClr { + &self.fifo_clr + } + #[doc = "0x30 - Internal STATE of SPI Controller"] + #[inline(always)] + pub const fn state(&self) -> &State { + &self.state + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "CTRL0 (rw) register accessor: Control Register 0\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl0::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl0::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ctrl0`] +module"] +#[doc(alias = "CTRL0")] +pub type Ctrl0 = crate::Reg; +#[doc = "Control Register 0"] +pub mod ctrl0; +#[doc = "CTRL1 (rw) register accessor: Control Register 1\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl1::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl1::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ctrl1`] +module"] +#[doc(alias = "CTRL1")] +pub type Ctrl1 = crate::Reg; +#[doc = "Control Register 1"] +pub mod ctrl1; +#[doc = "DATA (rw) register accessor: Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@data`] +module"] +#[doc(alias = "DATA")] +pub type Data = crate::Reg; +#[doc = "Data Input/Output"] +pub mod data; +#[doc = "STATUS (r) register accessor: Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`status::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@status`] +module"] +#[doc(alias = "STATUS")] +pub type Status = crate::Reg; +#[doc = "Status Register"] +pub mod status; +#[doc = "CLKPRESCALE (rw) register accessor: Clock Pre Scale divide value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkprescale::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkprescale::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@clkprescale`] +module"] +#[doc(alias = "CLKPRESCALE")] +pub type Clkprescale = crate::Reg; +#[doc = "Clock Pre Scale divide value"] +pub mod clkprescale; +#[doc = "IRQ_ENB (rw) register accessor: Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_enb`] +module"] +#[doc(alias = "IRQ_ENB")] +pub type IrqEnb = crate::Reg; +#[doc = "Interrupt Enable Register"] +pub mod irq_enb; +pub use irq_enb as irq_raw; +pub use irq_enb as irq_end; +pub use irq_enb as irq_clr; +pub use IrqEnb as IrqRaw; +pub use IrqEnb as IrqEnd; +pub use IrqEnb as IrqClr; +#[doc = "RXFIFOIRQTRG (rw) register accessor: Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxfifoirqtrg`] +module"] +#[doc(alias = "RXFIFOIRQTRG")] +pub type Rxfifoirqtrg = crate::Reg; +#[doc = "Rx FIFO IRQ Trigger Level"] +pub mod rxfifoirqtrg; +#[doc = "TXFIFOIRQTRG (rw) register accessor: Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txfifoirqtrg`] +module"] +#[doc(alias = "TXFIFOIRQTRG")] +pub type Txfifoirqtrg = crate::Reg; +#[doc = "Tx FIFO IRQ Trigger Level"] +pub mod txfifoirqtrg; +#[doc = "FIFO_CLR (w) register accessor: Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@fifo_clr`] +module"] +#[doc(alias = "FIFO_CLR")] +pub type FifoClr = crate::Reg; +#[doc = "Clear FIFO Register"] +pub mod fifo_clr; +#[doc = "STATE (r) register accessor: Internal STATE of SPI Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@state`] +module"] +#[doc(alias = "STATE")] +pub type State = crate::Reg; +#[doc = "Internal STATE of SPI Controller"] +pub mod state; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/spia/clkprescale.rs b/va108xx/src/spia/clkprescale.rs new file mode 100644 index 0000000..ea5249f --- /dev/null +++ b/va108xx/src/spia/clkprescale.rs @@ -0,0 +1,27 @@ +#[doc = "Register `CLKPRESCALE` reader"] +pub type R = crate::R; +#[doc = "Register `CLKPRESCALE` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Clock Pre Scale divide value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkprescale::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkprescale::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ClkprescaleSpec; +impl crate::RegisterSpec for ClkprescaleSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`clkprescale::R`](R) reader structure"] +impl crate::Readable for ClkprescaleSpec {} +#[doc = "`write(|w| ..)` method takes [`clkprescale::W`](W) writer structure"] +impl crate::Writable for ClkprescaleSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CLKPRESCALE to value 0"] +impl crate::Resettable for ClkprescaleSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/ctrl0.rs b/va108xx/src/spia/ctrl0.rs new file mode 100644 index 0000000..4e41012 --- /dev/null +++ b/va108xx/src/spia/ctrl0.rs @@ -0,0 +1,85 @@ +#[doc = "Register `CTRL0` reader"] +pub type R = crate::R; +#[doc = "Register `CTRL0` writer"] +pub type W = crate::W; +#[doc = "Field `SIZE` reader - Data Size(0x3=>4, 0xf=>16)"] +pub type SizeR = crate::FieldReader; +#[doc = "Field `SIZE` writer - Data Size(0x3=>4, 0xf=>16)"] +pub type SizeW<'a, REG> = crate::FieldWriter<'a, REG, 4>; +#[doc = "Field `SPO` reader - SPI Clock Polarity"] +pub type SpoR = crate::BitReader; +#[doc = "Field `SPO` writer - SPI Clock Polarity"] +pub type SpoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPH` reader - SPI Clock Phase"] +pub type SphR = crate::BitReader; +#[doc = "Field `SPH` writer - SPI Clock Phase"] +pub type SphW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SCRDV` reader - Serial Clock Rate divide+1 value"] +pub type ScrdvR = crate::FieldReader; +#[doc = "Field `SCRDV` writer - Serial Clock Rate divide+1 value"] +pub type ScrdvW<'a, REG> = crate::FieldWriter<'a, REG, 8>; +impl R { + #[doc = "Bits 0:3 - Data Size(0x3=>4, 0xf=>16)"] + #[inline(always)] + pub fn size(&self) -> SizeR { + SizeR::new((self.bits & 0x0f) as u8) + } + #[doc = "Bit 6 - SPI Clock Polarity"] + #[inline(always)] + pub fn spo(&self) -> SpoR { + SpoR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - SPI Clock Phase"] + #[inline(always)] + pub fn sph(&self) -> SphR { + SphR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bits 8:15 - Serial Clock Rate divide+1 value"] + #[inline(always)] + pub fn scrdv(&self) -> ScrdvR { + ScrdvR::new(((self.bits >> 8) & 0xff) as u8) + } +} +impl W { + #[doc = "Bits 0:3 - Data Size(0x3=>4, 0xf=>16)"] + #[inline(always)] + #[must_use] + pub fn size(&mut self) -> SizeW { + SizeW::new(self, 0) + } + #[doc = "Bit 6 - SPI Clock Polarity"] + #[inline(always)] + #[must_use] + pub fn spo(&mut self) -> SpoW { + SpoW::new(self, 6) + } + #[doc = "Bit 7 - SPI Clock Phase"] + #[inline(always)] + #[must_use] + pub fn sph(&mut self) -> SphW { + SphW::new(self, 7) + } + #[doc = "Bits 8:15 - Serial Clock Rate divide+1 value"] + #[inline(always)] + #[must_use] + pub fn scrdv(&mut self) -> ScrdvW { + ScrdvW::new(self, 8) + } +} +#[doc = "Control Register 0\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl0::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl0::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct Ctrl0Spec; +impl crate::RegisterSpec for Ctrl0Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ctrl0::R`](R) reader structure"] +impl crate::Readable for Ctrl0Spec {} +#[doc = "`write(|w| ..)` method takes [`ctrl0::W`](W) writer structure"] +impl crate::Writable for Ctrl0Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CTRL0 to value 0"] +impl crate::Resettable for Ctrl0Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/ctrl1.rs b/va108xx/src/spia/ctrl1.rs new file mode 100644 index 0000000..45d9ec8 --- /dev/null +++ b/va108xx/src/spia/ctrl1.rs @@ -0,0 +1,175 @@ +#[doc = "Register `CTRL1` reader"] +pub type R = crate::R; +#[doc = "Register `CTRL1` writer"] +pub type W = crate::W; +#[doc = "Field `LBM` reader - Loop Back"] +pub type LbmR = crate::BitReader; +#[doc = "Field `LBM` writer - Loop Back"] +pub type LbmW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ENABLE` reader - Enable"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - Enable"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `MS` reader - Master/Slave (0:Master, 1:Slave)"] +pub type MsR = crate::BitReader; +#[doc = "Field `MS` writer - Master/Slave (0:Master, 1:Slave)"] +pub type MsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SOD` reader - Slave output Disable"] +pub type SodR = crate::BitReader; +#[doc = "Field `SOD` writer - Slave output Disable"] +pub type SodW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SS` reader - Slave Select"] +pub type SsR = crate::FieldReader; +#[doc = "Field `SS` writer - Slave Select"] +pub type SsW<'a, REG> = crate::FieldWriter<'a, REG, 3>; +#[doc = "Field `BLOCKMODE` reader - Block Mode Enable"] +pub type BlockmodeR = crate::BitReader; +#[doc = "Field `BLOCKMODE` writer - Block Mode Enable"] +pub type BlockmodeW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `BMSTART` reader - Block Mode Start Status Enable"] +pub type BmstartR = crate::BitReader; +#[doc = "Field `BMSTART` writer - Block Mode Start Status Enable"] +pub type BmstartW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `BMSTALL` reader - Block Mode Stall Enable"] +pub type BmstallR = crate::BitReader; +#[doc = "Field `BMSTALL` writer - Block Mode Stall Enable"] +pub type BmstallW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `MDLYCAP` reader - Master Delayed Capture Enable"] +pub type MdlycapR = crate::BitReader; +#[doc = "Field `MDLYCAP` writer - Master Delayed Capture Enable"] +pub type MdlycapW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `MTXPAUSE` reader - Master Tx Pause Enable"] +pub type MtxpauseR = crate::BitReader; +#[doc = "Field `MTXPAUSE` writer - Master Tx Pause Enable"] +pub type MtxpauseW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Loop Back"] + #[inline(always)] + pub fn lbm(&self) -> LbmR { + LbmR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Enable"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Master/Slave (0:Master, 1:Slave)"] + #[inline(always)] + pub fn ms(&self) -> MsR { + MsR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Slave output Disable"] + #[inline(always)] + pub fn sod(&self) -> SodR { + SodR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bits 4:6 - Slave Select"] + #[inline(always)] + pub fn ss(&self) -> SsR { + SsR::new(((self.bits >> 4) & 7) as u8) + } + #[doc = "Bit 7 - Block Mode Enable"] + #[inline(always)] + pub fn blockmode(&self) -> BlockmodeR { + BlockmodeR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - Block Mode Start Status Enable"] + #[inline(always)] + pub fn bmstart(&self) -> BmstartR { + BmstartR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Block Mode Stall Enable"] + #[inline(always)] + pub fn bmstall(&self) -> BmstallR { + BmstallR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - Master Delayed Capture Enable"] + #[inline(always)] + pub fn mdlycap(&self) -> MdlycapR { + MdlycapR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - Master Tx Pause Enable"] + #[inline(always)] + pub fn mtxpause(&self) -> MtxpauseR { + MtxpauseR::new(((self.bits >> 11) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Loop Back"] + #[inline(always)] + #[must_use] + pub fn lbm(&mut self) -> LbmW { + LbmW::new(self, 0) + } + #[doc = "Bit 1 - Enable"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 1) + } + #[doc = "Bit 2 - Master/Slave (0:Master, 1:Slave)"] + #[inline(always)] + #[must_use] + pub fn ms(&mut self) -> MsW { + MsW::new(self, 2) + } + #[doc = "Bit 3 - Slave output Disable"] + #[inline(always)] + #[must_use] + pub fn sod(&mut self) -> SodW { + SodW::new(self, 3) + } + #[doc = "Bits 4:6 - Slave Select"] + #[inline(always)] + #[must_use] + pub fn ss(&mut self) -> SsW { + SsW::new(self, 4) + } + #[doc = "Bit 7 - Block Mode Enable"] + #[inline(always)] + #[must_use] + pub fn blockmode(&mut self) -> BlockmodeW { + BlockmodeW::new(self, 7) + } + #[doc = "Bit 8 - Block Mode Start Status Enable"] + #[inline(always)] + #[must_use] + pub fn bmstart(&mut self) -> BmstartW { + BmstartW::new(self, 8) + } + #[doc = "Bit 9 - Block Mode Stall Enable"] + #[inline(always)] + #[must_use] + pub fn bmstall(&mut self) -> BmstallW { + BmstallW::new(self, 9) + } + #[doc = "Bit 10 - Master Delayed Capture Enable"] + #[inline(always)] + #[must_use] + pub fn mdlycap(&mut self) -> MdlycapW { + MdlycapW::new(self, 10) + } + #[doc = "Bit 11 - Master Tx Pause Enable"] + #[inline(always)] + #[must_use] + pub fn mtxpause(&mut self) -> MtxpauseW { + MtxpauseW::new(self, 11) + } +} +#[doc = "Control Register 1\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl1::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl1::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct Ctrl1Spec; +impl crate::RegisterSpec for Ctrl1Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ctrl1::R`](R) reader structure"] +impl crate::Readable for Ctrl1Spec {} +#[doc = "`write(|w| ..)` method takes [`ctrl1::W`](W) writer structure"] +impl crate::Writable for Ctrl1Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CTRL1 to value 0"] +impl crate::Resettable for Ctrl1Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/data.rs b/va108xx/src/spia/data.rs new file mode 100644 index 0000000..30b85c9 --- /dev/null +++ b/va108xx/src/spia/data.rs @@ -0,0 +1,27 @@ +#[doc = "Register `DATA` reader"] +pub type R = crate::R; +#[doc = "Register `DATA` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Data Input/Output\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DataSpec; +impl crate::RegisterSpec for DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`data::R`](R) reader structure"] +impl crate::Readable for DataSpec {} +#[doc = "`write(|w| ..)` method takes [`data::W`](W) writer structure"] +impl crate::Writable for DataSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets DATA to value 0"] +impl crate::Resettable for DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/fifo_clr.rs b/va108xx/src/spia/fifo_clr.rs new file mode 100644 index 0000000..156da87 --- /dev/null +++ b/va108xx/src/spia/fifo_clr.rs @@ -0,0 +1,35 @@ +#[doc = "Register `FIFO_CLR` writer"] +pub type W = crate::W; +#[doc = "Field `RXFIFO` writer - Clear Rx FIFO"] +pub type RxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFIFO` writer - Clear Tx FIFO"] +pub type TxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +impl W { + #[doc = "Bit 0 - Clear Rx FIFO"] + #[inline(always)] + #[must_use] + pub fn rxfifo(&mut self) -> RxfifoW { + RxfifoW::new(self, 0) + } + #[doc = "Bit 1 - Clear Tx FIFO"] + #[inline(always)] + #[must_use] + pub fn txfifo(&mut self) -> TxfifoW { + TxfifoW::new(self, 1) + } +} +#[doc = "Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct FifoClrSpec; +impl crate::RegisterSpec for FifoClrSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`fifo_clr::W`](W) writer structure"] +impl crate::Writable for FifoClrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets FIFO_CLR to value 0"] +impl crate::Resettable for FifoClrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/irq_enb.rs b/va108xx/src/spia/irq_enb.rs new file mode 100644 index 0000000..68d93bc --- /dev/null +++ b/va108xx/src/spia/irq_enb.rs @@ -0,0 +1,85 @@ +#[doc = "Register `IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_ENB` writer"] +pub type W = crate::W; +#[doc = "Field `RORIM` reader - RX Overrun"] +pub type RorimR = crate::BitReader; +#[doc = "Field `RORIM` writer - RX Overrun"] +pub type RorimW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RTIM` reader - RX Timeout"] +pub type RtimR = crate::BitReader; +#[doc = "Field `RTIM` writer - RX Timeout"] +pub type RtimW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXIM` reader - RX Fifo is at least half full"] +pub type RximR = crate::BitReader; +#[doc = "Field `RXIM` writer - RX Fifo is at least half full"] +pub type RximW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXIM` reader - TX Fifo is at least half empty"] +pub type TximR = crate::BitReader; +#[doc = "Field `TXIM` writer - TX Fifo is at least half empty"] +pub type TximW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - RX Overrun"] + #[inline(always)] + pub fn rorim(&self) -> RorimR { + RorimR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - RX Timeout"] + #[inline(always)] + pub fn rtim(&self) -> RtimR { + RtimR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - RX Fifo is at least half full"] + #[inline(always)] + pub fn rxim(&self) -> RximR { + RximR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - TX Fifo is at least half empty"] + #[inline(always)] + pub fn txim(&self) -> TximR { + TximR::new(((self.bits >> 3) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - RX Overrun"] + #[inline(always)] + #[must_use] + pub fn rorim(&mut self) -> RorimW { + RorimW::new(self, 0) + } + #[doc = "Bit 1 - RX Timeout"] + #[inline(always)] + #[must_use] + pub fn rtim(&mut self) -> RtimW { + RtimW::new(self, 1) + } + #[doc = "Bit 2 - RX Fifo is at least half full"] + #[inline(always)] + #[must_use] + pub fn rxim(&mut self) -> RximW { + RximW::new(self, 2) + } + #[doc = "Bit 3 - TX Fifo is at least half empty"] + #[inline(always)] + #[must_use] + pub fn txim(&mut self) -> TximW { + TximW::new(self, 3) + } +} +#[doc = "Interrupt Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEnbSpec; +impl crate::RegisterSpec for IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_enb::R`](R) reader structure"] +impl crate::Readable for IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_enb::W`](W) writer structure"] +impl crate::Writable for IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_ENB to value 0"] +impl crate::Resettable for IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/perid.rs b/va108xx/src/spia/perid.rs new file mode 100644 index 0000000..fe8dddc --- /dev/null +++ b/va108xx/src/spia/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0012_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0012_07e1; +} diff --git a/va108xx/src/spia/rxfifoirqtrg.rs b/va108xx/src/spia/rxfifoirqtrg.rs new file mode 100644 index 0000000..46124d5 --- /dev/null +++ b/va108xx/src/spia/rxfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `RXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxfifoirqtrgSpec; +impl crate::RegisterSpec for RxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for RxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`rxfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for RxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RXFIFOIRQTRG to value 0"] +impl crate::Resettable for RxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/state.rs b/va108xx/src/spia/state.rs new file mode 100644 index 0000000..aaa69d0 --- /dev/null +++ b/va108xx/src/spia/state.rs @@ -0,0 +1,18 @@ +#[doc = "Register `STATE` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Internal STATE of SPI Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct StateSpec; +impl crate::RegisterSpec for StateSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`state::R`](R) reader structure"] +impl crate::Readable for StateSpec {} +#[doc = "`reset()` method sets STATE to value 0"] +impl crate::Resettable for StateSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/status.rs b/va108xx/src/spia/status.rs new file mode 100644 index 0000000..d076d06 --- /dev/null +++ b/va108xx/src/spia/status.rs @@ -0,0 +1,71 @@ +#[doc = "Register `STATUS` reader"] +pub type R = crate::R; +#[doc = "Field `TFE` reader - Transmit FIFO empty"] +pub type TfeR = crate::BitReader; +#[doc = "Field `TNF` reader - Transmit FIFO not full"] +pub type TnfR = crate::BitReader; +#[doc = "Field `RNE` reader - Receive FIFO not empty"] +pub type RneR = crate::BitReader; +#[doc = "Field `RFF` reader - Receive FIFO Full"] +pub type RffR = crate::BitReader; +#[doc = "Field `BUSY` reader - Busy"] +pub type BusyR = crate::BitReader; +#[doc = "Field `RXDATAFIRST` reader - Pending Data is first Byte in BLOCKMODE"] +pub type RxdatafirstR = crate::BitReader; +#[doc = "Field `RXTRIGGER` reader - RX FIFO Above Trigger Level"] +pub type RxtriggerR = crate::BitReader; +#[doc = "Field `TXTRIGGER` reader - TX FIFO Below Trigger Level"] +pub type TxtriggerR = crate::BitReader; +impl R { + #[doc = "Bit 0 - Transmit FIFO empty"] + #[inline(always)] + pub fn tfe(&self) -> TfeR { + TfeR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Transmit FIFO not full"] + #[inline(always)] + pub fn tnf(&self) -> TnfR { + TnfR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Receive FIFO not empty"] + #[inline(always)] + pub fn rne(&self) -> RneR { + RneR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Receive FIFO Full"] + #[inline(always)] + pub fn rff(&self) -> RffR { + RffR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Busy"] + #[inline(always)] + pub fn busy(&self) -> BusyR { + BusyR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - Pending Data is first Byte in BLOCKMODE"] + #[inline(always)] + pub fn rxdatafirst(&self) -> RxdatafirstR { + RxdatafirstR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - RX FIFO Above Trigger Level"] + #[inline(always)] + pub fn rxtrigger(&self) -> RxtriggerR { + RxtriggerR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - TX FIFO Below Trigger Level"] + #[inline(always)] + pub fn txtrigger(&self) -> TxtriggerR { + TxtriggerR::new(((self.bits >> 7) & 1) != 0) + } +} +#[doc = "Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`status::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct StatusSpec; +impl crate::RegisterSpec for StatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`status::R`](R) reader structure"] +impl crate::Readable for StatusSpec {} +#[doc = "`reset()` method sets STATUS to value 0"] +impl crate::Resettable for StatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/spia/txfifoirqtrg.rs b/va108xx/src/spia/txfifoirqtrg.rs new file mode 100644 index 0000000..0d13e54 --- /dev/null +++ b/va108xx/src/spia/txfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `TXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxfifoirqtrgSpec; +impl crate::RegisterSpec for TxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`txfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for TxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`txfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for TxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TXFIFOIRQTRG to value 0"] +impl crate::Resettable for TxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig.rs b/va108xx/src/sysconfig.rs new file mode 100644 index 0000000..482b2e4 --- /dev/null +++ b/va108xx/src/sysconfig.rs @@ -0,0 +1,376 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + rst_stat: RstStat, + rst_cntl_rom: RstCntlRom, + rst_cntl_ram: RstCntlRam, + rom_prot: RomProt, + rom_scrub: RomScrub, + ram_scrub: RamScrub, + rom_trap_addr: RomTrapAddr, + rom_trap_synd: RomTrapSynd, + ram_trap_addr: RamTrapAddr, + ram_trap_synd: RamTrapSynd, + irq_enb: IrqEnb, + irq_raw: IrqRaw, + irq_end: IrqEnd, + irq_clr: IrqClr, + ram_sbe: RamSbe, + ram_mbe: RamMbe, + rom_sbe: RomSbe, + rom_mbe: RomMbe, + ioconfig_clkdiv0: IoconfigClkdiv0, + ioconfig_clkdiv: [IoconfigClkdiv; 7], + rom_retries: RomRetries, + refresh_config: RefreshConfig, + tim_reset: TimReset, + tim_clk_enable: TimClkEnable, + peripheral_reset: PeripheralReset, + peripheral_clk_enable: PeripheralClkEnable, + lockup_reset: LockupReset, + _reserved27: [u8; 0x0f6c], + ef_config: EfConfig, + ef_id: EfId, + procid: Procid, + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - System Reset Status"] + #[inline(always)] + pub const fn rst_stat(&self) -> &RstStat { + &self.rst_stat + } + #[doc = "0x04 - ROM Reset Control"] + #[inline(always)] + pub const fn rst_cntl_rom(&self) -> &RstCntlRom { + &self.rst_cntl_rom + } + #[doc = "0x08 - RAM Reset Control"] + #[inline(always)] + pub const fn rst_cntl_ram(&self) -> &RstCntlRam { + &self.rst_cntl_ram + } + #[doc = "0x0c - ROM Protection Configuration"] + #[inline(always)] + pub const fn rom_prot(&self) -> &RomProt { + &self.rom_prot + } + #[doc = "0x10 - ROM Scrub Period Configuration"] + #[inline(always)] + pub const fn rom_scrub(&self) -> &RomScrub { + &self.rom_scrub + } + #[doc = "0x14 - RAM Scrub Period Configuration"] + #[inline(always)] + pub const fn ram_scrub(&self) -> &RamScrub { + &self.ram_scrub + } + #[doc = "0x18 - ROM Trap Address"] + #[inline(always)] + pub const fn rom_trap_addr(&self) -> &RomTrapAddr { + &self.rom_trap_addr + } + #[doc = "0x1c - ROM Trap Syndrome"] + #[inline(always)] + pub const fn rom_trap_synd(&self) -> &RomTrapSynd { + &self.rom_trap_synd + } + #[doc = "0x20 - RAM Trap Address"] + #[inline(always)] + pub const fn ram_trap_addr(&self) -> &RamTrapAddr { + &self.ram_trap_addr + } + #[doc = "0x24 - RAM Trap Syndrome"] + #[inline(always)] + pub const fn ram_trap_synd(&self) -> &RamTrapSynd { + &self.ram_trap_synd + } + #[doc = "0x28 - Enable EDAC Error Interrupt Register"] + #[inline(always)] + pub const fn irq_enb(&self) -> &IrqEnb { + &self.irq_enb + } + #[doc = "0x2c - Raw EDAC Error Interrupt Status"] + #[inline(always)] + pub const fn irq_raw(&self) -> &IrqRaw { + &self.irq_raw + } + #[doc = "0x30 - Enabled EDAC Error Interrupt Status"] + #[inline(always)] + pub const fn irq_end(&self) -> &IrqEnd { + &self.irq_end + } + #[doc = "0x34 - Clear EDAC Error Interrupt Status"] + #[inline(always)] + pub const fn irq_clr(&self) -> &IrqClr { + &self.irq_clr + } + #[doc = "0x38 - Count of RAM EDAC Single Bit Errors"] + #[inline(always)] + pub const fn ram_sbe(&self) -> &RamSbe { + &self.ram_sbe + } + #[doc = "0x3c - Count of RAM EDAC Multi Bit Errors"] + #[inline(always)] + pub const fn ram_mbe(&self) -> &RamMbe { + &self.ram_mbe + } + #[doc = "0x40 - Count of ROM EDAC Single Bit Errors"] + #[inline(always)] + pub const fn rom_sbe(&self) -> &RomSbe { + &self.rom_sbe + } + #[doc = "0x44 - Count of ROM EDAC Multi Bit Errors"] + #[inline(always)] + pub const fn rom_mbe(&self) -> &RomMbe { + &self.rom_mbe + } + #[doc = "0x48 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv0(&self) -> &IoconfigClkdiv0 { + &self.ioconfig_clkdiv0 + } + #[doc = "0x4c..0x68 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv(&self, n: usize) -> &IoconfigClkdiv { + &self.ioconfig_clkdiv[n] + } + #[doc = "Iterator for array of:"] + #[doc = "0x4c..0x68 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub fn ioconfig_clkdiv_iter(&self) -> impl Iterator { + self.ioconfig_clkdiv.iter() + } + #[doc = "0x4c - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv1(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(0) + } + #[doc = "0x50 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv2(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(1) + } + #[doc = "0x54 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv3(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(2) + } + #[doc = "0x58 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv4(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(3) + } + #[doc = "0x5c - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv5(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(4) + } + #[doc = "0x60 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv6(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(5) + } + #[doc = "0x64 - IO Configuration Clock Divider Register"] + #[inline(always)] + pub const fn ioconfig_clkdiv7(&self) -> &IoconfigClkdiv { + self.ioconfig_clkdiv(6) + } + #[doc = "0x68 - ROM BOOT Retry count"] + #[inline(always)] + pub const fn rom_retries(&self) -> &RomRetries { + &self.rom_retries + } + #[doc = "0x6c - Register Refresh Control"] + #[inline(always)] + pub const fn refresh_config(&self) -> &RefreshConfig { + &self.refresh_config + } + #[doc = "0x70 - TIM Reset Control"] + #[inline(always)] + pub const fn tim_reset(&self) -> &TimReset { + &self.tim_reset + } + #[doc = "0x74 - TIM Enable Control"] + #[inline(always)] + pub const fn tim_clk_enable(&self) -> &TimClkEnable { + &self.tim_clk_enable + } + #[doc = "0x78 - Peripheral Reset Control"] + #[inline(always)] + pub const fn peripheral_reset(&self) -> &PeripheralReset { + &self.peripheral_reset + } + #[doc = "0x7c - Peripheral Enable Control"] + #[inline(always)] + pub const fn peripheral_clk_enable(&self) -> &PeripheralClkEnable { + &self.peripheral_clk_enable + } + #[doc = "0x80 - Lockup Reset Configuration"] + #[inline(always)] + pub const fn lockup_reset(&self) -> &LockupReset { + &self.lockup_reset + } + #[doc = "0xff0 - EFuse Config Register"] + #[inline(always)] + pub const fn ef_config(&self) -> &EfConfig { + &self.ef_config + } + #[doc = "0xff4 - EFuse ID Register"] + #[inline(always)] + pub const fn ef_id(&self) -> &EfId { + &self.ef_id + } + #[doc = "0xff8 - Processor ID Register"] + #[inline(always)] + pub const fn procid(&self) -> &Procid { + &self.procid + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "RST_STAT (rw) register accessor: System Reset Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rst_stat::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rst_stat::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rst_stat`] +module"] +#[doc(alias = "RST_STAT")] +pub type RstStat = crate::Reg; +#[doc = "System Reset Status"] +pub mod rst_stat; +pub use rst_stat as rst_cntl_rom; +pub use rst_stat as rst_cntl_ram; +pub use RstStat as RstCntlRom; +pub use RstStat as RstCntlRam; +#[doc = "ROM_PROT (rw) register accessor: ROM Protection Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_prot::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_prot::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rom_prot`] +module"] +#[doc(alias = "ROM_PROT")] +pub type RomProt = crate::Reg; +#[doc = "ROM Protection Configuration"] +pub mod rom_prot; +#[doc = "ROM_SCRUB (rw) register accessor: ROM Scrub Period Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_scrub::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_scrub::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rom_scrub`] +module"] +#[doc(alias = "ROM_SCRUB")] +pub type RomScrub = crate::Reg; +#[doc = "ROM Scrub Period Configuration"] +pub mod rom_scrub; +pub use rom_scrub as ram_scrub; +pub use RomScrub as RamScrub; +#[doc = "ROM_TRAP_ADDR (rw) register accessor: ROM Trap Address\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_trap_addr::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_trap_addr::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rom_trap_addr`] +module"] +#[doc(alias = "ROM_TRAP_ADDR")] +pub type RomTrapAddr = crate::Reg; +#[doc = "ROM Trap Address"] +pub mod rom_trap_addr; +#[doc = "ROM_TRAP_SYND (rw) register accessor: ROM Trap Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_trap_synd::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_trap_synd::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rom_trap_synd`] +module"] +#[doc(alias = "ROM_TRAP_SYND")] +pub type RomTrapSynd = crate::Reg; +#[doc = "ROM Trap Syndrome"] +pub mod rom_trap_synd; +pub use rom_trap_addr as ram_trap_addr; +pub use rom_trap_synd as ram_trap_synd; +pub use RomTrapAddr as RamTrapAddr; +pub use RomTrapSynd as RamTrapSynd; +#[doc = "IRQ_ENB (rw) register accessor: Enable EDAC Error Interrupt Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_enb`] +module"] +#[doc(alias = "IRQ_ENB")] +pub type IrqEnb = crate::Reg; +#[doc = "Enable EDAC Error Interrupt Register"] +pub mod irq_enb; +pub use irq_enb as irq_raw; +pub use irq_enb as irq_end; +pub use irq_enb as irq_clr; +pub use IrqEnb as IrqRaw; +pub use IrqEnb as IrqEnd; +pub use IrqEnb as IrqClr; +#[doc = "RAM_SBE (rw) register accessor: Count of RAM EDAC Single Bit Errors\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ram_sbe::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ram_sbe::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ram_sbe`] +module"] +#[doc(alias = "RAM_SBE")] +pub type RamSbe = crate::Reg; +#[doc = "Count of RAM EDAC Single Bit Errors"] +pub mod ram_sbe; +pub use ram_sbe as ram_mbe; +pub use ram_sbe as rom_sbe; +pub use ram_sbe as rom_mbe; +pub use RamSbe as RamMbe; +pub use RamSbe as RomSbe; +pub use RamSbe as RomMbe; +#[doc = "IOCONFIG_CLKDIV0 (r) register accessor: IO Configuration Clock Divider Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ioconfig_clkdiv0::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ioconfig_clkdiv0`] +module"] +#[doc(alias = "IOCONFIG_CLKDIV0")] +pub type IoconfigClkdiv0 = crate::Reg; +#[doc = "IO Configuration Clock Divider Register"] +pub mod ioconfig_clkdiv0; +#[doc = "IOCONFIG_CLKDIV (rw) register accessor: IO Configuration Clock Divider Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ioconfig_clkdiv::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ioconfig_clkdiv::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ioconfig_clkdiv`] +module"] +#[doc(alias = "IOCONFIG_CLKDIV")] +pub type IoconfigClkdiv = crate::Reg; +#[doc = "IO Configuration Clock Divider Register"] +pub mod ioconfig_clkdiv; +#[doc = "ROM_RETRIES (r) register accessor: ROM BOOT Retry count\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_retries::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rom_retries`] +module"] +#[doc(alias = "ROM_RETRIES")] +pub type RomRetries = crate::Reg; +#[doc = "ROM BOOT Retry count"] +pub mod rom_retries; +#[doc = "REFRESH_CONFIG (rw) register accessor: Register Refresh Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`refresh_config::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`refresh_config::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@refresh_config`] +module"] +#[doc(alias = "REFRESH_CONFIG")] +pub type RefreshConfig = crate::Reg; +#[doc = "Register Refresh Control"] +pub mod refresh_config; +#[doc = "TIM_RESET (rw) register accessor: TIM Reset Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tim_reset::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tim_reset::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@tim_reset`] +module"] +#[doc(alias = "TIM_RESET")] +pub type TimReset = crate::Reg; +#[doc = "TIM Reset Control"] +pub mod tim_reset; +#[doc = "TIM_CLK_ENABLE (rw) register accessor: TIM Enable Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tim_clk_enable::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tim_clk_enable::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@tim_clk_enable`] +module"] +#[doc(alias = "TIM_CLK_ENABLE")] +pub type TimClkEnable = crate::Reg; +#[doc = "TIM Enable Control"] +pub mod tim_clk_enable; +#[doc = "PERIPHERAL_RESET (rw) register accessor: Peripheral Reset Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`peripheral_reset::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`peripheral_reset::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@peripheral_reset`] +module"] +#[doc(alias = "PERIPHERAL_RESET")] +pub type PeripheralReset = crate::Reg; +#[doc = "Peripheral Reset Control"] +pub mod peripheral_reset; +#[doc = "PERIPHERAL_CLK_ENABLE (rw) register accessor: Peripheral Enable Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`peripheral_clk_enable::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`peripheral_clk_enable::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@peripheral_clk_enable`] +module"] +#[doc(alias = "PERIPHERAL_CLK_ENABLE")] +pub type PeripheralClkEnable = crate::Reg; +#[doc = "Peripheral Enable Control"] +pub mod peripheral_clk_enable; +#[doc = "LOCKUP_RESET (rw) register accessor: Lockup Reset Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`lockup_reset::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`lockup_reset::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@lockup_reset`] +module"] +#[doc(alias = "LOCKUP_RESET")] +pub type LockupReset = crate::Reg; +#[doc = "Lockup Reset Configuration"] +pub mod lockup_reset; +#[doc = "EF_CONFIG (r) register accessor: EFuse Config Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ef_config::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ef_config`] +module"] +#[doc(alias = "EF_CONFIG")] +pub type EfConfig = crate::Reg; +#[doc = "EFuse Config Register"] +pub mod ef_config; +#[doc = "EF_ID (r) register accessor: EFuse ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ef_id::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ef_id`] +module"] +#[doc(alias = "EF_ID")] +pub type EfId = crate::Reg; +#[doc = "EFuse ID Register"] +pub mod ef_id; +#[doc = "PROCID (r) register accessor: Processor ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`procid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@procid`] +module"] +#[doc(alias = "PROCID")] +pub type Procid = crate::Reg; +#[doc = "Processor ID Register"] +pub mod procid; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/sysconfig/ef_config.rs b/va108xx/src/sysconfig/ef_config.rs new file mode 100644 index 0000000..f553fbf --- /dev/null +++ b/va108xx/src/sysconfig/ef_config.rs @@ -0,0 +1,18 @@ +#[doc = "Register `EF_CONFIG` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "EFuse Config Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ef_config::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct EfConfigSpec; +impl crate::RegisterSpec for EfConfigSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ef_config::R`](R) reader structure"] +impl crate::Readable for EfConfigSpec {} +#[doc = "`reset()` method sets EF_CONFIG to value 0"] +impl crate::Resettable for EfConfigSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/ef_id.rs b/va108xx/src/sysconfig/ef_id.rs new file mode 100644 index 0000000..a7a8ccb --- /dev/null +++ b/va108xx/src/sysconfig/ef_id.rs @@ -0,0 +1,18 @@ +#[doc = "Register `EF_ID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "EFuse ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ef_id::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct EfIdSpec; +impl crate::RegisterSpec for EfIdSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ef_id::R`](R) reader structure"] +impl crate::Readable for EfIdSpec {} +#[doc = "`reset()` method sets EF_ID to value 0"] +impl crate::Resettable for EfIdSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/ioconfig_clkdiv.rs b/va108xx/src/sysconfig/ioconfig_clkdiv.rs new file mode 100644 index 0000000..9615226 --- /dev/null +++ b/va108xx/src/sysconfig/ioconfig_clkdiv.rs @@ -0,0 +1,27 @@ +#[doc = "Register `IOCONFIG_CLKDIV%s` reader"] +pub type R = crate::R; +#[doc = "Register `IOCONFIG_CLKDIV%s` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "IO Configuration Clock Divider Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ioconfig_clkdiv::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ioconfig_clkdiv::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IoconfigClkdivSpec; +impl crate::RegisterSpec for IoconfigClkdivSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ioconfig_clkdiv::R`](R) reader structure"] +impl crate::Readable for IoconfigClkdivSpec {} +#[doc = "`write(|w| ..)` method takes [`ioconfig_clkdiv::W`](W) writer structure"] +impl crate::Writable for IoconfigClkdivSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IOCONFIG_CLKDIV%s to value 0"] +impl crate::Resettable for IoconfigClkdivSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/ioconfig_clkdiv0.rs b/va108xx/src/sysconfig/ioconfig_clkdiv0.rs new file mode 100644 index 0000000..f510375 --- /dev/null +++ b/va108xx/src/sysconfig/ioconfig_clkdiv0.rs @@ -0,0 +1,18 @@ +#[doc = "Register `IOCONFIG_CLKDIV0` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "IO Configuration Clock Divider Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ioconfig_clkdiv0::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IoconfigClkdiv0Spec; +impl crate::RegisterSpec for IoconfigClkdiv0Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ioconfig_clkdiv0::R`](R) reader structure"] +impl crate::Readable for IoconfigClkdiv0Spec {} +#[doc = "`reset()` method sets IOCONFIG_CLKDIV0 to value 0"] +impl crate::Resettable for IoconfigClkdiv0Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/irq_enb.rs b/va108xx/src/sysconfig/irq_enb.rs new file mode 100644 index 0000000..bbcd84f --- /dev/null +++ b/va108xx/src/sysconfig/irq_enb.rs @@ -0,0 +1,85 @@ +#[doc = "Register `IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_ENB` writer"] +pub type W = crate::W; +#[doc = "Field `RAMSBE` reader - RAM Single Bit Interrupt"] +pub type RamsbeR = crate::BitReader; +#[doc = "Field `RAMSBE` writer - RAM Single Bit Interrupt"] +pub type RamsbeW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RAMMBE` reader - RAM Multi Bit Interrupt"] +pub type RammbeR = crate::BitReader; +#[doc = "Field `RAMMBE` writer - RAM Multi Bit Interrupt"] +pub type RammbeW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ROMSBE` reader - ROM Single Bit Interrupt"] +pub type RomsbeR = crate::BitReader; +#[doc = "Field `ROMSBE` writer - ROM Single Bit Interrupt"] +pub type RomsbeW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ROMMBE` reader - ROM Multi Bit Interrupt"] +pub type RommbeR = crate::BitReader; +#[doc = "Field `ROMMBE` writer - ROM Multi Bit Interrupt"] +pub type RommbeW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - RAM Single Bit Interrupt"] + #[inline(always)] + pub fn ramsbe(&self) -> RamsbeR { + RamsbeR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - RAM Multi Bit Interrupt"] + #[inline(always)] + pub fn rammbe(&self) -> RammbeR { + RammbeR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - ROM Single Bit Interrupt"] + #[inline(always)] + pub fn romsbe(&self) -> RomsbeR { + RomsbeR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - ROM Multi Bit Interrupt"] + #[inline(always)] + pub fn rommbe(&self) -> RommbeR { + RommbeR::new(((self.bits >> 3) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - RAM Single Bit Interrupt"] + #[inline(always)] + #[must_use] + pub fn ramsbe(&mut self) -> RamsbeW { + RamsbeW::new(self, 0) + } + #[doc = "Bit 1 - RAM Multi Bit Interrupt"] + #[inline(always)] + #[must_use] + pub fn rammbe(&mut self) -> RammbeW { + RammbeW::new(self, 1) + } + #[doc = "Bit 2 - ROM Single Bit Interrupt"] + #[inline(always)] + #[must_use] + pub fn romsbe(&mut self) -> RomsbeW { + RomsbeW::new(self, 2) + } + #[doc = "Bit 3 - ROM Multi Bit Interrupt"] + #[inline(always)] + #[must_use] + pub fn rommbe(&mut self) -> RommbeW { + RommbeW::new(self, 3) + } +} +#[doc = "Enable EDAC Error Interrupt Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEnbSpec; +impl crate::RegisterSpec for IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_enb::R`](R) reader structure"] +impl crate::Readable for IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_enb::W`](W) writer structure"] +impl crate::Writable for IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_ENB to value 0"] +impl crate::Resettable for IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/lockup_reset.rs b/va108xx/src/sysconfig/lockup_reset.rs new file mode 100644 index 0000000..0a0afd7 --- /dev/null +++ b/va108xx/src/sysconfig/lockup_reset.rs @@ -0,0 +1,40 @@ +#[doc = "Register `LOCKUP_RESET` reader"] +pub type R = crate::R; +#[doc = "Register `LOCKUP_RESET` writer"] +pub type W = crate::W; +#[doc = "Field `LREN` reader - Lockup Reset Enable Bit"] +pub type LrenR = crate::BitReader; +#[doc = "Field `LREN` writer - Lockup Reset Enable Bit"] +pub type LrenW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Lockup Reset Enable Bit"] + #[inline(always)] + pub fn lren(&self) -> LrenR { + LrenR::new((self.bits & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Lockup Reset Enable Bit"] + #[inline(always)] + #[must_use] + pub fn lren(&mut self) -> LrenW { + LrenW::new(self, 0) + } +} +#[doc = "Lockup Reset Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`lockup_reset::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`lockup_reset::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct LockupResetSpec; +impl crate::RegisterSpec for LockupResetSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`lockup_reset::R`](R) reader structure"] +impl crate::Readable for LockupResetSpec {} +#[doc = "`write(|w| ..)` method takes [`lockup_reset::W`](W) writer structure"] +impl crate::Writable for LockupResetSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets LOCKUP_RESET to value 0x01"] +impl crate::Resettable for LockupResetSpec { + const RESET_VALUE: u32 = 0x01; +} diff --git a/va108xx/src/sysconfig/perid.rs b/va108xx/src/sysconfig/perid.rs new file mode 100644 index 0000000..5a84e29 --- /dev/null +++ b/va108xx/src/sysconfig/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0080_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0080_07e1; +} diff --git a/va108xx/src/sysconfig/peripheral_clk_enable.rs b/va108xx/src/sysconfig/peripheral_clk_enable.rs new file mode 100644 index 0000000..46a6025 --- /dev/null +++ b/va108xx/src/sysconfig/peripheral_clk_enable.rs @@ -0,0 +1,248 @@ +#[doc = "Register `PERIPHERAL_CLK_ENABLE` reader"] +pub type R = crate::R; +#[doc = "Register `PERIPHERAL_CLK_ENABLE` writer"] +pub type W = crate::W; +#[doc = "Field `PORTA` reader - Enable PORTA clock"] +pub type PortaR = crate::BitReader; +#[doc = "Field `PORTA` writer - Enable PORTA clock"] +pub type PortaW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PORTB` reader - Enable PORTB clock"] +pub type PortbR = crate::BitReader; +#[doc = "Field `PORTB` writer - Enable PORTB clock"] +pub type PortbW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_0` reader - Enable SPI\\[0\\] +clock"] +pub type Spi0R = crate::BitReader; +#[doc = "Field `SPI_0` writer - Enable SPI\\[0\\] +clock"] +pub type Spi0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_1` reader - Enable SPI\\[1\\] +clock"] +pub type Spi1R = crate::BitReader; +#[doc = "Field `SPI_1` writer - Enable SPI\\[1\\] +clock"] +pub type Spi1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_2` reader - Enable SPI\\[2\\] +clock"] +pub type Spi2R = crate::BitReader; +#[doc = "Field `SPI_2` writer - Enable SPI\\[2\\] +clock"] +pub type Spi2W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UART_0` reader - Enable UART\\[0\\] +clock"] +pub type Uart0R = crate::BitReader; +#[doc = "Field `UART_0` writer - Enable UART\\[0\\] +clock"] +pub type Uart0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UART_1` reader - Enable UART\\[1\\] +clock"] +pub type Uart1R = crate::BitReader; +#[doc = "Field `UART_1` writer - Enable UART\\[1\\] +clock"] +pub type Uart1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_0` reader - Enable I2C\\[0\\] +clock"] +pub type I2c0R = crate::BitReader; +#[doc = "Field `I2C_0` writer - Enable I2C\\[0\\] +clock"] +pub type I2c0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_1` reader - Enable I2C\\[1\\] +clock"] +pub type I2c1R = crate::BitReader; +#[doc = "Field `I2C_1` writer - Enable I2C\\[1\\] +clock"] +pub type I2c1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQSEL` reader - Enable IRQ selector clock"] +pub type IrqselR = crate::BitReader; +#[doc = "Field `IRQSEL` writer - Enable IRQ selector clock"] +pub type IrqselW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IOCONFIG` reader - Enable IO Configuration block clock"] +pub type IoconfigR = crate::BitReader; +#[doc = "Field `IOCONFIG` writer - Enable IO Configuration block clock"] +pub type IoconfigW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UTILITY` reader - Enable utility clock"] +pub type UtilityR = crate::BitReader; +#[doc = "Field `UTILITY` writer - Enable utility clock"] +pub type UtilityW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `GPIO` reader - Enable GPIO clock"] +pub type GpioR = crate::BitReader; +#[doc = "Field `GPIO` writer - Enable GPIO clock"] +pub type GpioW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Enable PORTA clock"] + #[inline(always)] + pub fn porta(&self) -> PortaR { + PortaR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Enable PORTB clock"] + #[inline(always)] + pub fn portb(&self) -> PortbR { + PortbR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 4 - Enable SPI\\[0\\] +clock"] + #[inline(always)] + pub fn spi_0(&self) -> Spi0R { + Spi0R::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - Enable SPI\\[1\\] +clock"] + #[inline(always)] + pub fn spi_1(&self) -> Spi1R { + Spi1R::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - Enable SPI\\[2\\] +clock"] + #[inline(always)] + pub fn spi_2(&self) -> Spi2R { + Spi2R::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 8 - Enable UART\\[0\\] +clock"] + #[inline(always)] + pub fn uart_0(&self) -> Uart0R { + Uart0R::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Enable UART\\[1\\] +clock"] + #[inline(always)] + pub fn uart_1(&self) -> Uart1R { + Uart1R::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 16 - Enable I2C\\[0\\] +clock"] + #[inline(always)] + pub fn i2c_0(&self) -> I2c0R { + I2c0R::new(((self.bits >> 16) & 1) != 0) + } + #[doc = "Bit 17 - Enable I2C\\[1\\] +clock"] + #[inline(always)] + pub fn i2c_1(&self) -> I2c1R { + I2c1R::new(((self.bits >> 17) & 1) != 0) + } + #[doc = "Bit 21 - Enable IRQ selector clock"] + #[inline(always)] + pub fn irqsel(&self) -> IrqselR { + IrqselR::new(((self.bits >> 21) & 1) != 0) + } + #[doc = "Bit 22 - Enable IO Configuration block clock"] + #[inline(always)] + pub fn ioconfig(&self) -> IoconfigR { + IoconfigR::new(((self.bits >> 22) & 1) != 0) + } + #[doc = "Bit 23 - Enable utility clock"] + #[inline(always)] + pub fn utility(&self) -> UtilityR { + UtilityR::new(((self.bits >> 23) & 1) != 0) + } + #[doc = "Bit 24 - Enable GPIO clock"] + #[inline(always)] + pub fn gpio(&self) -> GpioR { + GpioR::new(((self.bits >> 24) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Enable PORTA clock"] + #[inline(always)] + #[must_use] + pub fn porta(&mut self) -> PortaW { + PortaW::new(self, 0) + } + #[doc = "Bit 1 - Enable PORTB clock"] + #[inline(always)] + #[must_use] + pub fn portb(&mut self) -> PortbW { + PortbW::new(self, 1) + } + #[doc = "Bit 4 - Enable SPI\\[0\\] +clock"] + #[inline(always)] + #[must_use] + pub fn spi_0(&mut self) -> Spi0W { + Spi0W::new(self, 4) + } + #[doc = "Bit 5 - Enable SPI\\[1\\] +clock"] + #[inline(always)] + #[must_use] + pub fn spi_1(&mut self) -> Spi1W { + Spi1W::new(self, 5) + } + #[doc = "Bit 6 - Enable SPI\\[2\\] +clock"] + #[inline(always)] + #[must_use] + pub fn spi_2(&mut self) -> Spi2W { + Spi2W::new(self, 6) + } + #[doc = "Bit 8 - Enable UART\\[0\\] +clock"] + #[inline(always)] + #[must_use] + pub fn uart_0(&mut self) -> Uart0W { + Uart0W::new(self, 8) + } + #[doc = "Bit 9 - Enable UART\\[1\\] +clock"] + #[inline(always)] + #[must_use] + pub fn uart_1(&mut self) -> Uart1W { + Uart1W::new(self, 9) + } + #[doc = "Bit 16 - Enable I2C\\[0\\] +clock"] + #[inline(always)] + #[must_use] + pub fn i2c_0(&mut self) -> I2c0W { + I2c0W::new(self, 16) + } + #[doc = "Bit 17 - Enable I2C\\[1\\] +clock"] + #[inline(always)] + #[must_use] + pub fn i2c_1(&mut self) -> I2c1W { + I2c1W::new(self, 17) + } + #[doc = "Bit 21 - Enable IRQ selector clock"] + #[inline(always)] + #[must_use] + pub fn irqsel(&mut self) -> IrqselW { + IrqselW::new(self, 21) + } + #[doc = "Bit 22 - Enable IO Configuration block clock"] + #[inline(always)] + #[must_use] + pub fn ioconfig(&mut self) -> IoconfigW { + IoconfigW::new(self, 22) + } + #[doc = "Bit 23 - Enable utility clock"] + #[inline(always)] + #[must_use] + pub fn utility(&mut self) -> UtilityW { + UtilityW::new(self, 23) + } + #[doc = "Bit 24 - Enable GPIO clock"] + #[inline(always)] + #[must_use] + pub fn gpio(&mut self) -> GpioW { + GpioW::new(self, 24) + } +} +#[doc = "Peripheral Enable Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`peripheral_clk_enable::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`peripheral_clk_enable::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeripheralClkEnableSpec; +impl crate::RegisterSpec for PeripheralClkEnableSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`peripheral_clk_enable::R`](R) reader structure"] +impl crate::Readable for PeripheralClkEnableSpec {} +#[doc = "`write(|w| ..)` method takes [`peripheral_clk_enable::W`](W) writer structure"] +impl crate::Writable for PeripheralClkEnableSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PERIPHERAL_CLK_ENABLE to value 0"] +impl crate::Resettable for PeripheralClkEnableSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/peripheral_reset.rs b/va108xx/src/sysconfig/peripheral_reset.rs new file mode 100644 index 0000000..4f302d7 --- /dev/null +++ b/va108xx/src/sysconfig/peripheral_reset.rs @@ -0,0 +1,220 @@ +#[doc = "Register `PERIPHERAL_RESET` reader"] +pub type R = crate::R; +#[doc = "Register `PERIPHERAL_RESET` writer"] +pub type W = crate::W; +#[doc = "Field `PORTA` reader - Reset PORTA"] +pub type PortaR = crate::BitReader; +#[doc = "Field `PORTA` writer - Reset PORTA"] +pub type PortaW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PORTB` reader - Reset PORTB"] +pub type PortbR = crate::BitReader; +#[doc = "Field `PORTB` writer - Reset PORTB"] +pub type PortbW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_0` reader - Reset SPI\\[0\\]"] +pub type Spi0R = crate::BitReader; +#[doc = "Field `SPI_0` writer - Reset SPI\\[0\\]"] +pub type Spi0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_1` reader - Reset SPI\\[1\\]"] +pub type Spi1R = crate::BitReader; +#[doc = "Field `SPI_1` writer - Reset SPI\\[1\\]"] +pub type Spi1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SPI_2` reader - Reset SPI\\[2\\]"] +pub type Spi2R = crate::BitReader; +#[doc = "Field `SPI_2` writer - Reset SPI\\[2\\]"] +pub type Spi2W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UART_0` reader - Reset UART\\[0\\]"] +pub type Uart0R = crate::BitReader; +#[doc = "Field `UART_0` writer - Reset UART\\[0\\]"] +pub type Uart0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UART_1` reader - Reset UART\\[1\\]"] +pub type Uart1R = crate::BitReader; +#[doc = "Field `UART_1` writer - Reset UART\\[1\\]"] +pub type Uart1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_0` reader - Reset I2C\\[0\\]"] +pub type I2c0R = crate::BitReader; +#[doc = "Field `I2C_0` writer - Reset I2C\\[0\\]"] +pub type I2c0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `I2C_1` reader - Reset I2C\\[1\\]"] +pub type I2c1R = crate::BitReader; +#[doc = "Field `I2C_1` writer - Reset I2C\\[1\\]"] +pub type I2c1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQSEL` reader - Reset IRQ selector"] +pub type IrqselR = crate::BitReader; +#[doc = "Field `IRQSEL` writer - Reset IRQ selector"] +pub type IrqselW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IOCONFIG` reader - Reset IO Configuration block"] +pub type IoconfigR = crate::BitReader; +#[doc = "Field `IOCONFIG` writer - Reset IO Configuration block"] +pub type IoconfigW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `UTILITY` reader - Reset Utility Block"] +pub type UtilityR = crate::BitReader; +#[doc = "Field `UTILITY` writer - Reset Utility Block"] +pub type UtilityW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `GPIO` reader - Reset GPIO"] +pub type GpioR = crate::BitReader; +#[doc = "Field `GPIO` writer - Reset GPIO"] +pub type GpioW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Reset PORTA"] + #[inline(always)] + pub fn porta(&self) -> PortaR { + PortaR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Reset PORTB"] + #[inline(always)] + pub fn portb(&self) -> PortbR { + PortbR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 4 - Reset SPI\\[0\\]"] + #[inline(always)] + pub fn spi_0(&self) -> Spi0R { + Spi0R::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - Reset SPI\\[1\\]"] + #[inline(always)] + pub fn spi_1(&self) -> Spi1R { + Spi1R::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - Reset SPI\\[2\\]"] + #[inline(always)] + pub fn spi_2(&self) -> Spi2R { + Spi2R::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 8 - Reset UART\\[0\\]"] + #[inline(always)] + pub fn uart_0(&self) -> Uart0R { + Uart0R::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Reset UART\\[1\\]"] + #[inline(always)] + pub fn uart_1(&self) -> Uart1R { + Uart1R::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 16 - Reset I2C\\[0\\]"] + #[inline(always)] + pub fn i2c_0(&self) -> I2c0R { + I2c0R::new(((self.bits >> 16) & 1) != 0) + } + #[doc = "Bit 17 - Reset I2C\\[1\\]"] + #[inline(always)] + pub fn i2c_1(&self) -> I2c1R { + I2c1R::new(((self.bits >> 17) & 1) != 0) + } + #[doc = "Bit 21 - Reset IRQ selector"] + #[inline(always)] + pub fn irqsel(&self) -> IrqselR { + IrqselR::new(((self.bits >> 21) & 1) != 0) + } + #[doc = "Bit 22 - Reset IO Configuration block"] + #[inline(always)] + pub fn ioconfig(&self) -> IoconfigR { + IoconfigR::new(((self.bits >> 22) & 1) != 0) + } + #[doc = "Bit 23 - Reset Utility Block"] + #[inline(always)] + pub fn utility(&self) -> UtilityR { + UtilityR::new(((self.bits >> 23) & 1) != 0) + } + #[doc = "Bit 24 - Reset GPIO"] + #[inline(always)] + pub fn gpio(&self) -> GpioR { + GpioR::new(((self.bits >> 24) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Reset PORTA"] + #[inline(always)] + #[must_use] + pub fn porta(&mut self) -> PortaW { + PortaW::new(self, 0) + } + #[doc = "Bit 1 - Reset PORTB"] + #[inline(always)] + #[must_use] + pub fn portb(&mut self) -> PortbW { + PortbW::new(self, 1) + } + #[doc = "Bit 4 - Reset SPI\\[0\\]"] + #[inline(always)] + #[must_use] + pub fn spi_0(&mut self) -> Spi0W { + Spi0W::new(self, 4) + } + #[doc = "Bit 5 - Reset SPI\\[1\\]"] + #[inline(always)] + #[must_use] + pub fn spi_1(&mut self) -> Spi1W { + Spi1W::new(self, 5) + } + #[doc = "Bit 6 - Reset SPI\\[2\\]"] + #[inline(always)] + #[must_use] + pub fn spi_2(&mut self) -> Spi2W { + Spi2W::new(self, 6) + } + #[doc = "Bit 8 - Reset UART\\[0\\]"] + #[inline(always)] + #[must_use] + pub fn uart_0(&mut self) -> Uart0W { + Uart0W::new(self, 8) + } + #[doc = "Bit 9 - Reset UART\\[1\\]"] + #[inline(always)] + #[must_use] + pub fn uart_1(&mut self) -> Uart1W { + Uart1W::new(self, 9) + } + #[doc = "Bit 16 - Reset I2C\\[0\\]"] + #[inline(always)] + #[must_use] + pub fn i2c_0(&mut self) -> I2c0W { + I2c0W::new(self, 16) + } + #[doc = "Bit 17 - Reset I2C\\[1\\]"] + #[inline(always)] + #[must_use] + pub fn i2c_1(&mut self) -> I2c1W { + I2c1W::new(self, 17) + } + #[doc = "Bit 21 - Reset IRQ selector"] + #[inline(always)] + #[must_use] + pub fn irqsel(&mut self) -> IrqselW { + IrqselW::new(self, 21) + } + #[doc = "Bit 22 - Reset IO Configuration block"] + #[inline(always)] + #[must_use] + pub fn ioconfig(&mut self) -> IoconfigW { + IoconfigW::new(self, 22) + } + #[doc = "Bit 23 - Reset Utility Block"] + #[inline(always)] + #[must_use] + pub fn utility(&mut self) -> UtilityW { + UtilityW::new(self, 23) + } + #[doc = "Bit 24 - Reset GPIO"] + #[inline(always)] + #[must_use] + pub fn gpio(&mut self) -> GpioW { + GpioW::new(self, 24) + } +} +#[doc = "Peripheral Reset Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`peripheral_reset::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`peripheral_reset::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeripheralResetSpec; +impl crate::RegisterSpec for PeripheralResetSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`peripheral_reset::R`](R) reader structure"] +impl crate::Readable for PeripheralResetSpec {} +#[doc = "`write(|w| ..)` method takes [`peripheral_reset::W`](W) writer structure"] +impl crate::Writable for PeripheralResetSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PERIPHERAL_RESET to value 0xffff_ffff"] +impl crate::Resettable for PeripheralResetSpec { + const RESET_VALUE: u32 = 0xffff_ffff; +} diff --git a/va108xx/src/sysconfig/procid.rs b/va108xx/src/sysconfig/procid.rs new file mode 100644 index 0000000..203b2fe --- /dev/null +++ b/va108xx/src/sysconfig/procid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PROCID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Processor ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`procid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ProcidSpec; +impl crate::RegisterSpec for ProcidSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`procid::R`](R) reader structure"] +impl crate::Readable for ProcidSpec {} +#[doc = "`reset()` method sets PROCID to value 0x0400_17e3"] +impl crate::Resettable for ProcidSpec { + const RESET_VALUE: u32 = 0x0400_17e3; +} diff --git a/va108xx/src/sysconfig/ram_sbe.rs b/va108xx/src/sysconfig/ram_sbe.rs new file mode 100644 index 0000000..e3ae75c --- /dev/null +++ b/va108xx/src/sysconfig/ram_sbe.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RAM_SBE` reader"] +pub type R = crate::R; +#[doc = "Register `RAM_SBE` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Count of RAM EDAC Single Bit Errors\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ram_sbe::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ram_sbe::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RamSbeSpec; +impl crate::RegisterSpec for RamSbeSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ram_sbe::R`](R) reader structure"] +impl crate::Readable for RamSbeSpec {} +#[doc = "`write(|w| ..)` method takes [`ram_sbe::W`](W) writer structure"] +impl crate::Writable for RamSbeSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RAM_SBE to value 0"] +impl crate::Resettable for RamSbeSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/refresh_config.rs b/va108xx/src/sysconfig/refresh_config.rs new file mode 100644 index 0000000..fd34ab4 --- /dev/null +++ b/va108xx/src/sysconfig/refresh_config.rs @@ -0,0 +1,27 @@ +#[doc = "Register `REFRESH_CONFIG` reader"] +pub type R = crate::R; +#[doc = "Register `REFRESH_CONFIG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Register Refresh Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`refresh_config::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`refresh_config::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RefreshConfigSpec; +impl crate::RegisterSpec for RefreshConfigSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`refresh_config::R`](R) reader structure"] +impl crate::Readable for RefreshConfigSpec {} +#[doc = "`write(|w| ..)` method takes [`refresh_config::W`](W) writer structure"] +impl crate::Writable for RefreshConfigSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets REFRESH_CONFIG to value 0"] +impl crate::Resettable for RefreshConfigSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/rom_prot.rs b/va108xx/src/sysconfig/rom_prot.rs new file mode 100644 index 0000000..525344e --- /dev/null +++ b/va108xx/src/sysconfig/rom_prot.rs @@ -0,0 +1,40 @@ +#[doc = "Register `ROM_PROT` reader"] +pub type R = crate::R; +#[doc = "Register `ROM_PROT` writer"] +pub type W = crate::W; +#[doc = "Field `WREN` reader - ROM Write Enable Bit"] +pub type WrenR = crate::BitReader; +#[doc = "Field `WREN` writer - ROM Write Enable Bit"] +pub type WrenW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - ROM Write Enable Bit"] + #[inline(always)] + pub fn wren(&self) -> WrenR { + WrenR::new((self.bits & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - ROM Write Enable Bit"] + #[inline(always)] + #[must_use] + pub fn wren(&mut self) -> WrenW { + WrenW::new(self, 0) + } +} +#[doc = "ROM Protection Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_prot::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_prot::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RomProtSpec; +impl crate::RegisterSpec for RomProtSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rom_prot::R`](R) reader structure"] +impl crate::Readable for RomProtSpec {} +#[doc = "`write(|w| ..)` method takes [`rom_prot::W`](W) writer structure"] +impl crate::Writable for RomProtSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ROM_PROT to value 0x01"] +impl crate::Resettable for RomProtSpec { + const RESET_VALUE: u32 = 0x01; +} diff --git a/va108xx/src/sysconfig/rom_retries.rs b/va108xx/src/sysconfig/rom_retries.rs new file mode 100644 index 0000000..2278e6e --- /dev/null +++ b/va108xx/src/sysconfig/rom_retries.rs @@ -0,0 +1,18 @@ +#[doc = "Register `ROM_RETRIES` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "ROM BOOT Retry count\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_retries::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RomRetriesSpec; +impl crate::RegisterSpec for RomRetriesSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rom_retries::R`](R) reader structure"] +impl crate::Readable for RomRetriesSpec {} +#[doc = "`reset()` method sets ROM_RETRIES to value 0"] +impl crate::Resettable for RomRetriesSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/rom_scrub.rs b/va108xx/src/sysconfig/rom_scrub.rs new file mode 100644 index 0000000..20d5262 --- /dev/null +++ b/va108xx/src/sysconfig/rom_scrub.rs @@ -0,0 +1,48 @@ +#[doc = "Register `ROM_SCRUB` reader"] +pub type R = crate::R; +#[doc = "Register `ROM_SCRUB` writer"] +pub type W = crate::W; +#[doc = "Field `VALUE` reader - Counter divide value"] +pub type ValueR = crate::FieldReader; +#[doc = "Field `VALUE` writer - Counter divide value"] +pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 24, u32>; +#[doc = "Field `RESET` writer - Reset Counter"] +pub type ResetW<'a, REG> = crate::BitWriter1C<'a, REG>; +impl R { + #[doc = "Bits 0:23 - Counter divide value"] + #[inline(always)] + pub fn value(&self) -> ValueR { + ValueR::new(self.bits & 0x00ff_ffff) + } +} +impl W { + #[doc = "Bits 0:23 - Counter divide value"] + #[inline(always)] + #[must_use] + pub fn value(&mut self) -> ValueW { + ValueW::new(self, 0) + } + #[doc = "Bit 31 - Reset Counter"] + #[inline(always)] + #[must_use] + pub fn reset(&mut self) -> ResetW { + ResetW::new(self, 31) + } +} +#[doc = "ROM Scrub Period Configuration\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_scrub::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_scrub::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RomScrubSpec; +impl crate::RegisterSpec for RomScrubSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rom_scrub::R`](R) reader structure"] +impl crate::Readable for RomScrubSpec {} +#[doc = "`write(|w| ..)` method takes [`rom_scrub::W`](W) writer structure"] +impl crate::Writable for RomScrubSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0x8000_0000; +} +#[doc = "`reset()` method sets ROM_SCRUB to value 0"] +impl crate::Resettable for RomScrubSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/rom_trap_addr.rs b/va108xx/src/sysconfig/rom_trap_addr.rs new file mode 100644 index 0000000..a2c45db --- /dev/null +++ b/va108xx/src/sysconfig/rom_trap_addr.rs @@ -0,0 +1,55 @@ +#[doc = "Register `ROM_TRAP_ADDR` reader"] +pub type R = crate::R; +#[doc = "Register `ROM_TRAP_ADDR` writer"] +pub type W = crate::W; +#[doc = "Field `ADDR` reader - Trap Address Match Bits"] +pub type AddrR = crate::FieldReader; +#[doc = "Field `ADDR` writer - Trap Address Match Bits"] +pub type AddrW<'a, REG> = crate::FieldWriter<'a, REG, 14, u16>; +#[doc = "Field `ENABLE` reader - Trap Enable Bit"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - Trap Enable Bit"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bits 2:15 - Trap Address Match Bits"] + #[inline(always)] + pub fn addr(&self) -> AddrR { + AddrR::new(((self.bits >> 2) & 0x3fff) as u16) + } + #[doc = "Bit 31 - Trap Enable Bit"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new(((self.bits >> 31) & 1) != 0) + } +} +impl W { + #[doc = "Bits 2:15 - Trap Address Match Bits"] + #[inline(always)] + #[must_use] + pub fn addr(&mut self) -> AddrW { + AddrW::new(self, 2) + } + #[doc = "Bit 31 - Trap Enable Bit"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 31) + } +} +#[doc = "ROM Trap Address\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_trap_addr::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_trap_addr::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RomTrapAddrSpec; +impl crate::RegisterSpec for RomTrapAddrSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rom_trap_addr::R`](R) reader structure"] +impl crate::Readable for RomTrapAddrSpec {} +#[doc = "`write(|w| ..)` method takes [`rom_trap_addr::W`](W) writer structure"] +impl crate::Writable for RomTrapAddrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ROM_TRAP_ADDR to value 0"] +impl crate::Resettable for RomTrapAddrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/rom_trap_synd.rs b/va108xx/src/sysconfig/rom_trap_synd.rs new file mode 100644 index 0000000..cb7a4e6 --- /dev/null +++ b/va108xx/src/sysconfig/rom_trap_synd.rs @@ -0,0 +1,40 @@ +#[doc = "Register `ROM_TRAP_SYND` reader"] +pub type R = crate::R; +#[doc = "Register `ROM_TRAP_SYND` writer"] +pub type W = crate::W; +#[doc = "Field `SYND` reader - Trap Syndrom Bits"] +pub type SyndR = crate::FieldReader; +#[doc = "Field `SYND` writer - Trap Syndrom Bits"] +pub type SyndW<'a, REG> = crate::FieldWriter<'a, REG, 20, u32>; +impl R { + #[doc = "Bits 0:19 - Trap Syndrom Bits"] + #[inline(always)] + pub fn synd(&self) -> SyndR { + SyndR::new(self.bits & 0x000f_ffff) + } +} +impl W { + #[doc = "Bits 0:19 - Trap Syndrom Bits"] + #[inline(always)] + #[must_use] + pub fn synd(&mut self) -> SyndW { + SyndW::new(self, 0) + } +} +#[doc = "ROM Trap Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rom_trap_synd::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rom_trap_synd::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RomTrapSyndSpec; +impl crate::RegisterSpec for RomTrapSyndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rom_trap_synd::R`](R) reader structure"] +impl crate::Readable for RomTrapSyndSpec {} +#[doc = "`write(|w| ..)` method takes [`rom_trap_synd::W`](W) writer structure"] +impl crate::Writable for RomTrapSyndSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ROM_TRAP_SYND to value 0"] +impl crate::Resettable for RomTrapSyndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/rst_stat.rs b/va108xx/src/sysconfig/rst_stat.rs new file mode 100644 index 0000000..e671bbd --- /dev/null +++ b/va108xx/src/sysconfig/rst_stat.rs @@ -0,0 +1,115 @@ +#[doc = "Register `RST_STAT` reader"] +pub type R = crate::R; +#[doc = "Register `RST_STAT` writer"] +pub type W = crate::W; +#[doc = "Field `POR` reader - Power On Reset Status"] +pub type PorR = crate::BitReader; +#[doc = "Field `POR` writer - Power On Reset Status"] +pub type PorW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `EXTRST` reader - External Reset Status"] +pub type ExtrstR = crate::BitReader; +#[doc = "Field `EXTRST` writer - External Reset Status"] +pub type ExtrstW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `SYSRSTREQ` reader - SYSRESETREQ Reset Status"] +pub type SysrstreqR = crate::BitReader; +#[doc = "Field `SYSRSTREQ` writer - SYSRESETREQ Reset Status"] +pub type SysrstreqW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `LOOKUP` reader - LOOKUP Reset Status"] +pub type LookupR = crate::BitReader; +#[doc = "Field `LOOKUP` writer - LOOKUP Reset Status"] +pub type LookupW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `WATCHDOG` reader - WATCHDOG Reset Status"] +pub type WatchdogR = crate::BitReader; +#[doc = "Field `WATCHDOG` writer - WATCHDOG Reset Status"] +pub type WatchdogW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `MEMERR` reader - Memory Error Reset Status"] +pub type MemerrR = crate::BitReader; +#[doc = "Field `MEMERR` writer - Memory Error Reset Status"] +pub type MemerrW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Power On Reset Status"] + #[inline(always)] + pub fn por(&self) -> PorR { + PorR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - External Reset Status"] + #[inline(always)] + pub fn extrst(&self) -> ExtrstR { + ExtrstR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - SYSRESETREQ Reset Status"] + #[inline(always)] + pub fn sysrstreq(&self) -> SysrstreqR { + SysrstreqR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - LOOKUP Reset Status"] + #[inline(always)] + pub fn lookup(&self) -> LookupR { + LookupR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - WATCHDOG Reset Status"] + #[inline(always)] + pub fn watchdog(&self) -> WatchdogR { + WatchdogR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - Memory Error Reset Status"] + #[inline(always)] + pub fn memerr(&self) -> MemerrR { + MemerrR::new(((self.bits >> 5) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Power On Reset Status"] + #[inline(always)] + #[must_use] + pub fn por(&mut self) -> PorW { + PorW::new(self, 0) + } + #[doc = "Bit 1 - External Reset Status"] + #[inline(always)] + #[must_use] + pub fn extrst(&mut self) -> ExtrstW { + ExtrstW::new(self, 1) + } + #[doc = "Bit 2 - SYSRESETREQ Reset Status"] + #[inline(always)] + #[must_use] + pub fn sysrstreq(&mut self) -> SysrstreqW { + SysrstreqW::new(self, 2) + } + #[doc = "Bit 3 - LOOKUP Reset Status"] + #[inline(always)] + #[must_use] + pub fn lookup(&mut self) -> LookupW { + LookupW::new(self, 3) + } + #[doc = "Bit 4 - WATCHDOG Reset Status"] + #[inline(always)] + #[must_use] + pub fn watchdog(&mut self) -> WatchdogW { + WatchdogW::new(self, 4) + } + #[doc = "Bit 5 - Memory Error Reset Status"] + #[inline(always)] + #[must_use] + pub fn memerr(&mut self) -> MemerrW { + MemerrW::new(self, 5) + } +} +#[doc = "System Reset Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rst_stat::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rst_stat::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RstStatSpec; +impl crate::RegisterSpec for RstStatSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rst_stat::R`](R) reader structure"] +impl crate::Readable for RstStatSpec {} +#[doc = "`write(|w| ..)` method takes [`rst_stat::W`](W) writer structure"] +impl crate::Writable for RstStatSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RST_STAT to value 0x01"] +impl crate::Resettable for RstStatSpec { + const RESET_VALUE: u32 = 0x01; +} diff --git a/va108xx/src/sysconfig/tim_clk_enable.rs b/va108xx/src/sysconfig/tim_clk_enable.rs new file mode 100644 index 0000000..f0b91e7 --- /dev/null +++ b/va108xx/src/sysconfig/tim_clk_enable.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TIM_CLK_ENABLE` reader"] +pub type R = crate::R; +#[doc = "Register `TIM_CLK_ENABLE` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "TIM Enable Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tim_clk_enable::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tim_clk_enable::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TimClkEnableSpec; +impl crate::RegisterSpec for TimClkEnableSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`tim_clk_enable::R`](R) reader structure"] +impl crate::Readable for TimClkEnableSpec {} +#[doc = "`write(|w| ..)` method takes [`tim_clk_enable::W`](W) writer structure"] +impl crate::Writable for TimClkEnableSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TIM_CLK_ENABLE to value 0"] +impl crate::Resettable for TimClkEnableSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/sysconfig/tim_reset.rs b/va108xx/src/sysconfig/tim_reset.rs new file mode 100644 index 0000000..82aceb4 --- /dev/null +++ b/va108xx/src/sysconfig/tim_reset.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TIM_RESET` reader"] +pub type R = crate::R; +#[doc = "Register `TIM_RESET` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "TIM Reset Control\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`tim_reset::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`tim_reset::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TimResetSpec; +impl crate::RegisterSpec for TimResetSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`tim_reset::R`](R) reader structure"] +impl crate::Readable for TimResetSpec {} +#[doc = "`write(|w| ..)` method takes [`tim_reset::W`](W) writer structure"] +impl crate::Writable for TimResetSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TIM_RESET to value 0xffff_ffff"] +impl crate::Resettable for TimResetSpec { + const RESET_VALUE: u32 = 0xffff_ffff; +} diff --git a/va108xx/src/tim0.rs b/va108xx/src/tim0.rs new file mode 100644 index 0000000..7b3ad32 --- /dev/null +++ b/va108xx/src/tim0.rs @@ -0,0 +1,142 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + ctrl: Ctrl, + rst_value: RstValue, + cnt_value: CntValue, + enable: Enable, + csd_ctrl: CsdCtrl, + cascade0: Cascade0, + cascade1: Cascade1, + cascade2: Cascade2, + _reserved_8_pwm_value: [u8; 0x04], + pwmb_value: PwmbValue, + _reserved10: [u8; 0x0fd4], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Control Register"] + #[inline(always)] + pub const fn ctrl(&self) -> &Ctrl { + &self.ctrl + } + #[doc = "0x04 - The value that counter start from after reaching 0."] + #[inline(always)] + pub const fn rst_value(&self) -> &RstValue { + &self.rst_value + } + #[doc = "0x08 - The current value of the counter"] + #[inline(always)] + pub const fn cnt_value(&self) -> &CntValue { + &self.cnt_value + } + #[doc = "0x0c - Alternate access to the Counter ENABLE bit in the CTRL Register"] + #[inline(always)] + pub const fn enable(&self) -> &Enable { + &self.enable + } + #[doc = "0x10 - The Cascade Control Register. Controls the counter external enable signals"] + #[inline(always)] + pub const fn csd_ctrl(&self) -> &CsdCtrl { + &self.csd_ctrl + } + #[doc = "0x14 - Cascade Enable Selection"] + #[inline(always)] + pub const fn cascade0(&self) -> &Cascade0 { + &self.cascade0 + } + #[doc = "0x18 - Cascade Enable Selection"] + #[inline(always)] + pub const fn cascade1(&self) -> &Cascade1 { + &self.cascade1 + } + #[doc = "0x1c - Cascade Enable Selection"] + #[inline(always)] + pub const fn cascade2(&self) -> &Cascade2 { + &self.cascade2 + } + #[doc = "0x20 - The Pulse Width Modulation ValueA"] + #[inline(always)] + pub const fn pwma_value(&self) -> &PwmaValue { + unsafe { &*(self as *const Self).cast::().add(32).cast() } + } + #[doc = "0x20 - The Pulse Width Modulation Value"] + #[inline(always)] + pub const fn pwm_value(&self) -> &PwmValue { + unsafe { &*(self as *const Self).cast::().add(32).cast() } + } + #[doc = "0x24 - The Pulse Width Modulation ValueB"] + #[inline(always)] + pub const fn pwmb_value(&self) -> &PwmbValue { + &self.pwmb_value + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "CTRL (rw) register accessor: Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ctrl`] +module"] +#[doc(alias = "CTRL")] +pub type Ctrl = crate::Reg; +#[doc = "Control Register"] +pub mod ctrl; +#[doc = "RST_VALUE (rw) register accessor: The value that counter start from after reaching 0.\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rst_value::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rst_value::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rst_value`] +module"] +#[doc(alias = "RST_VALUE")] +pub type RstValue = crate::Reg; +#[doc = "The value that counter start from after reaching 0."] +pub mod rst_value; +#[doc = "CNT_VALUE (rw) register accessor: The current value of the counter\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cnt_value::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cnt_value::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@cnt_value`] +module"] +#[doc(alias = "CNT_VALUE")] +pub type CntValue = crate::Reg; +#[doc = "The current value of the counter"] +pub mod cnt_value; +#[doc = "ENABLE (rw) register accessor: Alternate access to the Counter ENABLE bit in the CTRL Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`enable::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`enable::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@enable`] +module"] +#[doc(alias = "ENABLE")] +pub type Enable = crate::Reg; +#[doc = "Alternate access to the Counter ENABLE bit in the CTRL Register"] +pub mod enable; +#[doc = "CSD_CTRL (rw) register accessor: The Cascade Control Register. Controls the counter external enable signals\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`csd_ctrl::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`csd_ctrl::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@csd_ctrl`] +module"] +#[doc(alias = "CSD_CTRL")] +pub type CsdCtrl = crate::Reg; +#[doc = "The Cascade Control Register. Controls the counter external enable signals"] +pub mod csd_ctrl; +#[doc = "CASCADE0 (rw) register accessor: Cascade Enable Selection\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cascade0::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cascade0::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@cascade0`] +module"] +#[doc(alias = "CASCADE0")] +pub type Cascade0 = crate::Reg; +#[doc = "Cascade Enable Selection"] +pub mod cascade0; +pub use cascade0 as cascade1; +pub use cascade0 as cascade2; +pub use Cascade0 as Cascade1; +pub use Cascade0 as Cascade2; +#[doc = "PWM_VALUE (rw) register accessor: The Pulse Width Modulation Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwm_value::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwm_value::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@pwm_value`] +module"] +#[doc(alias = "PWM_VALUE")] +pub type PwmValue = crate::Reg; +#[doc = "The Pulse Width Modulation Value"] +pub mod pwm_value; +#[doc = "PWMA_VALUE (rw) register accessor: The Pulse Width Modulation ValueA\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwma_value::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwma_value::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@pwma_value`] +module"] +#[doc(alias = "PWMA_VALUE")] +pub type PwmaValue = crate::Reg; +#[doc = "The Pulse Width Modulation ValueA"] +pub mod pwma_value; +#[doc = "PWMB_VALUE (rw) register accessor: The Pulse Width Modulation ValueB\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwmb_value::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwmb_value::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@pwmb_value`] +module"] +#[doc(alias = "PWMB_VALUE")] +pub type PwmbValue = crate::Reg; +#[doc = "The Pulse Width Modulation ValueB"] +pub mod pwmb_value; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/tim0/cascade0.rs b/va108xx/src/tim0/cascade0.rs new file mode 100644 index 0000000..984dd73 --- /dev/null +++ b/va108xx/src/tim0/cascade0.rs @@ -0,0 +1,40 @@ +#[doc = "Register `CASCADE0` reader"] +pub type R = crate::R; +#[doc = "Register `CASCADE0` writer"] +pub type W = crate::W; +#[doc = "Field `CASSEL` reader - Cascade Selection"] +pub type CasselR = crate::FieldReader; +#[doc = "Field `CASSEL` writer - Cascade Selection"] +pub type CasselW<'a, REG> = crate::FieldWriter<'a, REG, 8>; +impl R { + #[doc = "Bits 0:7 - Cascade Selection"] + #[inline(always)] + pub fn cassel(&self) -> CasselR { + CasselR::new((self.bits & 0xff) as u8) + } +} +impl W { + #[doc = "Bits 0:7 - Cascade Selection"] + #[inline(always)] + #[must_use] + pub fn cassel(&mut self) -> CasselW { + CasselW::new(self, 0) + } +} +#[doc = "Cascade Enable Selection\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cascade0::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cascade0::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct Cascade0Spec; +impl crate::RegisterSpec for Cascade0Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`cascade0::R`](R) reader structure"] +impl crate::Readable for Cascade0Spec {} +#[doc = "`write(|w| ..)` method takes [`cascade0::W`](W) writer structure"] +impl crate::Writable for Cascade0Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CASCADE0 to value 0"] +impl crate::Resettable for Cascade0Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/cnt_value.rs b/va108xx/src/tim0/cnt_value.rs new file mode 100644 index 0000000..f5ee38a --- /dev/null +++ b/va108xx/src/tim0/cnt_value.rs @@ -0,0 +1,27 @@ +#[doc = "Register `CNT_VALUE` reader"] +pub type R = crate::R; +#[doc = "Register `CNT_VALUE` writer"] +pub type W = crate::W; +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 current value of the counter\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`cnt_value::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`cnt_value::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CntValueSpec; +impl crate::RegisterSpec for CntValueSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`cnt_value::R`](R) reader structure"] +impl crate::Readable for CntValueSpec {} +#[doc = "`write(|w| ..)` method takes [`cnt_value::W`](W) writer structure"] +impl crate::Writable for CntValueSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CNT_VALUE to value 0"] +impl crate::Resettable for CntValueSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/csd_ctrl.rs b/va108xx/src/tim0/csd_ctrl.rs new file mode 100644 index 0000000..2a53a5b --- /dev/null +++ b/va108xx/src/tim0/csd_ctrl.rs @@ -0,0 +1,190 @@ +#[doc = "Register `CSD_CTRL` reader"] +pub type R = crate::R; +#[doc = "Register `CSD_CTRL` writer"] +pub type W = crate::W; +#[doc = "Field `CSDEN0` reader - Cascade 0 Enable"] +pub type Csden0R = crate::BitReader; +#[doc = "Field `CSDEN0` writer - Cascade 0 Enable"] +pub type Csden0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDINV0` reader - Cascade 0 Invert"] +pub type Csdinv0R = crate::BitReader; +#[doc = "Field `CSDINV0` writer - Cascade 0 Invert"] +pub type Csdinv0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDEN1` reader - Cascade 1 Enable"] +pub type Csden1R = crate::BitReader; +#[doc = "Field `CSDEN1` writer - Cascade 1 Enable"] +pub type Csden1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDINV1` reader - Cascade 1 Invert"] +pub type Csdinv1R = crate::BitReader; +#[doc = "Field `CSDINV1` writer - Cascade 1 Invert"] +pub type Csdinv1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `DCASOP` reader - Dual Cascade Operation (0:AND, 1:OR)"] +pub type DcasopR = crate::BitReader; +#[doc = "Field `DCASOP` writer - Dual Cascade Operation (0:AND, 1:OR)"] +pub type DcasopW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDTRG0` reader - Cascade 0 Enabled as Trigger"] +pub type Csdtrg0R = crate::BitReader; +#[doc = "Field `CSDTRG0` writer - Cascade 0 Enabled as Trigger"] +pub type Csdtrg0W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDTRG1` reader - Cascade 1 Enabled as Trigger"] +pub type Csdtrg1R = crate::BitReader; +#[doc = "Field `CSDTRG1` writer - Cascade 1 Enabled as Trigger"] +pub type Csdtrg1W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDEN2` reader - Cascade 2 Enable"] +pub type Csden2R = crate::BitReader; +#[doc = "Field `CSDEN2` writer - Cascade 2 Enable"] +pub type Csden2W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDINV2` reader - Cascade 2 Invert"] +pub type Csdinv2R = crate::BitReader; +#[doc = "Field `CSDINV2` writer - Cascade 2 Invert"] +pub type Csdinv2W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDTRG2` reader - Cascade 2 Enabled as Trigger"] +pub type Csdtrg2R = crate::BitReader; +#[doc = "Field `CSDTRG2` writer - Cascade 2 Enabled as Trigger"] +pub type Csdtrg2W<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `CSDXXX2` reader - Cascade 2 test mode"] +pub type Csdxxx2R = crate::BitReader; +#[doc = "Field `CSDXXX2` writer - Cascade 2 test mode"] +pub type Csdxxx2W<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Cascade 0 Enable"] + #[inline(always)] + pub fn csden0(&self) -> Csden0R { + Csden0R::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Cascade 0 Invert"] + #[inline(always)] + pub fn csdinv0(&self) -> Csdinv0R { + Csdinv0R::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Cascade 1 Enable"] + #[inline(always)] + pub fn csden1(&self) -> Csden1R { + Csden1R::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Cascade 1 Invert"] + #[inline(always)] + pub fn csdinv1(&self) -> Csdinv1R { + Csdinv1R::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Dual Cascade Operation (0:AND, 1:OR)"] + #[inline(always)] + pub fn dcasop(&self) -> DcasopR { + DcasopR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 6 - Cascade 0 Enabled as Trigger"] + #[inline(always)] + pub fn csdtrg0(&self) -> Csdtrg0R { + Csdtrg0R::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - Cascade 1 Enabled as Trigger"] + #[inline(always)] + pub fn csdtrg1(&self) -> Csdtrg1R { + Csdtrg1R::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - Cascade 2 Enable"] + #[inline(always)] + pub fn csden2(&self) -> Csden2R { + Csden2R::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Cascade 2 Invert"] + #[inline(always)] + pub fn csdinv2(&self) -> Csdinv2R { + Csdinv2R::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - Cascade 2 Enabled as Trigger"] + #[inline(always)] + pub fn csdtrg2(&self) -> Csdtrg2R { + Csdtrg2R::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - Cascade 2 test mode"] + #[inline(always)] + pub fn csdxxx2(&self) -> Csdxxx2R { + Csdxxx2R::new(((self.bits >> 11) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Cascade 0 Enable"] + #[inline(always)] + #[must_use] + pub fn csden0(&mut self) -> Csden0W { + Csden0W::new(self, 0) + } + #[doc = "Bit 1 - Cascade 0 Invert"] + #[inline(always)] + #[must_use] + pub fn csdinv0(&mut self) -> Csdinv0W { + Csdinv0W::new(self, 1) + } + #[doc = "Bit 2 - Cascade 1 Enable"] + #[inline(always)] + #[must_use] + pub fn csden1(&mut self) -> Csden1W { + Csden1W::new(self, 2) + } + #[doc = "Bit 3 - Cascade 1 Invert"] + #[inline(always)] + #[must_use] + pub fn csdinv1(&mut self) -> Csdinv1W { + Csdinv1W::new(self, 3) + } + #[doc = "Bit 4 - Dual Cascade Operation (0:AND, 1:OR)"] + #[inline(always)] + #[must_use] + pub fn dcasop(&mut self) -> DcasopW { + DcasopW::new(self, 4) + } + #[doc = "Bit 6 - Cascade 0 Enabled as Trigger"] + #[inline(always)] + #[must_use] + pub fn csdtrg0(&mut self) -> Csdtrg0W { + Csdtrg0W::new(self, 6) + } + #[doc = "Bit 7 - Cascade 1 Enabled as Trigger"] + #[inline(always)] + #[must_use] + pub fn csdtrg1(&mut self) -> Csdtrg1W { + Csdtrg1W::new(self, 7) + } + #[doc = "Bit 8 - Cascade 2 Enable"] + #[inline(always)] + #[must_use] + pub fn csden2(&mut self) -> Csden2W { + Csden2W::new(self, 8) + } + #[doc = "Bit 9 - Cascade 2 Invert"] + #[inline(always)] + #[must_use] + pub fn csdinv2(&mut self) -> Csdinv2W { + Csdinv2W::new(self, 9) + } + #[doc = "Bit 10 - Cascade 2 Enabled as Trigger"] + #[inline(always)] + #[must_use] + pub fn csdtrg2(&mut self) -> Csdtrg2W { + Csdtrg2W::new(self, 10) + } + #[doc = "Bit 11 - Cascade 2 test mode"] + #[inline(always)] + #[must_use] + pub fn csdxxx2(&mut self) -> Csdxxx2W { + Csdxxx2W::new(self, 11) + } +} +#[doc = "The Cascade Control Register. Controls the counter external enable signals\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`csd_ctrl::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`csd_ctrl::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CsdCtrlSpec; +impl crate::RegisterSpec for CsdCtrlSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`csd_ctrl::R`](R) reader structure"] +impl crate::Readable for CsdCtrlSpec {} +#[doc = "`write(|w| ..)` method takes [`csd_ctrl::W`](W) writer structure"] +impl crate::Writable for CsdCtrlSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CSD_CTRL to value 0"] +impl crate::Resettable for CsdCtrlSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/ctrl.rs b/va108xx/src/tim0/ctrl.rs new file mode 100644 index 0000000..32b2b66 --- /dev/null +++ b/va108xx/src/tim0/ctrl.rs @@ -0,0 +1,258 @@ +#[doc = "Register `CTRL` reader"] +pub type R = crate::R; +#[doc = "Register `CTRL` writer"] +pub type W = crate::W; +#[doc = "Field `ENABLE` reader - Counter Enable"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - Counter Enable"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `ACTIVE` reader - Counter Active"] +pub type ActiveR = crate::BitReader; +#[doc = "Field `AUTO_DISABLE` reader - Auto Disables the counter (set ENABLE to 0) when the count reaches 0"] +pub type AutoDisableR = crate::BitReader; +#[doc = "Field `AUTO_DISABLE` writer - Auto Disables the counter (set ENABLE to 0) when the count reaches 0"] +pub type AutoDisableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `AUTO_DEACTIVATE` reader - Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0"] +pub type AutoDeactivateR = crate::BitReader; +#[doc = "Field `AUTO_DEACTIVATE` writer - Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0"] +pub type AutoDeactivateW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_ENB` reader - Interrupt Enable"] +pub type IrqEnbR = crate::BitReader; +#[doc = "Field `IRQ_ENB` writer - Interrupt Enable"] +pub type IrqEnbW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Counter Status Selection\n\nValue on reset: 0"] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum StatusSel { + #[doc = "0: Single cycle pulse when the counter reaches 0"] + Done = 0, + #[doc = "1: Returns the counter ACTIVE bit"] + Active = 1, + #[doc = "2: Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output."] + Toggle = 2, + #[doc = "3: Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE"] + Pwma = 3, + #[doc = "4: Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE"] + Pwmb = 4, + #[doc = "5: Returns the counter ENABLED bit"] + Enabled = 5, + #[doc = "6: Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0"] + PwmaActive = 6, +} +impl From for u8 { + #[inline(always)] + fn from(variant: StatusSel) -> Self { + variant as _ + } +} +impl crate::FieldSpec for StatusSel { + type Ux = u8; +} +impl crate::IsEnum for StatusSel {} +#[doc = "Field `STATUS_SEL` reader - Counter Status Selection"] +pub type StatusSelR = crate::FieldReader; +impl StatusSelR { + #[doc = "Get enumerated values variant"] + #[inline(always)] + pub const fn variant(&self) -> Option { + match self.bits { + 0 => Some(StatusSel::Done), + 1 => Some(StatusSel::Active), + 2 => Some(StatusSel::Toggle), + 3 => Some(StatusSel::Pwma), + 4 => Some(StatusSel::Pwmb), + 5 => Some(StatusSel::Enabled), + 6 => Some(StatusSel::PwmaActive), + _ => None, + } + } + #[doc = "Single cycle pulse when the counter reaches 0"] + #[inline(always)] + pub fn is_done(&self) -> bool { + *self == StatusSel::Done + } + #[doc = "Returns the counter ACTIVE bit"] + #[inline(always)] + pub fn is_active(&self) -> bool { + *self == StatusSel::Active + } + #[doc = "Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output."] + #[inline(always)] + pub fn is_toggle(&self) -> bool { + *self == StatusSel::Toggle + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE"] + #[inline(always)] + pub fn is_pwma(&self) -> bool { + *self == StatusSel::Pwma + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE"] + #[inline(always)] + pub fn is_pwmb(&self) -> bool { + *self == StatusSel::Pwmb + } + #[doc = "Returns the counter ENABLED bit"] + #[inline(always)] + pub fn is_enabled(&self) -> bool { + *self == StatusSel::Enabled + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0"] + #[inline(always)] + pub fn is_pwma_active(&self) -> bool { + *self == StatusSel::PwmaActive + } +} +#[doc = "Field `STATUS_SEL` writer - Counter Status Selection"] +pub type StatusSelW<'a, REG> = crate::FieldWriter<'a, REG, 3, StatusSel>; +impl<'a, REG> StatusSelW<'a, REG> +where + REG: crate::Writable + crate::RegisterSpec, + REG::Ux: From, +{ + #[doc = "Single cycle pulse when the counter reaches 0"] + #[inline(always)] + pub fn done(self) -> &'a mut crate::W { + self.variant(StatusSel::Done) + } + #[doc = "Returns the counter ACTIVE bit"] + #[inline(always)] + pub fn active(self) -> &'a mut crate::W { + self.variant(StatusSel::Active) + } + #[doc = "Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output."] + #[inline(always)] + pub fn toggle(self) -> &'a mut crate::W { + self.variant(StatusSel::Toggle) + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE"] + #[inline(always)] + pub fn pwma(self) -> &'a mut crate::W { + self.variant(StatusSel::Pwma) + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE"] + #[inline(always)] + pub fn pwmb(self) -> &'a mut crate::W { + self.variant(StatusSel::Pwmb) + } + #[doc = "Returns the counter ENABLED bit"] + #[inline(always)] + pub fn enabled(self) -> &'a mut crate::W { + self.variant(StatusSel::Enabled) + } + #[doc = "Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0"] + #[inline(always)] + pub fn pwma_active(self) -> &'a mut crate::W { + self.variant(StatusSel::PwmaActive) + } +} +#[doc = "Field `STATUS_INV` reader - Invert the Output Status"] +pub type StatusInvR = crate::BitReader; +#[doc = "Field `STATUS_INV` writer - Invert the Output Status"] +pub type StatusInvW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `REQ_STOP` reader - Stop Request"] +pub type ReqStopR = crate::BitReader; +#[doc = "Field `REQ_STOP` writer - Stop Request"] +pub type ReqStopW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Counter Enable"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Counter Active"] + #[inline(always)] + pub fn active(&self) -> ActiveR { + ActiveR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Auto Disables the counter (set ENABLE to 0) when the count reaches 0"] + #[inline(always)] + pub fn auto_disable(&self) -> AutoDisableR { + AutoDisableR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0"] + #[inline(always)] + pub fn auto_deactivate(&self) -> AutoDeactivateR { + AutoDeactivateR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Interrupt Enable"] + #[inline(always)] + pub fn irq_enb(&self) -> IrqEnbR { + IrqEnbR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bits 5:7 - Counter Status Selection"] + #[inline(always)] + pub fn status_sel(&self) -> StatusSelR { + StatusSelR::new(((self.bits >> 5) & 7) as u8) + } + #[doc = "Bit 8 - Invert the Output Status"] + #[inline(always)] + pub fn status_inv(&self) -> StatusInvR { + StatusInvR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Stop Request"] + #[inline(always)] + pub fn req_stop(&self) -> ReqStopR { + ReqStopR::new(((self.bits >> 9) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Counter Enable"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 0) + } + #[doc = "Bit 2 - Auto Disables the counter (set ENABLE to 0) when the count reaches 0"] + #[inline(always)] + #[must_use] + pub fn auto_disable(&mut self) -> AutoDisableW { + AutoDisableW::new(self, 2) + } + #[doc = "Bit 3 - Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0"] + #[inline(always)] + #[must_use] + pub fn auto_deactivate(&mut self) -> AutoDeactivateW { + AutoDeactivateW::new(self, 3) + } + #[doc = "Bit 4 - Interrupt Enable"] + #[inline(always)] + #[must_use] + pub fn irq_enb(&mut self) -> IrqEnbW { + IrqEnbW::new(self, 4) + } + #[doc = "Bits 5:7 - Counter Status Selection"] + #[inline(always)] + #[must_use] + pub fn status_sel(&mut self) -> StatusSelW { + StatusSelW::new(self, 5) + } + #[doc = "Bit 8 - Invert the Output Status"] + #[inline(always)] + #[must_use] + pub fn status_inv(&mut self) -> StatusInvW { + StatusInvW::new(self, 8) + } + #[doc = "Bit 9 - Stop Request"] + #[inline(always)] + #[must_use] + pub fn req_stop(&mut self) -> ReqStopW { + ReqStopW::new(self, 9) + } +} +#[doc = "Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CtrlSpec; +impl crate::RegisterSpec for CtrlSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ctrl::R`](R) reader structure"] +impl crate::Readable for CtrlSpec {} +#[doc = "`write(|w| ..)` method takes [`ctrl::W`](W) writer structure"] +impl crate::Writable for CtrlSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CTRL to value 0"] +impl crate::Resettable for CtrlSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/enable.rs b/va108xx/src/tim0/enable.rs new file mode 100644 index 0000000..2064cab --- /dev/null +++ b/va108xx/src/tim0/enable.rs @@ -0,0 +1,40 @@ +#[doc = "Register `ENABLE` reader"] +pub type R = crate::R; +#[doc = "Register `ENABLE` writer"] +pub type W = crate::W; +#[doc = "Field `ENABLE` reader - Counter Enable"] +pub type EnableR = crate::BitReader; +#[doc = "Field `ENABLE` writer - Counter Enable"] +pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Counter Enable"] + #[inline(always)] + pub fn enable(&self) -> EnableR { + EnableR::new((self.bits & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Counter Enable"] + #[inline(always)] + #[must_use] + pub fn enable(&mut self) -> EnableW { + EnableW::new(self, 0) + } +} +#[doc = "Alternate access to the Counter ENABLE bit in the CTRL Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`enable::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`enable::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct EnableSpec; +impl crate::RegisterSpec for EnableSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`enable::R`](R) reader structure"] +impl crate::Readable for EnableSpec {} +#[doc = "`write(|w| ..)` method takes [`enable::W`](W) writer structure"] +impl crate::Writable for EnableSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ENABLE to value 0"] +impl crate::Resettable for EnableSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/perid.rs b/va108xx/src/tim0/perid.rs new file mode 100644 index 0000000..75f49ab --- /dev/null +++ b/va108xx/src/tim0/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0011_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0011_07e1; +} diff --git a/va108xx/src/tim0/pwm_value.rs b/va108xx/src/tim0/pwm_value.rs new file mode 100644 index 0000000..b3b1480 --- /dev/null +++ b/va108xx/src/tim0/pwm_value.rs @@ -0,0 +1,27 @@ +#[doc = "Register `PWM_VALUE` reader"] +pub type R = crate::R; +#[doc = "Register `PWM_VALUE` writer"] +pub type W = crate::W; +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 Pulse Width Modulation Value\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwm_value::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwm_value::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PwmValueSpec; +impl crate::RegisterSpec for PwmValueSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`pwm_value::R`](R) reader structure"] +impl crate::Readable for PwmValueSpec {} +#[doc = "`write(|w| ..)` method takes [`pwm_value::W`](W) writer structure"] +impl crate::Writable for PwmValueSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PWM_VALUE to value 0"] +impl crate::Resettable for PwmValueSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/pwma_value.rs b/va108xx/src/tim0/pwma_value.rs new file mode 100644 index 0000000..ec26532 --- /dev/null +++ b/va108xx/src/tim0/pwma_value.rs @@ -0,0 +1,27 @@ +#[doc = "Register `PWMA_VALUE` reader"] +pub type R = crate::R; +#[doc = "Register `PWMA_VALUE` writer"] +pub type W = crate::W; +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 Pulse Width Modulation ValueA\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwma_value::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwma_value::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PwmaValueSpec; +impl crate::RegisterSpec for PwmaValueSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`pwma_value::R`](R) reader structure"] +impl crate::Readable for PwmaValueSpec {} +#[doc = "`write(|w| ..)` method takes [`pwma_value::W`](W) writer structure"] +impl crate::Writable for PwmaValueSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PWMA_VALUE to value 0"] +impl crate::Resettable for PwmaValueSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/pwmb_value.rs b/va108xx/src/tim0/pwmb_value.rs new file mode 100644 index 0000000..587cb50 --- /dev/null +++ b/va108xx/src/tim0/pwmb_value.rs @@ -0,0 +1,27 @@ +#[doc = "Register `PWMB_VALUE` reader"] +pub type R = crate::R; +#[doc = "Register `PWMB_VALUE` writer"] +pub type W = crate::W; +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 Pulse Width Modulation ValueB\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`pwmb_value::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`pwmb_value::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PwmbValueSpec; +impl crate::RegisterSpec for PwmbValueSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`pwmb_value::R`](R) reader structure"] +impl crate::Readable for PwmbValueSpec {} +#[doc = "`write(|w| ..)` method takes [`pwmb_value::W`](W) writer structure"] +impl crate::Writable for PwmbValueSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets PWMB_VALUE to value 0"] +impl crate::Resettable for PwmbValueSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/tim0/rst_value.rs b/va108xx/src/tim0/rst_value.rs new file mode 100644 index 0000000..2dfa5b4 --- /dev/null +++ b/va108xx/src/tim0/rst_value.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RST_VALUE` reader"] +pub type R = crate::R; +#[doc = "Register `RST_VALUE` writer"] +pub type W = crate::W; +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 value that counter start from after reaching 0.\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rst_value::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rst_value::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RstValueSpec; +impl crate::RegisterSpec for RstValueSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rst_value::R`](R) reader structure"] +impl crate::Readable for RstValueSpec {} +#[doc = "`write(|w| ..)` method takes [`rst_value::W`](W) writer structure"] +impl crate::Writable for RstValueSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RST_VALUE to value 0"] +impl crate::Resettable for RstValueSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta.rs b/va108xx/src/uarta.rs new file mode 100644 index 0000000..71aa47b --- /dev/null +++ b/va108xx/src/uarta.rs @@ -0,0 +1,223 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + data: Data, + enable: Enable, + ctrl: Ctrl, + clkscale: Clkscale, + rxstatus: Rxstatus, + txstatus: Txstatus, + fifo_clr: FifoClr, + txbreak: Txbreak, + addr9: Addr9, + addr9mask: Addr9mask, + irq_enb: IrqEnb, + irq_raw: IrqRaw, + irq_end: IrqEnd, + irq_clr: IrqClr, + rxfifoirqtrg: Rxfifoirqtrg, + txfifoirqtrg: Txfifoirqtrg, + rxfifortstrg: Rxfifortstrg, + state: State, + _reserved18: [u8; 0x0fb4], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Data In/Out Register"] + #[inline(always)] + pub const fn data(&self) -> &Data { + &self.data + } + #[doc = "0x04 - Enable Register"] + #[inline(always)] + pub const fn enable(&self) -> &Enable { + &self.enable + } + #[doc = "0x08 - Control Register"] + #[inline(always)] + pub const fn ctrl(&self) -> &Ctrl { + &self.ctrl + } + #[doc = "0x0c - Clock Scale Register"] + #[inline(always)] + pub const fn clkscale(&self) -> &Clkscale { + &self.clkscale + } + #[doc = "0x10 - Status Register"] + #[inline(always)] + pub const fn rxstatus(&self) -> &Rxstatus { + &self.rxstatus + } + #[doc = "0x14 - Status Register"] + #[inline(always)] + pub const fn txstatus(&self) -> &Txstatus { + &self.txstatus + } + #[doc = "0x18 - Clear FIFO Register"] + #[inline(always)] + pub const fn fifo_clr(&self) -> &FifoClr { + &self.fifo_clr + } + #[doc = "0x1c - Break Transmit Register"] + #[inline(always)] + pub const fn txbreak(&self) -> &Txbreak { + &self.txbreak + } + #[doc = "0x20 - Address9 Register"] + #[inline(always)] + pub const fn addr9(&self) -> &Addr9 { + &self.addr9 + } + #[doc = "0x24 - Address9 Mask Register"] + #[inline(always)] + pub const fn addr9mask(&self) -> &Addr9mask { + &self.addr9mask + } + #[doc = "0x28 - IRQ Enable Register"] + #[inline(always)] + pub const fn irq_enb(&self) -> &IrqEnb { + &self.irq_enb + } + #[doc = "0x2c - IRQ Raw Status Register"] + #[inline(always)] + pub const fn irq_raw(&self) -> &IrqRaw { + &self.irq_raw + } + #[doc = "0x30 - IRQ Enabled Status Register"] + #[inline(always)] + pub const fn irq_end(&self) -> &IrqEnd { + &self.irq_end + } + #[doc = "0x34 - IRQ Clear Status Register"] + #[inline(always)] + pub const fn irq_clr(&self) -> &IrqClr { + &self.irq_clr + } + #[doc = "0x38 - Rx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn rxfifoirqtrg(&self) -> &Rxfifoirqtrg { + &self.rxfifoirqtrg + } + #[doc = "0x3c - Tx FIFO IRQ Trigger Level"] + #[inline(always)] + pub const fn txfifoirqtrg(&self) -> &Txfifoirqtrg { + &self.txfifoirqtrg + } + #[doc = "0x40 - Rx FIFO RTS Trigger Level"] + #[inline(always)] + pub const fn rxfifortstrg(&self) -> &Rxfifortstrg { + &self.rxfifortstrg + } + #[doc = "0x44 - Internal STATE of UART Controller"] + #[inline(always)] + pub const fn state(&self) -> &State { + &self.state + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "DATA (rw) register accessor: Data In/Out Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@data`] +module"] +#[doc(alias = "DATA")] +pub type Data = crate::Reg; +#[doc = "Data In/Out Register"] +pub mod data; +#[doc = "ENABLE (rw) register accessor: Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`enable::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`enable::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@enable`] +module"] +#[doc(alias = "ENABLE")] +pub type Enable = crate::Reg; +#[doc = "Enable Register"] +pub mod enable; +#[doc = "CTRL (rw) register accessor: Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@ctrl`] +module"] +#[doc(alias = "CTRL")] +pub type Ctrl = crate::Reg; +#[doc = "Control Register"] +pub mod ctrl; +#[doc = "CLKSCALE (rw) register accessor: Clock Scale Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkscale::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkscale::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@clkscale`] +module"] +#[doc(alias = "CLKSCALE")] +pub type Clkscale = crate::Reg; +#[doc = "Clock Scale Register"] +pub mod clkscale; +#[doc = "RXSTATUS (r) register accessor: Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxstatus::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxstatus`] +module"] +#[doc(alias = "RXSTATUS")] +pub type Rxstatus = crate::Reg; +#[doc = "Status Register"] +pub mod rxstatus; +#[doc = "TXSTATUS (r) register accessor: Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txstatus::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txstatus`] +module"] +#[doc(alias = "TXSTATUS")] +pub type Txstatus = crate::Reg; +#[doc = "Status Register"] +pub mod txstatus; +#[doc = "FIFO_CLR (w) register accessor: Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@fifo_clr`] +module"] +#[doc(alias = "FIFO_CLR")] +pub type FifoClr = crate::Reg; +#[doc = "Clear FIFO Register"] +pub mod fifo_clr; +#[doc = "TXBREAK (w) register accessor: Break Transmit Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txbreak::W`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txbreak`] +module"] +#[doc(alias = "TXBREAK")] +pub type Txbreak = crate::Reg; +#[doc = "Break Transmit Register"] +pub mod txbreak; +#[doc = "ADDR9 (rw) register accessor: Address9 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`addr9::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`addr9::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@addr9`] +module"] +#[doc(alias = "ADDR9")] +pub type Addr9 = crate::Reg; +#[doc = "Address9 Register"] +pub mod addr9; +#[doc = "ADDR9MASK (rw) register accessor: Address9 Mask Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`addr9mask::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`addr9mask::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@addr9mask`] +module"] +#[doc(alias = "ADDR9MASK")] +pub type Addr9mask = crate::Reg; +#[doc = "Address9 Mask Register"] +pub mod addr9mask; +#[doc = "IRQ_ENB (rw) register accessor: IRQ Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@irq_enb`] +module"] +#[doc(alias = "IRQ_ENB")] +pub type IrqEnb = crate::Reg; +#[doc = "IRQ Enable Register"] +pub mod irq_enb; +pub use irq_enb as irq_raw; +pub use irq_enb as irq_end; +pub use irq_enb as irq_clr; +pub use IrqEnb as IrqRaw; +pub use IrqEnb as IrqEnd; +pub use IrqEnb as IrqClr; +#[doc = "RXFIFOIRQTRG (rw) register accessor: Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxfifoirqtrg`] +module"] +#[doc(alias = "RXFIFOIRQTRG")] +pub type Rxfifoirqtrg = crate::Reg; +#[doc = "Rx FIFO IRQ Trigger Level"] +pub mod rxfifoirqtrg; +#[doc = "TXFIFOIRQTRG (rw) register accessor: Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@txfifoirqtrg`] +module"] +#[doc(alias = "TXFIFOIRQTRG")] +pub type Txfifoirqtrg = crate::Reg; +#[doc = "Tx FIFO IRQ Trigger Level"] +pub mod txfifoirqtrg; +#[doc = "RXFIFORTSTRG (rw) register accessor: Rx FIFO RTS Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifortstrg::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifortstrg::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@rxfifortstrg`] +module"] +#[doc(alias = "RXFIFORTSTRG")] +pub type Rxfifortstrg = crate::Reg; +#[doc = "Rx FIFO RTS Trigger Level"] +pub mod rxfifortstrg; +#[doc = "STATE (r) register accessor: Internal STATE of UART Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@state`] +module"] +#[doc(alias = "STATE")] +pub type State = crate::Reg; +#[doc = "Internal STATE of UART Controller"] +pub mod state; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/uarta/addr9.rs b/va108xx/src/uarta/addr9.rs new file mode 100644 index 0000000..bca4484 --- /dev/null +++ b/va108xx/src/uarta/addr9.rs @@ -0,0 +1,27 @@ +#[doc = "Register `ADDR9` reader"] +pub type R = crate::R; +#[doc = "Register `ADDR9` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Address9 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`addr9::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`addr9::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct Addr9Spec; +impl crate::RegisterSpec for Addr9Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`addr9::R`](R) reader structure"] +impl crate::Readable for Addr9Spec {} +#[doc = "`write(|w| ..)` method takes [`addr9::W`](W) writer structure"] +impl crate::Writable for Addr9Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ADDR9 to value 0"] +impl crate::Resettable for Addr9Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/addr9mask.rs b/va108xx/src/uarta/addr9mask.rs new file mode 100644 index 0000000..f96e772 --- /dev/null +++ b/va108xx/src/uarta/addr9mask.rs @@ -0,0 +1,27 @@ +#[doc = "Register `ADDR9MASK` reader"] +pub type R = crate::R; +#[doc = "Register `ADDR9MASK` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Address9 Mask Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`addr9mask::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`addr9mask::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct Addr9maskSpec; +impl crate::RegisterSpec for Addr9maskSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`addr9mask::R`](R) reader structure"] +impl crate::Readable for Addr9maskSpec {} +#[doc = "`write(|w| ..)` method takes [`addr9mask::W`](W) writer structure"] +impl crate::Writable for Addr9maskSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ADDR9MASK to value 0"] +impl crate::Resettable for Addr9maskSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/clkscale.rs b/va108xx/src/uarta/clkscale.rs new file mode 100644 index 0000000..14a5e79 --- /dev/null +++ b/va108xx/src/uarta/clkscale.rs @@ -0,0 +1,63 @@ +#[doc = "Register `CLKSCALE` reader"] +pub type R = crate::R; +#[doc = "Register `CLKSCALE` writer"] +pub type W = crate::W; +#[doc = "Field `FRAC` reader - Fractional Divide (64ths)"] +pub type FracR = crate::FieldReader; +#[doc = "Field `FRAC` writer - Fractional Divide (64ths)"] +pub type FracW<'a, REG> = crate::FieldWriter<'a, REG, 6>; +#[doc = "Field `INT` reader - Integer Divide"] +pub type IntR = crate::FieldReader; +#[doc = "Field `INT` writer - Integer Divide"] +pub type IntW<'a, REG> = crate::FieldWriter<'a, REG, 18, u32>; +#[doc = "Field `RESET` writer - Reset Baud Counter"] +pub type ResetW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bits 0:5 - Fractional Divide (64ths)"] + #[inline(always)] + pub fn frac(&self) -> FracR { + FracR::new((self.bits & 0x3f) as u8) + } + #[doc = "Bits 6:23 - Integer Divide"] + #[inline(always)] + pub fn int(&self) -> IntR { + IntR::new((self.bits >> 6) & 0x0003_ffff) + } +} +impl W { + #[doc = "Bits 0:5 - Fractional Divide (64ths)"] + #[inline(always)] + #[must_use] + pub fn frac(&mut self) -> FracW { + FracW::new(self, 0) + } + #[doc = "Bits 6:23 - Integer Divide"] + #[inline(always)] + #[must_use] + pub fn int(&mut self) -> IntW { + IntW::new(self, 6) + } + #[doc = "Bit 31 - Reset Baud Counter"] + #[inline(always)] + #[must_use] + pub fn reset(&mut self) -> ResetW { + ResetW::new(self, 31) + } +} +#[doc = "Clock Scale Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`clkscale::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`clkscale::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct ClkscaleSpec; +impl crate::RegisterSpec for ClkscaleSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`clkscale::R`](R) reader structure"] +impl crate::Readable for ClkscaleSpec {} +#[doc = "`write(|w| ..)` method takes [`clkscale::W`](W) writer structure"] +impl crate::Writable for ClkscaleSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CLKSCALE to value 0"] +impl crate::Resettable for ClkscaleSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/ctrl.rs b/va108xx/src/uarta/ctrl.rs new file mode 100644 index 0000000..965c45a --- /dev/null +++ b/va108xx/src/uarta/ctrl.rs @@ -0,0 +1,190 @@ +#[doc = "Register `CTRL` reader"] +pub type R = crate::R; +#[doc = "Register `CTRL` writer"] +pub type W = crate::W; +#[doc = "Field `PAREN` reader - Parity Enable"] +pub type ParenR = crate::BitReader; +#[doc = "Field `PAREN` writer - Parity Enable"] +pub type ParenW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PAREVEN` reader - Parity Even/Odd(1/0)"] +pub type ParevenR = crate::BitReader; +#[doc = "Field `PAREVEN` writer - Parity Even/Odd(1/0)"] +pub type ParevenW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `PARSTK` reader - Parity Sticky"] +pub type ParstkR = crate::BitReader; +#[doc = "Field `PARSTK` writer - Parity Sticky"] +pub type ParstkW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `STOPBITS` reader - Stop Bits 1/2(0/1)"] +pub type StopbitsR = crate::BitReader; +#[doc = "Field `STOPBITS` writer - Stop Bits 1/2(0/1)"] +pub type StopbitsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `WORDSIZE` reader - Word Size in Bits 5/6/7/8(00/01/10/11)"] +pub type WordsizeR = crate::FieldReader; +#[doc = "Field `WORDSIZE` writer - Word Size in Bits 5/6/7/8(00/01/10/11)"] +pub type WordsizeW<'a, REG> = crate::FieldWriter<'a, REG, 2>; +#[doc = "Field `LOOPBACK` reader - Loopback Enable"] +pub type LoopbackR = crate::BitReader; +#[doc = "Field `LOOPBACK` writer - Loopback Enable"] +pub type LoopbackW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `LOOPBACKBLK` reader - Loopback Block"] +pub type LoopbackblkR = crate::BitReader; +#[doc = "Field `LOOPBACKBLK` writer - Loopback Block"] +pub type LoopbackblkW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `AUTOCTS` reader - Enable Auto CTS mode"] +pub type AutoctsR = crate::BitReader; +#[doc = "Field `AUTOCTS` writer - Enable Auto CTS mode"] +pub type AutoctsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `DEFRTS` reader - Default RTSn value"] +pub type DefrtsR = crate::BitReader; +#[doc = "Field `DEFRTS` writer - Default RTSn value"] +pub type DefrtsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `AUTORTS` reader - Enable Auto RTS mode"] +pub type AutortsR = crate::BitReader; +#[doc = "Field `AUTORTS` writer - Enable Auto RTS mode"] +pub type AutortsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `BAUD8` reader - Enable BAUD8 mode"] +pub type Baud8R = crate::BitReader; +#[doc = "Field `BAUD8` writer - Enable BAUD8 mode"] +pub type Baud8W<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Parity Enable"] + #[inline(always)] + pub fn paren(&self) -> ParenR { + ParenR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Parity Even/Odd(1/0)"] + #[inline(always)] + pub fn pareven(&self) -> ParevenR { + ParevenR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - Parity Sticky"] + #[inline(always)] + pub fn parstk(&self) -> ParstkR { + ParstkR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Stop Bits 1/2(0/1)"] + #[inline(always)] + pub fn stopbits(&self) -> StopbitsR { + StopbitsR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bits 4:5 - Word Size in Bits 5/6/7/8(00/01/10/11)"] + #[inline(always)] + pub fn wordsize(&self) -> WordsizeR { + WordsizeR::new(((self.bits >> 4) & 3) as u8) + } + #[doc = "Bit 6 - Loopback Enable"] + #[inline(always)] + pub fn loopback(&self) -> LoopbackR { + LoopbackR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - Loopback Block"] + #[inline(always)] + pub fn loopbackblk(&self) -> LoopbackblkR { + LoopbackblkR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - Enable Auto CTS mode"] + #[inline(always)] + pub fn autocts(&self) -> AutoctsR { + AutoctsR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Default RTSn value"] + #[inline(always)] + pub fn defrts(&self) -> DefrtsR { + DefrtsR::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 10 - Enable Auto RTS mode"] + #[inline(always)] + pub fn autorts(&self) -> AutortsR { + AutortsR::new(((self.bits >> 10) & 1) != 0) + } + #[doc = "Bit 11 - Enable BAUD8 mode"] + #[inline(always)] + pub fn baud8(&self) -> Baud8R { + Baud8R::new(((self.bits >> 11) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Parity Enable"] + #[inline(always)] + #[must_use] + pub fn paren(&mut self) -> ParenW { + ParenW::new(self, 0) + } + #[doc = "Bit 1 - Parity Even/Odd(1/0)"] + #[inline(always)] + #[must_use] + pub fn pareven(&mut self) -> ParevenW { + ParevenW::new(self, 1) + } + #[doc = "Bit 2 - Parity Sticky"] + #[inline(always)] + #[must_use] + pub fn parstk(&mut self) -> ParstkW { + ParstkW::new(self, 2) + } + #[doc = "Bit 3 - Stop Bits 1/2(0/1)"] + #[inline(always)] + #[must_use] + pub fn stopbits(&mut self) -> StopbitsW { + StopbitsW::new(self, 3) + } + #[doc = "Bits 4:5 - Word Size in Bits 5/6/7/8(00/01/10/11)"] + #[inline(always)] + #[must_use] + pub fn wordsize(&mut self) -> WordsizeW { + WordsizeW::new(self, 4) + } + #[doc = "Bit 6 - Loopback Enable"] + #[inline(always)] + #[must_use] + pub fn loopback(&mut self) -> LoopbackW { + LoopbackW::new(self, 6) + } + #[doc = "Bit 7 - Loopback Block"] + #[inline(always)] + #[must_use] + pub fn loopbackblk(&mut self) -> LoopbackblkW { + LoopbackblkW::new(self, 7) + } + #[doc = "Bit 8 - Enable Auto CTS mode"] + #[inline(always)] + #[must_use] + pub fn autocts(&mut self) -> AutoctsW { + AutoctsW::new(self, 8) + } + #[doc = "Bit 9 - Default RTSn value"] + #[inline(always)] + #[must_use] + pub fn defrts(&mut self) -> DefrtsW { + DefrtsW::new(self, 9) + } + #[doc = "Bit 10 - Enable Auto RTS mode"] + #[inline(always)] + #[must_use] + pub fn autorts(&mut self) -> AutortsW { + AutortsW::new(self, 10) + } + #[doc = "Bit 11 - Enable BAUD8 mode"] + #[inline(always)] + #[must_use] + pub fn baud8(&mut self) -> Baud8W { + Baud8W::new(self, 11) + } +} +#[doc = "Control Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`ctrl::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`ctrl::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct CtrlSpec; +impl crate::RegisterSpec for CtrlSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`ctrl::R`](R) reader structure"] +impl crate::Readable for CtrlSpec {} +#[doc = "`write(|w| ..)` method takes [`ctrl::W`](W) writer structure"] +impl crate::Writable for CtrlSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets CTRL to value 0"] +impl crate::Resettable for CtrlSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/data.rs b/va108xx/src/uarta/data.rs new file mode 100644 index 0000000..bc64a6c --- /dev/null +++ b/va108xx/src/uarta/data.rs @@ -0,0 +1,27 @@ +#[doc = "Register `DATA` reader"] +pub type R = crate::R; +#[doc = "Register `DATA` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Data In/Out Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`data::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`data::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct DataSpec; +impl crate::RegisterSpec for DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`data::R`](R) reader structure"] +impl crate::Readable for DataSpec {} +#[doc = "`write(|w| ..)` method takes [`data::W`](W) writer structure"] +impl crate::Writable for DataSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets DATA to value 0"] +impl crate::Resettable for DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/enable.rs b/va108xx/src/uarta/enable.rs new file mode 100644 index 0000000..ad6f797 --- /dev/null +++ b/va108xx/src/uarta/enable.rs @@ -0,0 +1,55 @@ +#[doc = "Register `ENABLE` reader"] +pub type R = crate::R; +#[doc = "Register `ENABLE` writer"] +pub type W = crate::W; +#[doc = "Field `RXENABLE` reader - Rx Enable"] +pub type RxenableR = crate::BitReader; +#[doc = "Field `RXENABLE` writer - Rx Enable"] +pub type RxenableW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXENABLE` reader - Tx Enable"] +pub type TxenableR = crate::BitReader; +#[doc = "Field `TXENABLE` writer - Tx Enable"] +pub type TxenableW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - Rx Enable"] + #[inline(always)] + pub fn rxenable(&self) -> RxenableR { + RxenableR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Tx Enable"] + #[inline(always)] + pub fn txenable(&self) -> TxenableR { + TxenableR::new(((self.bits >> 1) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - Rx Enable"] + #[inline(always)] + #[must_use] + pub fn rxenable(&mut self) -> RxenableW { + RxenableW::new(self, 0) + } + #[doc = "Bit 1 - Tx Enable"] + #[inline(always)] + #[must_use] + pub fn txenable(&mut self) -> TxenableW { + TxenableW::new(self, 1) + } +} +#[doc = "Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`enable::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`enable::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct EnableSpec; +impl crate::RegisterSpec for EnableSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`enable::R`](R) reader structure"] +impl crate::Readable for EnableSpec {} +#[doc = "`write(|w| ..)` method takes [`enable::W`](W) writer structure"] +impl crate::Writable for EnableSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets ENABLE to value 0"] +impl crate::Resettable for EnableSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/fifo_clr.rs b/va108xx/src/uarta/fifo_clr.rs new file mode 100644 index 0000000..c7e88b4 --- /dev/null +++ b/va108xx/src/uarta/fifo_clr.rs @@ -0,0 +1,51 @@ +#[doc = "Register `FIFO_CLR` writer"] +pub type W = crate::W; +#[doc = "Field `RXSTS` writer - Clear Rx Status"] +pub type RxstsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXSTS` writer - Clear Tx Status"] +pub type TxstsW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `RXFIFO` writer - Clear Rx FIFO"] +pub type RxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `TXFIFO` writer - Clear Tx FIFO"] +pub type TxfifoW<'a, REG> = crate::BitWriter<'a, REG>; +impl W { + #[doc = "Bit 0 - Clear Rx Status"] + #[inline(always)] + #[must_use] + pub fn rxsts(&mut self) -> RxstsW { + RxstsW::new(self, 0) + } + #[doc = "Bit 1 - Clear Tx Status"] + #[inline(always)] + #[must_use] + pub fn txsts(&mut self) -> TxstsW { + TxstsW::new(self, 1) + } + #[doc = "Bit 2 - Clear Rx FIFO"] + #[inline(always)] + #[must_use] + pub fn rxfifo(&mut self) -> RxfifoW { + RxfifoW::new(self, 2) + } + #[doc = "Bit 3 - Clear Tx FIFO"] + #[inline(always)] + #[must_use] + pub fn txfifo(&mut self) -> TxfifoW { + TxfifoW::new(self, 3) + } +} +#[doc = "Clear FIFO Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`fifo_clr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct FifoClrSpec; +impl crate::RegisterSpec for FifoClrSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`fifo_clr::W`](W) writer structure"] +impl crate::Writable for FifoClrSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets FIFO_CLR to value 0"] +impl crate::Resettable for FifoClrSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/irq_enb.rs b/va108xx/src/uarta/irq_enb.rs new file mode 100644 index 0000000..6702628 --- /dev/null +++ b/va108xx/src/uarta/irq_enb.rs @@ -0,0 +1,130 @@ +#[doc = "Register `IRQ_ENB` reader"] +pub type R = crate::R; +#[doc = "Register `IRQ_ENB` writer"] +pub type W = crate::W; +#[doc = "Field `IRQ_RX` reader - RX Interrupt"] +pub type IrqRxR = crate::BitReader; +#[doc = "Field `IRQ_RX` writer - RX Interrupt"] +pub type IrqRxW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_RX_STATUS` reader - RX Status Interrupt"] +pub type IrqRxStatusR = crate::BitReader; +#[doc = "Field `IRQ_RX_STATUS` writer - RX Status Interrupt"] +pub type IrqRxStatusW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_RX_TO` reader - RX Timeout Interrupt"] +pub type IrqRxToR = crate::BitReader; +#[doc = "Field `IRQ_RX_TO` writer - RX Timeout Interrupt"] +pub type IrqRxToW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_TX` reader - TX Interrupt"] +pub type IrqTxR = crate::BitReader; +#[doc = "Field `IRQ_TX` writer - TX Interrupt"] +pub type IrqTxW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_TX_STATUS` reader - TX Status Interrupt"] +pub type IrqTxStatusR = crate::BitReader; +#[doc = "Field `IRQ_TX_STATUS` writer - TX Status Interrupt"] +pub type IrqTxStatusW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_TX_EMPTY` reader - TX Empty Interrupt"] +pub type IrqTxEmptyR = crate::BitReader; +#[doc = "Field `IRQ_TX_EMPTY` writer - TX Empty Interrupt"] +pub type IrqTxEmptyW<'a, REG> = crate::BitWriter<'a, REG>; +#[doc = "Field `IRQ_TX_CTS` reader - TX CTS Change Interrupt"] +pub type IrqTxCtsR = crate::BitReader; +#[doc = "Field `IRQ_TX_CTS` writer - TX CTS Change Interrupt"] +pub type IrqTxCtsW<'a, REG> = crate::BitWriter<'a, REG>; +impl R { + #[doc = "Bit 0 - RX Interrupt"] + #[inline(always)] + pub fn irq_rx(&self) -> IrqRxR { + IrqRxR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - RX Status Interrupt"] + #[inline(always)] + pub fn irq_rx_status(&self) -> IrqRxStatusR { + IrqRxStatusR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - RX Timeout Interrupt"] + #[inline(always)] + pub fn irq_rx_to(&self) -> IrqRxToR { + IrqRxToR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 4 - TX Interrupt"] + #[inline(always)] + pub fn irq_tx(&self) -> IrqTxR { + IrqTxR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - TX Status Interrupt"] + #[inline(always)] + pub fn irq_tx_status(&self) -> IrqTxStatusR { + IrqTxStatusR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - TX Empty Interrupt"] + #[inline(always)] + pub fn irq_tx_empty(&self) -> IrqTxEmptyR { + IrqTxEmptyR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - TX CTS Change Interrupt"] + #[inline(always)] + pub fn irq_tx_cts(&self) -> IrqTxCtsR { + IrqTxCtsR::new(((self.bits >> 7) & 1) != 0) + } +} +impl W { + #[doc = "Bit 0 - RX Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_rx(&mut self) -> IrqRxW { + IrqRxW::new(self, 0) + } + #[doc = "Bit 1 - RX Status Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_rx_status(&mut self) -> IrqRxStatusW { + IrqRxStatusW::new(self, 1) + } + #[doc = "Bit 2 - RX Timeout Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_rx_to(&mut self) -> IrqRxToW { + IrqRxToW::new(self, 2) + } + #[doc = "Bit 4 - TX Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_tx(&mut self) -> IrqTxW { + IrqTxW::new(self, 4) + } + #[doc = "Bit 5 - TX Status Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_tx_status(&mut self) -> IrqTxStatusW { + IrqTxStatusW::new(self, 5) + } + #[doc = "Bit 6 - TX Empty Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_tx_empty(&mut self) -> IrqTxEmptyW { + IrqTxEmptyW::new(self, 6) + } + #[doc = "Bit 7 - TX CTS Change Interrupt"] + #[inline(always)] + #[must_use] + pub fn irq_tx_cts(&mut self) -> IrqTxCtsW { + IrqTxCtsW::new(self, 7) + } +} +#[doc = "IRQ Enable Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`irq_enb::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`irq_enb::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct IrqEnbSpec; +impl crate::RegisterSpec for IrqEnbSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`irq_enb::R`](R) reader structure"] +impl crate::Readable for IrqEnbSpec {} +#[doc = "`write(|w| ..)` method takes [`irq_enb::W`](W) writer structure"] +impl crate::Writable for IrqEnbSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets IRQ_ENB to value 0"] +impl crate::Resettable for IrqEnbSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/perid.rs b/va108xx/src/uarta/perid.rs new file mode 100644 index 0000000..fe8dddc --- /dev/null +++ b/va108xx/src/uarta/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0012_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0012_07e1; +} diff --git a/va108xx/src/uarta/rxfifoirqtrg.rs b/va108xx/src/uarta/rxfifoirqtrg.rs new file mode 100644 index 0000000..46124d5 --- /dev/null +++ b/va108xx/src/uarta/rxfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `RXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Rx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxfifoirqtrgSpec; +impl crate::RegisterSpec for RxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for RxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`rxfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for RxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RXFIFOIRQTRG to value 0"] +impl crate::Resettable for RxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/rxfifortstrg.rs b/va108xx/src/uarta/rxfifortstrg.rs new file mode 100644 index 0000000..dd8afea --- /dev/null +++ b/va108xx/src/uarta/rxfifortstrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `RXFIFORTSTRG` reader"] +pub type R = crate::R; +#[doc = "Register `RXFIFORTSTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Rx FIFO RTS Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxfifortstrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`rxfifortstrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxfifortstrgSpec; +impl crate::RegisterSpec for RxfifortstrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxfifortstrg::R`](R) reader structure"] +impl crate::Readable for RxfifortstrgSpec {} +#[doc = "`write(|w| ..)` method takes [`rxfifortstrg::W`](W) writer structure"] +impl crate::Writable for RxfifortstrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets RXFIFORTSTRG to value 0"] +impl crate::Resettable for RxfifortstrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/rxstatus.rs b/va108xx/src/uarta/rxstatus.rs new file mode 100644 index 0000000..c519eb8 --- /dev/null +++ b/va108xx/src/uarta/rxstatus.rs @@ -0,0 +1,92 @@ +#[doc = "Register `RXSTATUS` reader"] +pub type R = crate::R; +#[doc = "Field `RDAVL` reader - Read Data Available"] +pub type RdavlR = crate::BitReader; +#[doc = "Field `RDNFULL` reader - Read Fifo NOT Full"] +pub type RdnfullR = crate::BitReader; +#[doc = "Field `RXBUSY` reader - RX Busy Receiving"] +pub type RxbusyR = crate::BitReader; +#[doc = "Field `RXTO` reader - RX Receive Timeout"] +pub type RxtoR = crate::BitReader; +#[doc = "Field `RXOVR` reader - Read Fifo Overflow"] +pub type RxovrR = crate::BitReader; +#[doc = "Field `RXFRM` reader - RX Framing Error"] +pub type RxfrmR = crate::BitReader; +#[doc = "Field `RXPAR` reader - RX Parity Error"] +pub type RxparR = crate::BitReader; +#[doc = "Field `RXBRK` reader - RX Break Error"] +pub type RxbrkR = crate::BitReader; +#[doc = "Field `RXBUSYBRK` reader - RX Busy Receiving Break"] +pub type RxbusybrkR = crate::BitReader; +#[doc = "Field `RXADDR9` reader - Address Match for 9 bit mode"] +pub type Rxaddr9R = crate::BitReader; +#[doc = "Field `RXRTSN` reader - RX RTSn Output Value"] +pub type RxrtsnR = crate::BitReader; +impl R { + #[doc = "Bit 0 - Read Data Available"] + #[inline(always)] + pub fn rdavl(&self) -> RdavlR { + RdavlR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Read Fifo NOT Full"] + #[inline(always)] + pub fn rdnfull(&self) -> RdnfullR { + RdnfullR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - RX Busy Receiving"] + #[inline(always)] + pub fn rxbusy(&self) -> RxbusyR { + RxbusyR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - RX Receive Timeout"] + #[inline(always)] + pub fn rxto(&self) -> RxtoR { + RxtoR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 4 - Read Fifo Overflow"] + #[inline(always)] + pub fn rxovr(&self) -> RxovrR { + RxovrR::new(((self.bits >> 4) & 1) != 0) + } + #[doc = "Bit 5 - RX Framing Error"] + #[inline(always)] + pub fn rxfrm(&self) -> RxfrmR { + RxfrmR::new(((self.bits >> 5) & 1) != 0) + } + #[doc = "Bit 6 - RX Parity Error"] + #[inline(always)] + pub fn rxpar(&self) -> RxparR { + RxparR::new(((self.bits >> 6) & 1) != 0) + } + #[doc = "Bit 7 - RX Break Error"] + #[inline(always)] + pub fn rxbrk(&self) -> RxbrkR { + RxbrkR::new(((self.bits >> 7) & 1) != 0) + } + #[doc = "Bit 8 - RX Busy Receiving Break"] + #[inline(always)] + pub fn rxbusybrk(&self) -> RxbusybrkR { + RxbusybrkR::new(((self.bits >> 8) & 1) != 0) + } + #[doc = "Bit 9 - Address Match for 9 bit mode"] + #[inline(always)] + pub fn rxaddr9(&self) -> Rxaddr9R { + Rxaddr9R::new(((self.bits >> 9) & 1) != 0) + } + #[doc = "Bit 15 - RX RTSn Output Value"] + #[inline(always)] + pub fn rxrtsn(&self) -> RxrtsnR { + RxrtsnR::new(((self.bits >> 15) & 1) != 0) + } +} +#[doc = "Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`rxstatus::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct RxstatusSpec; +impl crate::RegisterSpec for RxstatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`rxstatus::R`](R) reader structure"] +impl crate::Readable for RxstatusSpec {} +#[doc = "`reset()` method sets RXSTATUS to value 0"] +impl crate::Resettable for RxstatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/state.rs b/va108xx/src/uarta/state.rs new file mode 100644 index 0000000..17ec5bc --- /dev/null +++ b/va108xx/src/uarta/state.rs @@ -0,0 +1,18 @@ +#[doc = "Register `STATE` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Internal STATE of UART Controller\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`state::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct StateSpec; +impl crate::RegisterSpec for StateSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`state::R`](R) reader structure"] +impl crate::Readable for StateSpec {} +#[doc = "`reset()` method sets STATE to value 0"] +impl crate::Resettable for StateSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/txbreak.rs b/va108xx/src/uarta/txbreak.rs new file mode 100644 index 0000000..69a167f --- /dev/null +++ b/va108xx/src/uarta/txbreak.rs @@ -0,0 +1,23 @@ +#[doc = "Register `TXBREAK` writer"] +pub type W = crate::W; +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 = "Break Transmit Register\n\nYou can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txbreak::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxbreakSpec; +impl crate::RegisterSpec for TxbreakSpec { + type Ux = u32; +} +#[doc = "`write(|w| ..)` method takes [`txbreak::W`](W) writer structure"] +impl crate::Writable for TxbreakSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TXBREAK to value 0"] +impl crate::Resettable for TxbreakSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/txfifoirqtrg.rs b/va108xx/src/uarta/txfifoirqtrg.rs new file mode 100644 index 0000000..0d13e54 --- /dev/null +++ b/va108xx/src/uarta/txfifoirqtrg.rs @@ -0,0 +1,27 @@ +#[doc = "Register `TXFIFOIRQTRG` reader"] +pub type R = crate::R; +#[doc = "Register `TXFIFOIRQTRG` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Tx FIFO IRQ Trigger Level\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txfifoirqtrg::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`txfifoirqtrg::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxfifoirqtrgSpec; +impl crate::RegisterSpec for TxfifoirqtrgSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`txfifoirqtrg::R`](R) reader structure"] +impl crate::Readable for TxfifoirqtrgSpec {} +#[doc = "`write(|w| ..)` method takes [`txfifoirqtrg::W`](W) writer structure"] +impl crate::Writable for TxfifoirqtrgSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets TXFIFOIRQTRG to value 0"] +impl crate::Resettable for TxfifoirqtrgSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/uarta/txstatus.rs b/va108xx/src/uarta/txstatus.rs new file mode 100644 index 0000000..42852d9 --- /dev/null +++ b/va108xx/src/uarta/txstatus.rs @@ -0,0 +1,50 @@ +#[doc = "Register `TXSTATUS` reader"] +pub type R = crate::R; +#[doc = "Field `WRRDY` reader - Write Fifo NOT Full"] +pub type WrrdyR = crate::BitReader; +#[doc = "Field `WRBUSY` reader - Write Fifo Full"] +pub type WrbusyR = crate::BitReader; +#[doc = "Field `TXBUSY` reader - TX Busy Transmitting"] +pub type TxbusyR = crate::BitReader; +#[doc = "Field `WRLOST` reader - Write Data Lost (Fifo Overflow)"] +pub type WrlostR = crate::BitReader; +#[doc = "Field `TXCTSN` reader - TX CTSn Input Value"] +pub type TxctsnR = crate::BitReader; +impl R { + #[doc = "Bit 0 - Write Fifo NOT Full"] + #[inline(always)] + pub fn wrrdy(&self) -> WrrdyR { + WrrdyR::new((self.bits & 1) != 0) + } + #[doc = "Bit 1 - Write Fifo Full"] + #[inline(always)] + pub fn wrbusy(&self) -> WrbusyR { + WrbusyR::new(((self.bits >> 1) & 1) != 0) + } + #[doc = "Bit 2 - TX Busy Transmitting"] + #[inline(always)] + pub fn txbusy(&self) -> TxbusyR { + TxbusyR::new(((self.bits >> 2) & 1) != 0) + } + #[doc = "Bit 3 - Write Data Lost (Fifo Overflow)"] + #[inline(always)] + pub fn wrlost(&self) -> WrlostR { + WrlostR::new(((self.bits >> 3) & 1) != 0) + } + #[doc = "Bit 15 - TX CTSn Input Value"] + #[inline(always)] + pub fn txctsn(&self) -> TxctsnR { + TxctsnR::new(((self.bits >> 15) & 1) != 0) + } +} +#[doc = "Status Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`txstatus::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct TxstatusSpec; +impl crate::RegisterSpec for TxstatusSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`txstatus::R`](R) reader structure"] +impl crate::Readable for TxstatusSpec {} +#[doc = "`reset()` method sets TXSTATUS to value 0"] +impl crate::Resettable for TxstatusSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility.rs b/va108xx/src/utility.rs new file mode 100644 index 0000000..66aba28 --- /dev/null +++ b/va108xx/src/utility.rs @@ -0,0 +1,175 @@ +#[repr(C)] +#[doc = "Register block"] +pub struct RegisterBlock { + synd_data0: SyndData0, + synd_data1: SyndData1, + synd_synd: SyndSynd, + synd_enc_32: SyndEnc32, + synd_check_32_data: SyndCheck32Data, + synd_check_32_synd: SyndCheck32Synd, + synd_enc_64: SyndEnc64, + synd_check_64_data0: SyndCheck64Data0, + synd_check_64_data1: SyndCheck64Data1, + synd_check_64_synd: SyndCheck64Synd, + synd_enc_32_52: SyndEnc32_52, + synd_check_32_52_data: SyndCheck32_52Data, + synd_check_32_52_synd: SyndCheck32_52Synd, + _reserved13: [u8; 0x0fc8], + perid: Perid, +} +impl RegisterBlock { + #[doc = "0x00 - Synd Data 0 Register"] + #[inline(always)] + pub const fn synd_data0(&self) -> &SyndData0 { + &self.synd_data0 + } + #[doc = "0x04 - Synd Data 1 Register"] + #[inline(always)] + pub const fn synd_data1(&self) -> &SyndData1 { + &self.synd_data1 + } + #[doc = "0x08 - Synd Parity Register"] + #[inline(always)] + pub const fn synd_synd(&self) -> &SyndSynd { + &self.synd_synd + } + #[doc = "0x0c - Synd 32 bit Encoded Syndrome"] + #[inline(always)] + pub const fn synd_enc_32(&self) -> &SyndEnc32 { + &self.synd_enc_32 + } + #[doc = "0x10 - Synd 32 bit Corrected Data"] + #[inline(always)] + pub const fn synd_check_32_data(&self) -> &SyndCheck32Data { + &self.synd_check_32_data + } + #[doc = "0x14 - Synd 32 bit Corrected Syndrome and Status"] + #[inline(always)] + pub const fn synd_check_32_synd(&self) -> &SyndCheck32Synd { + &self.synd_check_32_synd + } + #[doc = "0x18 - Synd 64 bit Encoded Syndrome"] + #[inline(always)] + pub const fn synd_enc_64(&self) -> &SyndEnc64 { + &self.synd_enc_64 + } + #[doc = "0x1c - Synd 64 bit Corrected Data 0"] + #[inline(always)] + pub const fn synd_check_64_data0(&self) -> &SyndCheck64Data0 { + &self.synd_check_64_data0 + } + #[doc = "0x20 - Synd 64 bit Corrected Data 1"] + #[inline(always)] + pub const fn synd_check_64_data1(&self) -> &SyndCheck64Data1 { + &self.synd_check_64_data1 + } + #[doc = "0x24 - Synd 64 bit Corrected Parity and Status"] + #[inline(always)] + pub const fn synd_check_64_synd(&self) -> &SyndCheck64Synd { + &self.synd_check_64_synd + } + #[doc = "0x28 - Synd 32/52 bit Encoded Syndrome"] + #[inline(always)] + pub const fn synd_enc_32_52(&self) -> &SyndEnc32_52 { + &self.synd_enc_32_52 + } + #[doc = "0x2c - Synd 32/52 bit Corrected Data"] + #[inline(always)] + pub const fn synd_check_32_52_data(&self) -> &SyndCheck32_52Data { + &self.synd_check_32_52_data + } + #[doc = "0x30 - Synd 32/52 bit Corrected Syndrome and Status"] + #[inline(always)] + pub const fn synd_check_32_52_synd(&self) -> &SyndCheck32_52Synd { + &self.synd_check_32_52_synd + } + #[doc = "0xffc - Peripheral ID Register"] + #[inline(always)] + pub const fn perid(&self) -> &Perid { + &self.perid + } +} +#[doc = "SYND_DATA0 (rw) register accessor: Synd Data 0 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_data0::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_data0::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_data0`] +module"] +#[doc(alias = "SYND_DATA0")] +pub type SyndData0 = crate::Reg; +#[doc = "Synd Data 0 Register"] +pub mod synd_data0; +#[doc = "SYND_DATA1 (rw) register accessor: Synd Data 1 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_data1::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_data1::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_data1`] +module"] +#[doc(alias = "SYND_DATA1")] +pub type SyndData1 = crate::Reg; +#[doc = "Synd Data 1 Register"] +pub mod synd_data1; +#[doc = "SYND_SYND (rw) register accessor: Synd Parity Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_synd::R`]. You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_synd::W`]. You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_synd`] +module"] +#[doc(alias = "SYND_SYND")] +pub type SyndSynd = crate::Reg; +#[doc = "Synd Parity Register"] +pub mod synd_synd; +#[doc = "SYND_ENC_32 (r) register accessor: Synd 32 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_32::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_enc_32`] +module"] +#[doc(alias = "SYND_ENC_32")] +pub type SyndEnc32 = crate::Reg; +#[doc = "Synd 32 bit Encoded Syndrome"] +pub mod synd_enc_32; +#[doc = "SYND_CHECK_32_DATA (r) register accessor: Synd 32 bit Corrected Data\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_data::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_32_data`] +module"] +#[doc(alias = "SYND_CHECK_32_DATA")] +pub type SyndCheck32Data = crate::Reg; +#[doc = "Synd 32 bit Corrected Data"] +pub mod synd_check_32_data; +#[doc = "SYND_CHECK_32_SYND (r) register accessor: Synd 32 bit Corrected Syndrome and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_synd::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_32_synd`] +module"] +#[doc(alias = "SYND_CHECK_32_SYND")] +pub type SyndCheck32Synd = crate::Reg; +#[doc = "Synd 32 bit Corrected Syndrome and Status"] +pub mod synd_check_32_synd; +#[doc = "SYND_ENC_64 (r) register accessor: Synd 64 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_64::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_enc_64`] +module"] +#[doc(alias = "SYND_ENC_64")] +pub type SyndEnc64 = crate::Reg; +#[doc = "Synd 64 bit Encoded Syndrome"] +pub mod synd_enc_64; +#[doc = "SYND_CHECK_64_DATA0 (r) register accessor: Synd 64 bit Corrected Data 0\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_data0::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_64_data0`] +module"] +#[doc(alias = "SYND_CHECK_64_DATA0")] +pub type SyndCheck64Data0 = crate::Reg; +#[doc = "Synd 64 bit Corrected Data 0"] +pub mod synd_check_64_data0; +#[doc = "SYND_CHECK_64_DATA1 (r) register accessor: Synd 64 bit Corrected Data 1\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_data1::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_64_data1`] +module"] +#[doc(alias = "SYND_CHECK_64_DATA1")] +pub type SyndCheck64Data1 = crate::Reg; +#[doc = "Synd 64 bit Corrected Data 1"] +pub mod synd_check_64_data1; +#[doc = "SYND_CHECK_64_SYND (r) register accessor: Synd 64 bit Corrected Parity and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_synd::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_64_synd`] +module"] +#[doc(alias = "SYND_CHECK_64_SYND")] +pub type SyndCheck64Synd = crate::Reg; +#[doc = "Synd 64 bit Corrected Parity and Status"] +pub mod synd_check_64_synd; +#[doc = "SYND_ENC_32_52 (r) register accessor: Synd 32/52 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_32_52::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_enc_32_52`] +module"] +#[doc(alias = "SYND_ENC_32_52")] +pub type SyndEnc32_52 = crate::Reg; +#[doc = "Synd 32/52 bit Encoded Syndrome"] +pub mod synd_enc_32_52; +#[doc = "SYND_CHECK_32_52_DATA (r) register accessor: Synd 32/52 bit Corrected Data\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_52_data::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_32_52_data`] +module"] +#[doc(alias = "SYND_CHECK_32_52_DATA")] +pub type SyndCheck32_52Data = crate::Reg; +#[doc = "Synd 32/52 bit Corrected Data"] +pub mod synd_check_32_52_data; +#[doc = "SYND_CHECK_32_52_SYND (r) register accessor: Synd 32/52 bit Corrected Syndrome and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_52_synd::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@synd_check_32_52_synd`] +module"] +#[doc(alias = "SYND_CHECK_32_52_SYND")] +pub type SyndCheck32_52Synd = crate::Reg; +#[doc = "Synd 32/52 bit Corrected Syndrome and Status"] +pub mod synd_check_32_52_synd; +#[doc = "PERID (r) register accessor: Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`]. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@perid`] +module"] +#[doc(alias = "PERID")] +pub type Perid = crate::Reg; +#[doc = "Peripheral ID Register"] +pub mod perid; diff --git a/va108xx/src/utility/perid.rs b/va108xx/src/utility/perid.rs new file mode 100644 index 0000000..7b4aa79 --- /dev/null +++ b/va108xx/src/utility/perid.rs @@ -0,0 +1,18 @@ +#[doc = "Register `PERID` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Peripheral ID Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`perid::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct PeridSpec; +impl crate::RegisterSpec for PeridSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`perid::R`](R) reader structure"] +impl crate::Readable for PeridSpec {} +#[doc = "`reset()` method sets PERID to value 0x0082_07e1"] +impl crate::Resettable for PeridSpec { + const RESET_VALUE: u32 = 0x0082_07e1; +} diff --git a/va108xx/src/utility/synd_check_32_52_data.rs b/va108xx/src/utility/synd_check_32_52_data.rs new file mode 100644 index 0000000..4eda35c --- /dev/null +++ b/va108xx/src/utility/synd_check_32_52_data.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_32_52_DATA` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32/52 bit Corrected Data\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_52_data::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck32_52DataSpec; +impl crate::RegisterSpec for SyndCheck32_52DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_32_52_data::R`](R) reader structure"] +impl crate::Readable for SyndCheck32_52DataSpec {} +#[doc = "`reset()` method sets SYND_CHECK_32_52_DATA to value 0"] +impl crate::Resettable for SyndCheck32_52DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_32_52_synd.rs b/va108xx/src/utility/synd_check_32_52_synd.rs new file mode 100644 index 0000000..eb4dc79 --- /dev/null +++ b/va108xx/src/utility/synd_check_32_52_synd.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_32_52_SYND` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32/52 bit Corrected Syndrome and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_52_synd::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck32_52SyndSpec; +impl crate::RegisterSpec for SyndCheck32_52SyndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_32_52_synd::R`](R) reader structure"] +impl crate::Readable for SyndCheck32_52SyndSpec {} +#[doc = "`reset()` method sets SYND_CHECK_32_52_SYND to value 0"] +impl crate::Resettable for SyndCheck32_52SyndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_32_data.rs b/va108xx/src/utility/synd_check_32_data.rs new file mode 100644 index 0000000..544e1be --- /dev/null +++ b/va108xx/src/utility/synd_check_32_data.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_32_DATA` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32 bit Corrected Data\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_data::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck32DataSpec; +impl crate::RegisterSpec for SyndCheck32DataSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_32_data::R`](R) reader structure"] +impl crate::Readable for SyndCheck32DataSpec {} +#[doc = "`reset()` method sets SYND_CHECK_32_DATA to value 0"] +impl crate::Resettable for SyndCheck32DataSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_32_synd.rs b/va108xx/src/utility/synd_check_32_synd.rs new file mode 100644 index 0000000..78393af --- /dev/null +++ b/va108xx/src/utility/synd_check_32_synd.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_32_SYND` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32 bit Corrected Syndrome and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_32_synd::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck32SyndSpec; +impl crate::RegisterSpec for SyndCheck32SyndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_32_synd::R`](R) reader structure"] +impl crate::Readable for SyndCheck32SyndSpec {} +#[doc = "`reset()` method sets SYND_CHECK_32_SYND to value 0"] +impl crate::Resettable for SyndCheck32SyndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_64_data0.rs b/va108xx/src/utility/synd_check_64_data0.rs new file mode 100644 index 0000000..294925a --- /dev/null +++ b/va108xx/src/utility/synd_check_64_data0.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_64_DATA0` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 64 bit Corrected Data 0\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_data0::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck64Data0Spec; +impl crate::RegisterSpec for SyndCheck64Data0Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_64_data0::R`](R) reader structure"] +impl crate::Readable for SyndCheck64Data0Spec {} +#[doc = "`reset()` method sets SYND_CHECK_64_DATA0 to value 0"] +impl crate::Resettable for SyndCheck64Data0Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_64_data1.rs b/va108xx/src/utility/synd_check_64_data1.rs new file mode 100644 index 0000000..f5c1ef2 --- /dev/null +++ b/va108xx/src/utility/synd_check_64_data1.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_64_DATA1` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 64 bit Corrected Data 1\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_data1::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck64Data1Spec; +impl crate::RegisterSpec for SyndCheck64Data1Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_64_data1::R`](R) reader structure"] +impl crate::Readable for SyndCheck64Data1Spec {} +#[doc = "`reset()` method sets SYND_CHECK_64_DATA1 to value 0"] +impl crate::Resettable for SyndCheck64Data1Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_check_64_synd.rs b/va108xx/src/utility/synd_check_64_synd.rs new file mode 100644 index 0000000..4b216d0 --- /dev/null +++ b/va108xx/src/utility/synd_check_64_synd.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_CHECK_64_SYND` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 64 bit Corrected Parity and Status\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_check_64_synd::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndCheck64SyndSpec; +impl crate::RegisterSpec for SyndCheck64SyndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_check_64_synd::R`](R) reader structure"] +impl crate::Readable for SyndCheck64SyndSpec {} +#[doc = "`reset()` method sets SYND_CHECK_64_SYND to value 0"] +impl crate::Resettable for SyndCheck64SyndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_data0.rs b/va108xx/src/utility/synd_data0.rs new file mode 100644 index 0000000..5bb9d05 --- /dev/null +++ b/va108xx/src/utility/synd_data0.rs @@ -0,0 +1,27 @@ +#[doc = "Register `SYND_DATA0` reader"] +pub type R = crate::R; +#[doc = "Register `SYND_DATA0` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Synd Data 0 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_data0::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_data0::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndData0Spec; +impl crate::RegisterSpec for SyndData0Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_data0::R`](R) reader structure"] +impl crate::Readable for SyndData0Spec {} +#[doc = "`write(|w| ..)` method takes [`synd_data0::W`](W) writer structure"] +impl crate::Writable for SyndData0Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets SYND_DATA0 to value 0"] +impl crate::Resettable for SyndData0Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_data1.rs b/va108xx/src/utility/synd_data1.rs new file mode 100644 index 0000000..6d226f5 --- /dev/null +++ b/va108xx/src/utility/synd_data1.rs @@ -0,0 +1,27 @@ +#[doc = "Register `SYND_DATA1` reader"] +pub type R = crate::R; +#[doc = "Register `SYND_DATA1` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Synd Data 1 Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_data1::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_data1::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndData1Spec; +impl crate::RegisterSpec for SyndData1Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_data1::R`](R) reader structure"] +impl crate::Readable for SyndData1Spec {} +#[doc = "`write(|w| ..)` method takes [`synd_data1::W`](W) writer structure"] +impl crate::Writable for SyndData1Spec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets SYND_DATA1 to value 0"] +impl crate::Resettable for SyndData1Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_enc_32.rs b/va108xx/src/utility/synd_enc_32.rs new file mode 100644 index 0000000..eff6f93 --- /dev/null +++ b/va108xx/src/utility/synd_enc_32.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_ENC_32` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_32::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndEnc32Spec; +impl crate::RegisterSpec for SyndEnc32Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_enc_32::R`](R) reader structure"] +impl crate::Readable for SyndEnc32Spec {} +#[doc = "`reset()` method sets SYND_ENC_32 to value 0"] +impl crate::Resettable for SyndEnc32Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_enc_32_52.rs b/va108xx/src/utility/synd_enc_32_52.rs new file mode 100644 index 0000000..e88ad29 --- /dev/null +++ b/va108xx/src/utility/synd_enc_32_52.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_ENC_32_52` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 32/52 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_32_52::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndEnc32_52Spec; +impl crate::RegisterSpec for SyndEnc32_52Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_enc_32_52::R`](R) reader structure"] +impl crate::Readable for SyndEnc32_52Spec {} +#[doc = "`reset()` method sets SYND_ENC_32_52 to value 0"] +impl crate::Resettable for SyndEnc32_52Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_enc_64.rs b/va108xx/src/utility/synd_enc_64.rs new file mode 100644 index 0000000..61c5730 --- /dev/null +++ b/va108xx/src/utility/synd_enc_64.rs @@ -0,0 +1,18 @@ +#[doc = "Register `SYND_ENC_64` reader"] +pub type R = crate::R; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +#[doc = "Synd 64 bit Encoded Syndrome\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_enc_64::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndEnc64Spec; +impl crate::RegisterSpec for SyndEnc64Spec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_enc_64::R`](R) reader structure"] +impl crate::Readable for SyndEnc64Spec {} +#[doc = "`reset()` method sets SYND_ENC_64 to value 0"] +impl crate::Resettable for SyndEnc64Spec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/src/utility/synd_synd.rs b/va108xx/src/utility/synd_synd.rs new file mode 100644 index 0000000..ec2f17f --- /dev/null +++ b/va108xx/src/utility/synd_synd.rs @@ -0,0 +1,27 @@ +#[doc = "Register `SYND_SYND` reader"] +pub type R = crate::R; +#[doc = "Register `SYND_SYND` writer"] +pub type W = crate::W; +impl core::fmt::Debug for R { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.bits()) + } +} +impl W {} +#[doc = "Synd Parity Register\n\nYou can [`read`](crate::generic::Reg::read) this register and get [`synd_synd::R`](R). You can [`reset`](crate::generic::Reg::reset), [`write`](crate::generic::Reg::write), [`write_with_zero`](crate::generic::Reg::write_with_zero) this register using [`synd_synd::W`](W). You can also [`modify`](crate::generic::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] +pub struct SyndSyndSpec; +impl crate::RegisterSpec for SyndSyndSpec { + type Ux = u32; +} +#[doc = "`read()` method returns [`synd_synd::R`](R) reader structure"] +impl crate::Readable for SyndSyndSpec {} +#[doc = "`write(|w| ..)` method takes [`synd_synd::W`](W) writer structure"] +impl crate::Writable for SyndSyndSpec { + type Safety = crate::Unsafe; + const ZERO_TO_MODIFY_FIELDS_BITMAP: u32 = 0; + const ONE_TO_MODIFY_FIELDS_BITMAP: u32 = 0; +} +#[doc = "`reset()` method sets SYND_SYND to value 0"] +impl crate::Resettable for SyndSyndSpec { + const RESET_VALUE: u32 = 0; +} diff --git a/va108xx/svd/va108xx-orig.svd b/va108xx/svd/va108xx-orig.svd new file mode 100644 index 0000000..3b956de --- /dev/null +++ b/va108xx/svd/va108xx-orig.svd @@ -0,0 +1,2743 @@ + + + VORAGO TECHNOLOGIES + SST + va108xx + M0 + 1.1 + ARM 32-bit Cortex-M0 Microcontroller based device, CPU clock up to 50MHz + + VORAGO Technologies \n +\n +----------------------------------------------------------------------------\n + Copyright (c) 2013-2016 VORAGO Technologies\n +\n + BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND BY ALL THE TERMS\n + AND CONDITIONS OF THE VORAGO TECHNOLOGIES END USER LICENSE AGREEMENT. \n +\n + THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\n + OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\n + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\n + VORAGO TECHNOLOGIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE\n + FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\n + + + CM0 + r0p0 + little + false + false + 2 + false + + system_VA108xx + VOR_ + 8 + 32 + + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + SYSCONFIG + 1.0 + System Configuration Peripheral + 0x40000000 + + 0 + 0x00001000 + registers + + + + RST_STAT + System Reset Status + 0x000 + read-write + 0x00000001 + + + POR + Power On Reset Status + [0:0] + + + EXTRST + External Reset Status + [1:1] + + + SYSRSTREQ + SYSRESETREQ Reset Status + [2:2] + + + LOOKUP + LOOKUP Reset Status + [3:3] + + + WATCHDOG + WATCHDOG Reset Status + [4:4] + + + MEMERR + Memory Error Reset Status + [5:5] + + + + + RST_CNTL_ROM + ROM Reset Control + 0x004 + 0x0000001F + + + RST_CNTL_RAM + RAM Reset Control + 0x008 + 0x0000001F + + + ROM_PROT + ROM Protection Configuration + 0x00C + 0x00000001 + + + WREN + ROM Write Enable Bit + [0:0] + + + + + ROM_SCRUB + ROM Scrub Period Configuration + 0x010 + read-write + 0x00000000 + + + VALUE + Counter divide value + [23:0] + + + RESET + Reset Counter + [31:31] + write-only + + oneToClear + + + + + + RAM_SCRUB + RAM Scrub Period Configuration + 0x014 + + + ROM_TRAP_ADDR + ROM Trap Address + 0x018 + 0x00000000 + + + ADDR + Trap Address Match Bits + [15:2] + + + ENABLE + Trap Enable Bit + [31:31] + + + + + ROM_TRAP_SYND + ROM Trap Syndrome + 0x01C + 0x00000000 + + + SYND + Trap Syndrom Bits + [19:0] + + + + + RAM_TRAP_ADDR + RAM Trap Address + 0x020 + + + RAM_TRAP_SYND + RAM Trap Syndrome + 0x024 + + + IRQ_ENB + Enable EDAC Error Interrupt Register + 0x028 + read-write + 0x00000000 + + + RAMSBE + RAM Single Bit Interrupt + [0:0] + + + RAMMBE + RAM Multi Bit Interrupt + [1:1] + + + ROMSBE + ROM Single Bit Interrupt + [2:2] + + + ROMMBE + ROM Multi Bit Interrupt + [3:3] + + + + + IRQ_RAW + Raw EDAC Error Interrupt Status + 0x02C + read-only + 0x00000000 + + + IRQ_END + Enabled EDAC Error Interrupt Status + 0x030 + read-only + 0x00000000 + + + IRQ_CLR + Clear EDAC Error Interrupt Status + 0x034 + write-only + 0x00000000 + + oneToClear + + + + RAM_SBE + Count of RAM EDAC Single Bit Errors + 0x038 + 0x00000000 + + + RAM_MBE + Count of RAM EDAC Multi Bit Errors + 0x03C + + + ROM_SBE + Count of ROM EDAC Single Bit Errors + 0x040 + + + ROM_MBE + Count of ROM EDAC Multi Bit Errors + 0x044 + + + IOCONFIG_CLKDIV0 + IO Configuration Clock Divider Register + 0x048 + read-only + 0x00000000 + + + 7 + 4 + 1-7 + IOCONFIG_CLKDIV%s + IO Configuration Clock Divider Register + 0x04C + 0x00000000 + + + ROM_RETRIES + ROM BOOT Retry count + 0x068 + read-only + 0x00000000 + + + REFRESH_CONFIG + Register Refresh Control + 0x06C + 0x00000000 + + + TIM_RESET + TIM Reset Control + 0x070 + 0xFFFFFFFF + + + TIM_CLK_ENABLE + TIM Enable Control + 0x074 + 0x00000000 + + + PERIPHERAL_RESET + Peripheral Reset Control + 0x078 + 0xFFFFFFFF + + + PERIPHERAL_CLK_ENABLE + Peripheral Enable Control + 0x07C + 0x00000000 + + + LOCKUP_RESET + Lockup Reset Configuration + 0x080 + 0x00000001 + + + LREN + Lockup Reset Enable Bit + [0:0] + + + + + EF_CONFIG + EFuse Config Register + 0xff0 + read-only + 0x00000000 + + + EF_ID + EFuse ID Register + 0xff4 + read-only + 0x00000000 + + + PROCID + Processor ID Register + 0xff8 + read-only + 0x040017e3 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008007e1 + + + + + + + IRQSEL + 1.0 + Interrupt Selector Peripheral + 0x40001000 + + 0 + 0x00001000 + registers + + + OC0 + 0 + + + OC1 + 1 + + + OC2 + 2 + + + OC3 + 3 + + + OC4 + 4 + + + OC5 + 5 + + + OC6 + 6 + + + OC7 + 7 + + + OC8 + 8 + + + OC9 + 9 + + + OC10 + 10 + + + OC11 + 11 + + + OC12 + 12 + + + OC13 + 13 + + + OC14 + 14 + + + OC15 + 15 + + + OC16 + 16 + + + OC17 + 17 + + + OC18 + 18 + + + OC19 + 19 + + + OC20 + 20 + + + OC21 + 21 + + + OC22 + 22 + + + OC23 + 23 + + + OC24 + 24 + + + OC25 + 25 + + + OC26 + 26 + + + OC27 + 27 + + + OC28 + 28 + + + OC29 + 29 + + + OC30 + 30 + + + OC31 + 31 + + + + INT_RAM_SBE + Internal Memory RAM SBE Interrupt Redirect Selection + 0x01C0 + read-write + 0xFFFFFFFF + + + 32 + 4 + PORTA[%s] + PORTA Interrupt Redirect Selection + 0x000 + + + 32 + 4 + PORTB[%s] + PORTB Interrupt Redirect Selection + 0x080 + + + 32 + 4 + TIM[%s] + TIM Interrupt Redirect Selection + 0x100 + + + 4 + 4 + UART[%s] + UART Interrupt Redirect Selection + 0x180 + + + 4 + 4 + SPI[%s] + SPI Interrupt Redirect Selection + 0x190 + + + 4 + 4 + I2C_MS[%s] + Master I2C Interrupt Redirect Selection + 0x01a0 + + + 4 + 4 + I2C_SL[%s] + Slave I2C Interrupt Redirect Selection + 0x01B0 + + + INT_RAM_MBE + Internal Memory RAM MBE Interrupt Redirect Selection + 0x01C4 + + + INT_ROM_SBE + Internal Memory ROM SBE Interrupt Redirect Selection + 0x01C8 + + + INT_ROM_MBE + Internal Memory ROM MBE Interrupt Redirect Selection + 0x01CC + + + TXEV + Processor TXEV Interrupt Redirect Selection + 0x01D0 + + + NMI + NMI Status Register + 0x8f8 + read-only + 0x00000000 + + + ACTIVE + Active + [0:0] + + + + + RXEV + RXEV Status Register + 0x8f4 + + + WATCHDOG + WATCHDOG Status Register + 0x8f0 + + + MERESET + MERESET Status Register + 0x8ec + + + EDBGRQ + EDBGRQ Status Register + 0x8e8 + + + 32 + 4 + IRQS[%s] + Interrupt Status Register + 0x800 + + + PERID + Peripheral ID Register + 0xffc + 32 + read-only + 0x008007e1 + + + + + + + IOCONFIG + 1.0 + IO Pin Configuration Peripheral + 0x40002000 + + 0 + 0x00001000 + registers + + + + 32 + 4 + PORTA[%s] + PORTA Pin Configuration Register + 0x000 + 0x00000000 + + + FLTTYPE + Input Filter Selectoin + [2:0] + + + SYNC + Synchronize to system clock + 0 + + + DIRECT + Direct input, no synchronization + 1 + + + FILTER1 + Require 2 samples to have the same value + 2 + + + FILTER2 + Require 3 samples to have the same value + 3 + + + FILTER3 + Require 4 samples to have the same value + 4 + + + FILTER4 + Require 5 samples to have the same value + 5 + + + + + FLTCLK + Input Filter Clock Selection + [5:3] + + + INVINP + Input Invert Selection + [6:6] + + + IEWO + Input Enable While Output enabled + [7:7] + + + OPENDRN + Output Open Drain Mode + [8:8] + + + INVOUT + Output Invert Selection + [9:9] + + + PLEVEL + Internal Pull up/down level + [10:10] + + + PEN + Enable Internal Pull up/down + [11:11] + + + PWOA + Enable Pull when output active + [12:12] + + + FUNSEL + Pin Function Selection + [15:13] + + + IODIS + IO Pin Disable + [16:16] + + + + + PORTB[%s] + PORTB Pin Configuration Register + 0x0080 + 0x00000800 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008207e1 + + + + + + + UTILITY + 1.0 + Utility Peripheral + 0x40003000 + + 0 + 0x00001000 + registers + + + + SYND_DATA0 + Synd Data 0 Register + 0x000 + 0x00000000 + + + SYND_DATA1 + Synd Data 1 Register + 0x004 + 0x00000000 + + + SYND_SYND + Synd Parity Register + 0x008 + 0x00000000 + + + SYND_ENC_32 + Synd 32 bit Encoded Syndrome + 0x00c + read-only + 0x00000000 + + + SYND_CHECK_32_DATA + Synd 32 bit Corrected Data + 0x010 + read-only + 0x00000000 + + + SYND_CHECK_32_SYND + Synd 32 bit Corrected Syndrome and Status + 0x014 + read-only + 0x00000000 + + + SYND_ENC_64 + Synd 64 bit Encoded Syndrome + 0x018 + read-only + 0x00000000 + + + SYND_CHECK_64_DATA0 + Synd 64 bit Corrected Data 0 + 0x01c + read-only + 0x00000000 + + + SYND_CHECK_64_DATA1 + Synd 64 bit Corrected Data 1 + 0x020 + read-only + 0x00000000 + + + SYND_CHECK_64_SYND + Synd 64 bit Corrected Parity and Status + 0x024 + read-only + 0x00000000 + + + SYND_ENC_32_52 + Synd 32/52 bit Encoded Syndrome + 0x028 + read-only + 0x00000000 + + + SYND_CHECK_32_52_DATA + Synd 32/52 bit Corrected Data + 0x02c + read-only + 0x00000000 + + + SYND_CHECK_32_52_SYND + Synd 32/52 bit Corrected Syndrome and Status + 0x030 + read-only + 0x00000000 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008207e1 + + + + + + + PORTA + 1.0 + GPIO Peripheral + GPIO + 0x50000000 + + 0 + 0x00001000 + registers + + + + + DATAIN + Data In Register + 0x000 + read-only + 0x0000000 + + + 4 + 1 + DATAINBYTE[%s] + Data In Register by Byte + DATAIN + 0x000 + 8 + read-only + 0x0000000 + + + DATAINRAW + Data In Raw Register + 0x004 + 0x0000000 + + + DATAINRAWBYTE[%s] + Data In Raw Register by Byte + DATAINRAW + 0x004 + 0x0000000 + + + DATAOUT + Data Out Register + 0x008 + write-only + 0x0000000 + + + 4 + 1 + DATAOUTBYTE[%s] + Data Out Register by Byte + DATAOUT + 0x008 + 8 + write-only + 0x0000000 + + + DATAOUTRAW + Data Out Register + 0x00c + 0x0000000 + + + DATAOUTRAWBYTE[%s] + Data Out Register by Byte + DATAOUTRAW + 0x00c + 0x0000000 + + + SETOUT + Set Out Register + 0x010 + 0x0000000 + + + SETOUTBYTE[%s] + Set Out Register by Byte + SETOUT + 0x010 + 0x0000000 + + + CLROUT + Clear Out Register + 0x014 + 0x0000000 + + + CLROUTBYTE[%s] + Clear Out Register by Byte + CLROUT + 0x014 + 0x0000000 + + + TOGOUT + Toggle Out Register + 0x018 + 0x0000000 + + + TOGOUTBYTE[%s] + Toggle Out Register by Byte + TOGOUT + 0x018 + 0x0000000 + + + DATAMASK + Data mask Register + 0x01c + 0x0000000 + + + 4 + 1 + DATAMASKBYTE[%s] + Data Out Register by Byte + DATAMASK + 0x01c + 8 + 0x0000000 + + + DIR + Direction Register (1:Output, 0:Input) + 0x020 + 0x0000000 + + + DIRBYTE[%s] + Direction Register by Byte + DIR + 0x020 + 0x0000000 + + + PULSE + Pulse Mode Register + 0x024 + 0x0000000 + + + PULSEBYTE[%s] + Pulse Mode Register by Byte + PULSE + 0x024 + 0x0000000 + + + PULSEBASE + Pulse Base Value Register + 0x028 + 0x0000000 + + + PULSEBASEBYTE[%s] + Pulse Base Mode Register by Byte + PULSEBASE + 0x028 + 0x0000000 + + + DELAY1 + Delay1 Register + 0x02c + 0x0000000 + + + DELAY1BYTE[%s] + Delay1 Register by Byte + DELAY1 + 0x02c + 0x0000000 + + + DELAY2 + Delay2 Register + 0x030 + 32 + read-write + 0x0000000 + + + DELAY2BYTE[%s] + Delay2 Register by Byte + DELAY2 + 0x030 + 0x0000000 + + + IRQ_SEN + Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive) + 0x034 + 0x0000000 + + + IRQ_EDGE + Interrupt Both Edge Register (1:Both Edges, 0:Single Edge) + 0x038 + 0x0000000 + + + IRQ_EVT + Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge) + 0x03c + 0x0000000 + + + IRQ_ENB + Interrupt Enable Register + 0x040 + 0x0000000 + + + IRQ_RAW + Raw Interrupt Status + 0x044 + read-only + 0x0000000 + + + IRQ_END + Masked Interrupt Status + 0x048 + read-only + 0x0000000 + + + EDGE_STATUS + Edge Status Register + 0x04c + read-write + 0x00000000 + + + PERID + Peripheral ID Register + 0xffc + 32 + read-only + 0x001007e1 + + + + + PORTB + 0x50001000 + + + + + TIM0 + 1.0 + Timer/Counter Peripheral + Timer_Counter + 0x40020000 + + 0 + 0x00001000 + registers + + + + + CTRL + Control Register + 0x000 + read-write + + + ENABLE + Counter Enable + [0:0] + + + ACTIVE + Counter Active + [1:1] + read-only + + + AUTO_DISABLE + Auto Disables the counter (set ENABLE to 0) when the count reaches 0 + [2:2] + + + AUTO_DEACTIVATE + Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0 + [3:3] + + + IRQ_ENB + Interrupt Enable + [4:4] + + + STATUS_SEL + Counter Status Selection + [7:5] + + + DONE + Single cycle pulse when the counter reaches 0 + 0 + + + ACTIVE + Returns the counter ACTIVE bit + 1 + + + TOGGLE + Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output. + 2 + + + PWMA + Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE + 3 + + + PWMB + Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE + 4 + + + ENABLED + Returns the counter ENABLED bit + 5 + + + PWMA_ACTIVE + Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0 + 6 + + + + + STATUS_INV + Invert the Output Status + [8:8] + + + REQ_STOP + Stop Request + [9:9] + + + + + RST_VALUE + The value that counter start from after reaching 0. + 0x004 + + + CNT_VALUE + The current value of the counter + 0x008 + + + ENABLE + Alternate access to the Counter ENABLE bit in the CTRL Register + 0x00c + + + ENABLE + Counter Enable + [0:0] + + + + + CSD_CTRL + The Cascade Control Register. Controls the counter external enable signals + 0x010 + + + CSDEN0 + Cascade 0 Enable + [0:0] + + + CSDINV0 + Cascade 0 Invert + [1:1] + + + CSDEN1 + Cascade 1 Enable + [2:2] + + + CSDINV1 + Cascade 1 Invert + [3:3] + + + DCASOP + Dual Cascade Operation (0:AND, 1:OR) + [4:4] + + + CSDTRG0 + Cascade 0 Enabled as Trigger + [6:6] + + + CSDTRG1 + Cascade 1 Enabled as Trigger + [7:7] + + + CSDEN2 + Cascade 2 Enable + [8:8] + + + CSDINV2 + Cascade 2 Invert + [9:9] + + + CSDXXX2 + Cascade 2 test mode + [11:11] + + + + + CASCADE0 + Cascade Enable Selection + 0x014 + + + CASSEL + Cascade Selection + [7:0] + + + + + CASCADE1 + Cascade Enable Selection + 0x018 + + + CASCADE2 + Cascade Enable Selection + 0x01c + + + PWM_VALUE + The Pulse Width Modulation Value + 0x020 + + + PWMA_VALUE + The Pulse Width Modulation ValueA + PWM_VALUE + 0x020 + + + PWMB_VALUE + The Pulse Width Modulation ValueB + 0x024 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001107e1 + + + + + TIM1 + 0x40021000 + + + TIM2 + 0x40022000 + + + TIM3 + 0x40023000 + + + TIM4 + 0x40024000 + + + TIM5 + 0x40025000 + + + TIM6 + 0x40026000 + + + TIM7 + 0x40027000 + + + TIM8 + 0x40028000 + + + TIM9 + 0x40029000 + + + TIM10 + 0x4002a000 + + + TIM11 + 0x4002b000 + + + TIM12 + 0x4002c000 + + + TIM13 + 0x4002d000 + + + TIM14 + 0x4002e000 + + + TIM15 + 0x4002f000 + + + TIM16 + 0x40030000 + + + TIM17 + 0x40031000 + + + TIM18 + 0x40032000 + + + TIM19 + 0x40033000 + + + TIM20 + 0x40034000 + + + TIM21 + 0x40035000 + + + TIM22 + 0x40036000 + + + TIM23 + 0x40037000 + + + + + UARTA + 1.0 + UART Peripheral + UART + 0x40040000 + + 0 + 0x00001000 + registers + + + + + DATA + Data In/Out Register + 0x000 + 0x0000000 + + + ENABLE + Enable Register + 0x004 + 0x0000000 + + + RXENABLE + Rx Enable + [0:0] + + + TXENABLE + Tx Enable + [1:1] + + + + + CTRL + Control Register + 0x008 + 0x0000000 + + + PAREN + Parity Enable + [0:0] + + + PAREVEN + Parity Even/Odd(1/0) + [1:1] + + + PARSTK + Parity Sticky + [2:2] + + + STOPBITS + Stop Bits 1/2(0/1) + [3:3] + + + WORDSIZE + Word Size in Bits 5/6/7/8(00/01/10/11) + [5:4] + + + LOOPBACK + Loopback Enable + [6:6] + + + LOOPBACKBLK + Loopback Block + [7:7] + + + AUTOCTS + Enable Auto CTS mode + [8:8] + + + DEFRTS + Default RTSn value + [9:9] + + + AUTORTS + Enable Auto RTS mode + [10:10] + + + BAUD8 + Enable BAUD8 mode + [11:11] + + + + + CLKSCALE + Clock Scale Register + 0x00c + 0x0000000 + + + FRAC + Fractional Divide (64ths) + [5:0] + + + INT + Integer Divide + [23:6] + + + RESET + Reset Baud Counter + [31:31] + write-only + + + + + RXSTATUS + Status Register + 0x010 + read-only + 0x0000000 + + + RDAVL + Read Data Available + [0:0] + + + RDNFULL + Read Fifo NOT Full + [1:1] + + + RXBUSY + RX Busy Receiving + [2:2] + + + RXTO + RX Receive Timeout + [3:3] + + + RXOVR + Read Fifo Overflow + [4:4] + + + RXFRM + RX Framing Error + [5:5] + + + RXPAR + RX Parity Error + [6:6] + + + RXBRK + RX Break Error + [7:7] + + + RXBUSYBRK + RX Busy Receiving Break + [8:8] + + + RXADDR9 + Address Match for 9 bit mode + [9:9] + + + RXRTSN + RX RTSn Output Value + [15:15] + + + + + TXSTATUS + Status Register + 0x014 + read-only + 0x0000000 + + + WRRDY + Write Fifo NOT Full + [0:0] + + + WRBUSY + Write Fifo Full + [1:1] + + + TXBUSY + TX Busy Transmitting + [2:2] + + + WRLOST + Write Data Lost (Fifo Overflow) + [3:3] + + + TXCTSN + TX CTSn Input Value + [15:15] + + + + + FIFO_CLR + Clear FIFO Register + 0x018 + write-only + 0x0000000 + + + RXSTS + Clear Rx Status + [0:0] + + + TXSTS + Clear Tx Status + [1:1] + + + RXFIFO + Clear Rx FIFO + [2:2] + + + TXFIFO + Clear Tx FIFO + [3:3] + + + + + TXBREAK + Break Transmit Register + 0x01c + write-only + 0x0000000 + + + ADDR9 + Address9 Register + 0x020 + read-write + 0x0000000 + + + ADDR9MASK + Address9 Mask Register + 0x024 + read-write + 0x0000000 + + + IRQ_ENB + IRQ Enable Register + 0x028 + read-write + 0x0000000 + + + IRQ_RX + RX Interrupt + [0:0] + + + IRQ_RX_STATUS + RX Status Interrupt + [1:1] + + + IRQ_RX_TO + RX Timeout Interrupt + [2:2] + + + IRQ_TX + TX Interrupt + [4:4] + + + IRQ_TX_STATUS + TX Status Interrupt + [5:5] + + + IRQ_TX_EMPTY + TX Empty Interrupt + [6:6] + + + IRQ_TX_CTS + TX CTS Change Interrupt + [7:7] + + + + + IRQ_RAW + IRQ Raw Status Register + 0x02c + read-only + 0x0000000 + + + IRQ_END + IRQ Enabled Status Register + 0x030 + read-only + 0x0000000 + + + IRQ_CLR + IRQ Clear Status Register + 0x034 + write-only + 0x0000000 + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x038 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x03c + + + RXFIFORTSTRG + Rx FIFO RTS Trigger Level + 0x040 + + + STATE + Internal STATE of UART Controller + 0x044 + 32 + read-only + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001207e1 + + + + + UARTB + 0x40041000 + + + + + SPIA + 1.0 + SPI Peripheral + SPI + 0x40050000 + + 0 + 0x00001000 + registers + + + + + CTRL0 + Control Register 0 + 0x000 + 0x0000000 + + + SIZE + Data Size(0x3=>4, 0xf=>16) + [3:0] + + + SPO + SPI Clock Polarity + [6:6] + + + SPH + SPI Clock Phase + [7:7] + + + SCRDV + Serial Clock Rate divide+1 value + [15:8] + + + + + CTRL1 + Control Register 1 + 0x004 + 0x0000000 + + + LBM + Loop Back + [0:0] + + + ENABLE + Enable + [1:1] + + + MS + Master/Slave (0:Master, 1:Slave) + [2:2] + + + SOD + Slave output Disable + [3:3] + + + SS + Slave Select + [6:4] + + + BLOCKMODE + Block Mode Enable + [7:7] + + + BMSTART + Block Mode Start Status Enable + [8:8] + + + BMSTALL + Block Mode Stall Enable + [9:9] + + + MDLYCAP + Master Delayed Capture Enable + [10:10] + + + MTXPAUSE + Master Tx Pause Enable + [11:11] + + + + + DATA + Data Input/Output + 0x008 + + + STATUS + Status Register + 0x00C + read-only + 0x0000000 + + + TFE + Transmit FIFO empty + [0:0] + + + TNF + Transmit FIFO not full + [1:1] + + + RNE + Receive FIFO not empty + [2:2] + + + RFF + Receive FIFO Full + [3:3] + + + BUSY + Busy + [4:4] + + + RXDATAFIRST + Pending Data is first Byte in BLOCKMODE + [5:5] + + + RXTRIGGER + RX FIFO Above Trigger Level + [6:6] + + + TXTRIGGER + TX FIFO Below Trigger Level + [7:7] + + + + + CLKPRESCALE + Clock Pre Scale divide value + 0x010 + + + IRQ_ENB + Interrupt Enable Register + 0x014 + read-write + 0x0000000 + + + RORIM + RX Overrun + [0:0] + + + RTIM + RX Timeout + [1:1] + + + RXIM + RX Fifo is at least half full + [2:2] + + + TXIM + TX Fifo is at least half empty + [3:3] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x018 + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x01C + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x020 + write-only + + oneToClear + + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x024 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x028 + + + FIFO_CLR + Clear FIFO Register + 0x02c + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + STATE + Internal STATE of SPI Controller + 0x030 + read-only + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001207e1 + + + + + SPIB + 0x40051000 + + + SPIC + 0x40052000 + + + + + I2CA + 1.0 + I2C Peripheral + I2C + 0x40060000 + + 0 + 0x00001000 + registers + + + + + + CTRL + Control Register + 0x000 + 0x0000000 + + + CLKENABLED + I2C CLK Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + ALGFILTER + Enable Input Analog Glitch Filter + [5:5] + + + DLGFILTER + Enable Input Digital Glitch Filter + [6:6] + + + LOOPBACK + Enable LoopBack Mode + [8:8] + + + TMCONFIGENB + Enable Timing Config Register + [9:9] + + + + + CLKSCALE + Clock Scale divide value + 0x004 + + + VALUE + Enable FastMode + [30:0] + + + FASTMODE + Enable FastMode + [31:31] + + + + + WORDS + Word Count value + 0x008 + + + ADDRESS + I2C Address value + 0x00c + + + DATA + Data Input/Output + 0x010 + + + CMD + Command Register + 0x014 + + + STATUS + I2C Controller Status Register + 0x018 + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + + + STATE + Internal STATE of I2C Master Controller + 0x01c + read-only + + + TXCOUNT + TX Count Register + 0x020 + read-only + + + RXCOUNT + RX Count Register + 0x024 + read-only + + + IRQ_ENB + Interrupt Enable Register + 0x028 + read-write + 0x0000000 + + + I2CIDLE + I2C Bus is Idle + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + CLKLOTO + I2C Clock Low Timeout + [7:7] + + + TXOVERFLOW + TX FIFO Overflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x02c + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x030 + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x034 + write-only + + oneToClear + + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x038 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x03c + + + FIFO_CLR + Clear FIFO Register + 0x040 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + TMCONFIG + Timing Config Register + 0x044 + + + CLKTOLIMIT + Clock Low Timeout Limit Register + 0x048 + + + + S0_CTRL + Slave Control Register + 0x100 + 0x0000000 + + + CLKENABLED + I2C Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + + + S0_MAXWORDS + Slave MaxWords Register + 0x104 + + + S0_ADDRESS + Slave I2C Address Value + 0x108 + + + S0_ADDRESSMASK + Slave I2C Address Mask value + 0x10c + + + S0_DATA + Slave Data Input/Output + 0x110 + + + S0_LASTADDRESS + Slave I2C Last Address value + 0x114 + read-only + + + S0_STATUS + Slave I2C Controller Status Register + 0x118 + read-only + 0x0000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_BUSY + I2C Raw Busy value + [29:29] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + + + S0_STATE + Internal STATE of I2C Slave Controller + 0x11c + read-only + + + S0_TXCOUNT + Slave TX Count Register + 0x120 + read-only + + + S0_RXCOUNT + Slave RX Count Register + 0x124 + read-only + + + S0_IRQ_ENB + Slave Interrupt Enable Register + 0x128 + read-write + 0x0000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + I2C_START + I2C Start Condition + [8:8] + + + I2C_STOP + I2C Stop Condition + [9:9] + + + TXUNDERFLOW + TX FIFO Underflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + S0_IRQ_RAW + Slave Raw Interrupt Status Register + 0x12c + read-only + + + S0_IRQ_END + Slave Enabled Interrupt Status Register + 0x130 + read-only + + + S0_IRQ_CLR + Slave Clear Interrupt Status Register + 0x134 + write-only + + oneToClear + + + + S0_RXFIFOIRQTRG + Slave Rx FIFO IRQ Trigger Level + 0x138 + + + S0_TXFIFOIRQTRG + Slave Tx FIFO IRQ Trigger Level + 0x13c + + + S0_FIFO_CLR + Slave Clear FIFO Register + 0x140 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + S0_ADDRESSB + Slave I2C Address B Value + 0x144 + + + S0_ADDRESSMASKB + Slave I2C Address B Mask value + 0x148 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001407e1 + + + + + I2CB + 0x40061000 + + + + diff --git a/va108xx/svd/va108xx-patch.yml b/va108xx/svd/va108xx-patch.yml new file mode 100644 index 0000000..a7a8873 --- /dev/null +++ b/va108xx/svd/va108xx-patch.yml @@ -0,0 +1,137 @@ +_svd: va108xx.svd + +SYSCONFIG: + PERIPHERAL_CLK_ENABLE: + _add: + PORTA: + description: Enable PORTA clock + bitOffset: 0 + bitWidth: 1 + PORTB: + description: Enable PORTB clock + bitOffset: 1 + bitWidth: 1 + SPI_0: + description: Enable SPI[0] clock + bitOffset: 4 + bitWidth: 1 + SPI_1: + description: Enable SPI[1] clock + bitOffset: 5 + bitWidth: 1 + SPI_2: + description: Enable SPI[2] clock + bitOffset: 6 + bitWidth: 1 + UART_0: + description: Enable UART[0] clock + bitOffset: 8 + bitWidth: 1 + UART_1: + description: Enable UART[1] clock + bitOffset: 9 + bitWidth: 1 + I2C_0: + description: Enable I2C[0] clock + bitOffset: 16 + bitWidth: 1 + I2C_1: + description: Enable I2C[1] clock + bitOffset: 17 + bitWidth: 1 + IRQSEL: + description: Enable IRQ selector clock + bitOffset: 21 + bitWidth: 1 + IOCONFIG: + description: Enable IO Configuration block clock + bitOffset: 22 + bitWidth: 1 + UTILITY: + description: Enable utility clock + bitOffset: 23 + bitWidth: 1 + GPIO: + description: Enable GPIO clock + bitOffset: 24 + bitWidth: 1 + + PERIPHERAL_RESET: + _add: + PORTA: + description: Reset PORTA + bitOffset: 0 + bitWidth: 1 + PORTB: + description: Reset PORTB + bitOffset: 1 + bitWidth: 1 + SPI_0: + description: Reset SPI[0] + bitOffset: 4 + bitWidth: 1 + SPI_1: + description: Reset SPI[1] + bitOffset: 5 + bitWidth: 1 + SPI_2: + description: Reset SPI[2] + bitOffset: 6 + bitWidth: 1 + UART_0: + description: Reset UART[0] + bitOffset: 8 + bitWidth: 1 + UART_1: + description: Reset UART[1] + bitOffset: 9 + bitWidth: 1 + I2C_0: + description: Reset I2C[0] + bitOffset: 16 + bitWidth: 1 + I2C_1: + description: Reset I2C[1] + bitOffset: 17 + bitWidth: 1 + IRQSEL: + description: Reset IRQ selector + bitOffset: 21 + bitWidth: 1 + IOCONFIG: + description: Reset IO Configuration block + bitOffset: 22 + bitWidth: 1 + UTILITY: + description: Reset Utility Block + bitOffset: 23 + bitWidth: 1 + GPIO: + description: Reset GPIO + bitOffset: 24 + bitWidth: 1 + +# I2CB is derived from I2CA +I2CA: + _modify: + STATUS: + access: read-only + STATUS: + _add: + I2C_IDLE: + description: I2C bus is Idle + bitOffset: 0 + bitWidth: 1 + IDLE: + description: Controller is Idle + bitOffset: 1 + bitWidth: 1 + +# All TIMs are derived from TIM0 +TIM0: + CSD_CTRL: + _add: + CSDTRG2: + description: Cascade 2 Enabled as Trigger + bitOffset: 10 + bitWidth: 1 diff --git a/va108xx/svd/va108xx.svd b/va108xx/svd/va108xx.svd new file mode 100644 index 0000000..0658a97 --- /dev/null +++ b/va108xx/svd/va108xx.svd @@ -0,0 +1,2733 @@ + + + VORAGO TECHNOLOGIES + SST + va108xx + M0 + 1.1 + ARM 32-bit Cortex-M0 Microcontroller based device, CPU clock up to 50MHz + + VORAGO Technologies \n +\n +----------------------------------------------------------------------------\n + Copyright (c) 2013-2016 VORAGO Technologies\n +\n + BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND BY ALL THE TERMS\n + AND CONDITIONS OF THE VORAGO TECHNOLOGIES END USER LICENSE AGREEMENT. \n +\n + THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\n + OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\n + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\n + VORAGO TECHNOLOGIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE\n + FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\n + + + CM0 + r0p0 + little + false + false + 2 + false + + system_VA108xx + VOR_ + 8 + 32 + + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + + + SYSCONFIG + 1.0 + System Configuration Peripheral + 0x40000000 + + 0 + 0x00001000 + registers + + + + RST_STAT + System Reset Status + 0x000 + read-write + 0x00000001 + + + POR + Power On Reset Status + [0:0] + + + EXTRST + External Reset Status + [1:1] + + + SYSRSTREQ + SYSRESETREQ Reset Status + [2:2] + + + LOOKUP + LOOKUP Reset Status + [3:3] + + + WATCHDOG + WATCHDOG Reset Status + [4:4] + + + MEMERR + Memory Error Reset Status + [5:5] + + + + + RST_CNTL_ROM + ROM Reset Control + 0x004 + 0x0000001F + + + RST_CNTL_RAM + RAM Reset Control + 0x008 + 0x0000001F + + + ROM_PROT + ROM Protection Configuration + 0x00C + 0x00000001 + + + WREN + ROM Write Enable Bit + [0:0] + + + + + ROM_SCRUB + ROM Scrub Period Configuration + 0x010 + read-write + 0x00000000 + + + VALUE + Counter divide value + [23:0] + + + RESET + Reset Counter + [31:31] + write-only + oneToClear + + + + + RAM_SCRUB + RAM Scrub Period Configuration + 0x014 + + + ROM_TRAP_ADDR + ROM Trap Address + 0x018 + 0x00000000 + + + ADDR + Trap Address Match Bits + [15:2] + + + ENABLE + Trap Enable Bit + [31:31] + + + + + ROM_TRAP_SYND + ROM Trap Syndrome + 0x01C + 0x00000000 + + + SYND + Trap Syndrom Bits + [19:0] + + + + + RAM_TRAP_ADDR + RAM Trap Address + 0x020 + + + RAM_TRAP_SYND + RAM Trap Syndrome + 0x024 + + + IRQ_ENB + Enable EDAC Error Interrupt Register + 0x028 + read-write + 0x00000000 + + + RAMSBE + RAM Single Bit Interrupt + [0:0] + + + RAMMBE + RAM Multi Bit Interrupt + [1:1] + + + ROMSBE + ROM Single Bit Interrupt + [2:2] + + + ROMMBE + ROM Multi Bit Interrupt + [3:3] + + + + + IRQ_RAW + Raw EDAC Error Interrupt Status + 0x02C + read-only + 0x00000000 + + + IRQ_END + Enabled EDAC Error Interrupt Status + 0x030 + read-only + 0x00000000 + + + IRQ_CLR + Clear EDAC Error Interrupt Status + 0x034 + write-only + 0x00000000 + oneToClear + + + RAM_SBE + Count of RAM EDAC Single Bit Errors + 0x038 + 0x00000000 + + + RAM_MBE + Count of RAM EDAC Multi Bit Errors + 0x03C + + + ROM_SBE + Count of ROM EDAC Single Bit Errors + 0x040 + + + ROM_MBE + Count of ROM EDAC Multi Bit Errors + 0x044 + + + IOCONFIG_CLKDIV0 + IO Configuration Clock Divider Register + 0x048 + read-only + 0x00000000 + + + 7 + 4 + 1-7 + IOCONFIG_CLKDIV%s + IO Configuration Clock Divider Register + 0x04C + 0x00000000 + + + ROM_RETRIES + ROM BOOT Retry count + 0x068 + read-only + 0x00000000 + + + REFRESH_CONFIG + Register Refresh Control + 0x06C + 0x00000000 + + + TIM_RESET + TIM Reset Control + 0x070 + 0xFFFFFFFF + + + TIM_CLK_ENABLE + TIM Enable Control + 0x074 + 0x00000000 + + + PERIPHERAL_RESET + Peripheral Reset Control + 0x078 + 0xFFFFFFFF + + + PERIPHERAL_CLK_ENABLE + Peripheral Enable Control + 0x07C + 0x00000000 + + + LOCKUP_RESET + Lockup Reset Configuration + 0x080 + 0x00000001 + + + LREN + Lockup Reset Enable Bit + [0:0] + + + + + EF_CONFIG + EFuse Config Register + 0xff0 + read-only + 0x00000000 + + + EF_ID + EFuse ID Register + 0xff4 + read-only + 0x00000000 + + + PROCID + Processor ID Register + 0xff8 + read-only + 0x040017e3 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008007e1 + + + + + + + IRQSEL + 1.0 + Interrupt Selector Peripheral + 0x40001000 + + 0 + 0x00001000 + registers + + + OC0 + 0 + + + OC1 + 1 + + + OC2 + 2 + + + OC3 + 3 + + + OC4 + 4 + + + OC5 + 5 + + + OC6 + 6 + + + OC7 + 7 + + + OC8 + 8 + + + OC9 + 9 + + + OC10 + 10 + + + OC11 + 11 + + + OC12 + 12 + + + OC13 + 13 + + + OC14 + 14 + + + OC15 + 15 + + + OC16 + 16 + + + OC17 + 17 + + + OC18 + 18 + + + OC19 + 19 + + + OC20 + 20 + + + OC21 + 21 + + + OC22 + 22 + + + OC23 + 23 + + + OC24 + 24 + + + OC25 + 25 + + + OC26 + 26 + + + OC27 + 27 + + + OC28 + 28 + + + OC29 + 29 + + + OC30 + 30 + + + OC31 + 31 + + + + INT_RAM_SBE + Internal Memory RAM SBE Interrupt Redirect Selection + 0x01C0 + read-write + 0xFFFFFFFF + + + 32 + 4 + PORTA[%s] + PORTA Interrupt Redirect Selection + 0x000 + + + 32 + 4 + PORTB[%s] + PORTB Interrupt Redirect Selection + 0x080 + + + 32 + 4 + TIM[%s] + TIM Interrupt Redirect Selection + 0x100 + + + 4 + 4 + UART[%s] + UART Interrupt Redirect Selection + 0x180 + + + 4 + 4 + SPI[%s] + SPI Interrupt Redirect Selection + 0x190 + + + 4 + 4 + I2C_MS[%s] + Master I2C Interrupt Redirect Selection + 0x01a0 + + + 4 + 4 + I2C_SL[%s] + Slave I2C Interrupt Redirect Selection + 0x01B0 + + + INT_RAM_MBE + Internal Memory RAM MBE Interrupt Redirect Selection + 0x01C4 + + + INT_ROM_SBE + Internal Memory ROM SBE Interrupt Redirect Selection + 0x01C8 + + + INT_ROM_MBE + Internal Memory ROM MBE Interrupt Redirect Selection + 0x01CC + + + TXEV + Processor TXEV Interrupt Redirect Selection + 0x01D0 + + + NMI + NMI Status Register + 0x8f8 + read-only + 0x00000000 + + + ACTIVE + Active + [0:0] + + + + + RXEV + RXEV Status Register + 0x8f4 + + + WATCHDOG + WATCHDOG Status Register + 0x8f0 + + + MERESET + MERESET Status Register + 0x8ec + + + EDBGRQ + EDBGRQ Status Register + 0x8e8 + + + 32 + 4 + IRQS[%s] + Interrupt Status Register + 0x800 + + + PERID + Peripheral ID Register + 0xffc + 32 + read-only + 0x008007e1 + + + + + + + IOCONFIG + 1.0 + IO Pin Configuration Peripheral + 0x40002000 + + 0 + 0x00001000 + registers + + + + 32 + 4 + PORTA[%s] + PORTA Pin Configuration Register + 0x000 + 0x00000000 + + + FLTTYPE + Input Filter Selectoin + [2:0] + + + SYNC + Synchronize to system clock + 0 + + + DIRECT + Direct input, no synchronization + 1 + + + FILTER1 + Require 2 samples to have the same value + 2 + + + FILTER2 + Require 3 samples to have the same value + 3 + + + FILTER3 + Require 4 samples to have the same value + 4 + + + FILTER4 + Require 5 samples to have the same value + 5 + + + + + FLTCLK + Input Filter Clock Selection + [5:3] + + + INVINP + Input Invert Selection + [6:6] + + + IEWO + Input Enable While Output enabled + [7:7] + + + OPENDRN + Output Open Drain Mode + [8:8] + + + INVOUT + Output Invert Selection + [9:9] + + + PLEVEL + Internal Pull up/down level + [10:10] + + + PEN + Enable Internal Pull up/down + [11:11] + + + PWOA + Enable Pull when output active + [12:12] + + + FUNSEL + Pin Function Selection + [15:13] + + + IODIS + IO Pin Disable + [16:16] + + + + + PORTB[%s] + PORTB Pin Configuration Register + 0x0080 + 0x00000800 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008207e1 + + + + + + + UTILITY + 1.0 + Utility Peripheral + 0x40003000 + + 0 + 0x00001000 + registers + + + + SYND_DATA0 + Synd Data 0 Register + 0x000 + 0x00000000 + + + SYND_DATA1 + Synd Data 1 Register + 0x004 + 0x00000000 + + + SYND_SYND + Synd Parity Register + 0x008 + 0x00000000 + + + SYND_ENC_32 + Synd 32 bit Encoded Syndrome + 0x00c + read-only + 0x00000000 + + + SYND_CHECK_32_DATA + Synd 32 bit Corrected Data + 0x010 + read-only + 0x00000000 + + + SYND_CHECK_32_SYND + Synd 32 bit Corrected Syndrome and Status + 0x014 + read-only + 0x00000000 + + + SYND_ENC_64 + Synd 64 bit Encoded Syndrome + 0x018 + read-only + 0x00000000 + + + SYND_CHECK_64_DATA0 + Synd 64 bit Corrected Data 0 + 0x01c + read-only + 0x00000000 + + + SYND_CHECK_64_DATA1 + Synd 64 bit Corrected Data 1 + 0x020 + read-only + 0x00000000 + + + SYND_CHECK_64_SYND + Synd 64 bit Corrected Parity and Status + 0x024 + read-only + 0x00000000 + + + SYND_ENC_32_52 + Synd 32/52 bit Encoded Syndrome + 0x028 + read-only + 0x00000000 + + + SYND_CHECK_32_52_DATA + Synd 32/52 bit Corrected Data + 0x02c + read-only + 0x00000000 + + + SYND_CHECK_32_52_SYND + Synd 32/52 bit Corrected Syndrome and Status + 0x030 + read-only + 0x00000000 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x008207e1 + + + + + + + PORTA + 1.0 + GPIO Peripheral + GPIO + 0x50000000 + + 0 + 0x00001000 + registers + + + + + DATAIN + Data In Register + 0x000 + read-only + 0x0000000 + + + 4 + 1 + DATAINBYTE[%s] + Data In Register by Byte + DATAIN + 0x000 + 8 + read-only + 0x0000000 + + + DATAINRAW + Data In Raw Register + 0x004 + 0x0000000 + + + DATAINRAWBYTE[%s] + Data In Raw Register by Byte + DATAINRAW + 0x004 + 0x0000000 + + + DATAOUT + Data Out Register + 0x008 + write-only + 0x0000000 + + + 4 + 1 + DATAOUTBYTE[%s] + Data Out Register by Byte + DATAOUT + 0x008 + 8 + write-only + 0x0000000 + + + DATAOUTRAW + Data Out Register + 0x00c + 0x0000000 + + + DATAOUTRAWBYTE[%s] + Data Out Register by Byte + DATAOUTRAW + 0x00c + 0x0000000 + + + SETOUT + Set Out Register + 0x010 + 0x0000000 + + + SETOUTBYTE[%s] + Set Out Register by Byte + SETOUT + 0x010 + 0x0000000 + + + CLROUT + Clear Out Register + 0x014 + 0x0000000 + + + CLROUTBYTE[%s] + Clear Out Register by Byte + CLROUT + 0x014 + 0x0000000 + + + TOGOUT + Toggle Out Register + 0x018 + 0x0000000 + + + TOGOUTBYTE[%s] + Toggle Out Register by Byte + TOGOUT + 0x018 + 0x0000000 + + + DATAMASK + Data mask Register + 0x01c + 0x0000000 + + + 4 + 1 + DATAMASKBYTE[%s] + Data Out Register by Byte + DATAMASK + 0x01c + 8 + 0x0000000 + + + DIR + Direction Register (1:Output, 0:Input) + 0x020 + 0x0000000 + + + DIRBYTE[%s] + Direction Register by Byte + DIR + 0x020 + 0x0000000 + + + PULSE + Pulse Mode Register + 0x024 + 0x0000000 + + + PULSEBYTE[%s] + Pulse Mode Register by Byte + PULSE + 0x024 + 0x0000000 + + + PULSEBASE + Pulse Base Value Register + 0x028 + 0x0000000 + + + PULSEBASEBYTE[%s] + Pulse Base Mode Register by Byte + PULSEBASE + 0x028 + 0x0000000 + + + DELAY1 + Delay1 Register + 0x02c + 0x0000000 + + + DELAY1BYTE[%s] + Delay1 Register by Byte + DELAY1 + 0x02c + 0x0000000 + + + DELAY2 + Delay2 Register + 0x030 + 32 + read-write + 0x0000000 + + + DELAY2BYTE[%s] + Delay2 Register by Byte + DELAY2 + 0x030 + 0x0000000 + + + IRQ_SEN + Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive) + 0x034 + 0x0000000 + + + IRQ_EDGE + Interrupt Both Edge Register (1:Both Edges, 0:Single Edge) + 0x038 + 0x0000000 + + + IRQ_EVT + Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge) + 0x03c + 0x0000000 + + + IRQ_ENB + Interrupt Enable Register + 0x040 + 0x0000000 + + + IRQ_RAW + Raw Interrupt Status + 0x044 + read-only + 0x0000000 + + + IRQ_END + Masked Interrupt Status + 0x048 + read-only + 0x0000000 + + + EDGE_STATUS + Edge Status Register + 0x04c + read-write + 0x00000000 + + + PERID + Peripheral ID Register + 0xffc + 32 + read-only + 0x001007e1 + + + + + PORTB + 0x50001000 + + + + + TIM0 + 1.0 + Timer/Counter Peripheral + Timer_Counter + 0x40020000 + + 0 + 0x00001000 + registers + + + + + CTRL + Control Register + 0x000 + read-write + + + ENABLE + Counter Enable + [0:0] + + + ACTIVE + Counter Active + [1:1] + read-only + + + AUTO_DISABLE + Auto Disables the counter (set ENABLE to 0) when the count reaches 0 + [2:2] + + + AUTO_DEACTIVATE + Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0 + [3:3] + + + IRQ_ENB + Interrupt Enable + [4:4] + + + STATUS_SEL + Counter Status Selection + [7:5] + + + DONE + Single cycle pulse when the counter reaches 0 + 0 + + + ACTIVE + Returns the counter ACTIVE bit + 1 + + + TOGGLE + Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output. + 2 + + + PWMA + Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE + 3 + + + PWMB + Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE + 4 + + + ENABLED + Returns the counter ENABLED bit + 5 + + + PWMA_ACTIVE + Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0 + 6 + + + + + STATUS_INV + Invert the Output Status + [8:8] + + + REQ_STOP + Stop Request + [9:9] + + + + + RST_VALUE + The value that counter start from after reaching 0. + 0x004 + + + CNT_VALUE + The current value of the counter + 0x008 + + + ENABLE + Alternate access to the Counter ENABLE bit in the CTRL Register + 0x00c + + + ENABLE + Counter Enable + [0:0] + + + + + CSD_CTRL + The Cascade Control Register. Controls the counter external enable signals + 0x010 + + + CSDEN0 + Cascade 0 Enable + [0:0] + + + CSDINV0 + Cascade 0 Invert + [1:1] + + + CSDEN1 + Cascade 1 Enable + [2:2] + + + CSDINV1 + Cascade 1 Invert + [3:3] + + + DCASOP + Dual Cascade Operation (0:AND, 1:OR) + [4:4] + + + CSDTRG0 + Cascade 0 Enabled as Trigger + [6:6] + + + CSDTRG1 + Cascade 1 Enabled as Trigger + [7:7] + + + CSDEN2 + Cascade 2 Enable + [8:8] + + + CSDINV2 + Cascade 2 Invert + [9:9] + + + CSDXXX2 + Cascade 2 test mode + [11:11] + + + + + CASCADE0 + Cascade Enable Selection + 0x014 + + + CASSEL + Cascade Selection + [7:0] + + + + + CASCADE1 + Cascade Enable Selection + 0x018 + + + CASCADE2 + Cascade Enable Selection + 0x01c + + + PWM_VALUE + The Pulse Width Modulation Value + 0x020 + + + PWMA_VALUE + The Pulse Width Modulation ValueA + PWM_VALUE + 0x020 + + + PWMB_VALUE + The Pulse Width Modulation ValueB + 0x024 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001107e1 + + + + + TIM1 + 0x40021000 + + + TIM2 + 0x40022000 + + + TIM3 + 0x40023000 + + + TIM4 + 0x40024000 + + + TIM5 + 0x40025000 + + + TIM6 + 0x40026000 + + + TIM7 + 0x40027000 + + + TIM8 + 0x40028000 + + + TIM9 + 0x40029000 + + + TIM10 + 0x4002a000 + + + TIM11 + 0x4002b000 + + + TIM12 + 0x4002c000 + + + TIM13 + 0x4002d000 + + + TIM14 + 0x4002e000 + + + TIM15 + 0x4002f000 + + + TIM16 + 0x40030000 + + + TIM17 + 0x40031000 + + + TIM18 + 0x40032000 + + + TIM19 + 0x40033000 + + + TIM20 + 0x40034000 + + + TIM21 + 0x40035000 + + + TIM22 + 0x40036000 + + + TIM23 + 0x40037000 + + + + + UARTA + 1.0 + UART Peripheral + UART + 0x40040000 + + 0 + 0x00001000 + registers + + + + + DATA + Data In/Out Register + 0x000 + 0x0000000 + + + ENABLE + Enable Register + 0x004 + 0x0000000 + + + RXENABLE + Rx Enable + [0:0] + + + TXENABLE + Tx Enable + [1:1] + + + + + CTRL + Control Register + 0x008 + 0x0000000 + + + PAREN + Parity Enable + [0:0] + + + PAREVEN + Parity Even/Odd(1/0) + [1:1] + + + PARSTK + Parity Sticky + [2:2] + + + STOPBITS + Stop Bits 1/2(0/1) + [3:3] + + + WORDSIZE + Word Size in Bits 5/6/7/8(00/01/10/11) + [5:4] + + + LOOPBACK + Loopback Enable + [6:6] + + + LOOPBACKBLK + Loopback Block + [7:7] + + + AUTOCTS + Enable Auto CTS mode + [8:8] + + + DEFRTS + Default RTSn value + [9:9] + + + AUTORTS + Enable Auto RTS mode + [10:10] + + + BAUD8 + Enable BAUD8 mode + [11:11] + + + + + CLKSCALE + Clock Scale Register + 0x00c + 0x0000000 + + + FRAC + Fractional Divide (64ths) + [5:0] + + + INT + Integer Divide + [23:6] + + + RESET + Reset Baud Counter + [31:31] + write-only + + + + + RXSTATUS + Status Register + 0x010 + read-only + 0x0000000 + + + RDAVL + Read Data Available + [0:0] + + + RDNFULL + Read Fifo NOT Full + [1:1] + + + RXBUSY + RX Busy Receiving + [2:2] + + + RXTO + RX Receive Timeout + [3:3] + + + RXOVR + Read Fifo Overflow + [4:4] + + + RXFRM + RX Framing Error + [5:5] + + + RXPAR + RX Parity Error + [6:6] + + + RXBRK + RX Break Error + [7:7] + + + RXBUSYBRK + RX Busy Receiving Break + [8:8] + + + RXADDR9 + Address Match for 9 bit mode + [9:9] + + + RXRTSN + RX RTSn Output Value + [15:15] + + + + + TXSTATUS + Status Register + 0x014 + read-only + 0x0000000 + + + WRRDY + Write Fifo NOT Full + [0:0] + + + WRBUSY + Write Fifo Full + [1:1] + + + TXBUSY + TX Busy Transmitting + [2:2] + + + WRLOST + Write Data Lost (Fifo Overflow) + [3:3] + + + TXCTSN + TX CTSn Input Value + [15:15] + + + + + FIFO_CLR + Clear FIFO Register + 0x018 + write-only + 0x0000000 + + + RXSTS + Clear Rx Status + [0:0] + + + TXSTS + Clear Tx Status + [1:1] + + + RXFIFO + Clear Rx FIFO + [2:2] + + + TXFIFO + Clear Tx FIFO + [3:3] + + + + + TXBREAK + Break Transmit Register + 0x01c + write-only + 0x0000000 + + + ADDR9 + Address9 Register + 0x020 + read-write + 0x0000000 + + + ADDR9MASK + Address9 Mask Register + 0x024 + read-write + 0x0000000 + + + IRQ_ENB + IRQ Enable Register + 0x028 + read-write + 0x0000000 + + + IRQ_RX + RX Interrupt + [0:0] + + + IRQ_RX_STATUS + RX Status Interrupt + [1:1] + + + IRQ_RX_TO + RX Timeout Interrupt + [2:2] + + + IRQ_TX + TX Interrupt + [4:4] + + + IRQ_TX_STATUS + TX Status Interrupt + [5:5] + + + IRQ_TX_EMPTY + TX Empty Interrupt + [6:6] + + + IRQ_TX_CTS + TX CTS Change Interrupt + [7:7] + + + + + IRQ_RAW + IRQ Raw Status Register + 0x02c + read-only + 0x0000000 + + + IRQ_END + IRQ Enabled Status Register + 0x030 + read-only + 0x0000000 + + + IRQ_CLR + IRQ Clear Status Register + 0x034 + write-only + 0x0000000 + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x038 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x03c + + + RXFIFORTSTRG + Rx FIFO RTS Trigger Level + 0x040 + + + STATE + Internal STATE of UART Controller + 0x044 + 32 + read-only + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001207e1 + + + + + UARTB + 0x40041000 + + + + + SPIA + 1.0 + SPI Peripheral + SPI + 0x40050000 + + 0 + 0x00001000 + registers + + + + + CTRL0 + Control Register 0 + 0x000 + 0x0000000 + + + SIZE + Data Size(0x3=>4, 0xf=>16) + [3:0] + + + SPO + SPI Clock Polarity + [6:6] + + + SPH + SPI Clock Phase + [7:7] + + + SCRDV + Serial Clock Rate divide+1 value + [15:8] + + + + + CTRL1 + Control Register 1 + 0x004 + 0x0000000 + + + LBM + Loop Back + [0:0] + + + ENABLE + Enable + [1:1] + + + MS + Master/Slave (0:Master, 1:Slave) + [2:2] + + + SOD + Slave output Disable + [3:3] + + + SS + Slave Select + [6:4] + + + BLOCKMODE + Block Mode Enable + [7:7] + + + BMSTART + Block Mode Start Status Enable + [8:8] + + + BMSTALL + Block Mode Stall Enable + [9:9] + + + MDLYCAP + Master Delayed Capture Enable + [10:10] + + + MTXPAUSE + Master Tx Pause Enable + [11:11] + + + + + DATA + Data Input/Output + 0x008 + + + STATUS + Status Register + 0x00C + read-only + 0x0000000 + + + TFE + Transmit FIFO empty + [0:0] + + + TNF + Transmit FIFO not full + [1:1] + + + RNE + Receive FIFO not empty + [2:2] + + + RFF + Receive FIFO Full + [3:3] + + + BUSY + Busy + [4:4] + + + RXDATAFIRST + Pending Data is first Byte in BLOCKMODE + [5:5] + + + RXTRIGGER + RX FIFO Above Trigger Level + [6:6] + + + TXTRIGGER + TX FIFO Below Trigger Level + [7:7] + + + + + CLKPRESCALE + Clock Pre Scale divide value + 0x010 + + + IRQ_ENB + Interrupt Enable Register + 0x014 + read-write + 0x0000000 + + + RORIM + RX Overrun + [0:0] + + + RTIM + RX Timeout + [1:1] + + + RXIM + RX Fifo is at least half full + [2:2] + + + TXIM + TX Fifo is at least half empty + [3:3] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x018 + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x01C + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x020 + write-only + oneToClear + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x024 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x028 + + + FIFO_CLR + Clear FIFO Register + 0x02c + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + STATE + Internal STATE of SPI Controller + 0x030 + read-only + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001207e1 + + + + + SPIB + 0x40051000 + + + SPIC + 0x40052000 + + + + + I2CA + 1.0 + I2C Peripheral + I2C + 0x40060000 + + 0 + 0x00001000 + registers + + + + + + CTRL + Control Register + 0x000 + 0x0000000 + + + CLKENABLED + I2C CLK Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + ALGFILTER + Enable Input Analog Glitch Filter + [5:5] + + + DLGFILTER + Enable Input Digital Glitch Filter + [6:6] + + + LOOPBACK + Enable LoopBack Mode + [8:8] + + + TMCONFIGENB + Enable Timing Config Register + [9:9] + + + + + CLKSCALE + Clock Scale divide value + 0x004 + + + VALUE + Enable FastMode + [30:0] + + + FASTMODE + Enable FastMode + [31:31] + + + + + WORDS + Word Count value + 0x008 + + + ADDRESS + I2C Address value + 0x00c + + + DATA + Data Input/Output + 0x010 + + + CMD + Command Register + 0x014 + + + STATUS + I2C Controller Status Register + 0x018 + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + + + STATE + Internal STATE of I2C Master Controller + 0x01c + read-only + + + TXCOUNT + TX Count Register + 0x020 + read-only + + + RXCOUNT + RX Count Register + 0x024 + read-only + + + IRQ_ENB + Interrupt Enable Register + 0x028 + read-write + 0x0000000 + + + I2CIDLE + I2C Bus is Idle + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + CLKLOTO + I2C Clock Low Timeout + [7:7] + + + TXOVERFLOW + TX FIFO Overflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x02c + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x030 + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x034 + write-only + oneToClear + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x038 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x03c + + + FIFO_CLR + Clear FIFO Register + 0x040 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + TMCONFIG + Timing Config Register + 0x044 + + + CLKTOLIMIT + Clock Low Timeout Limit Register + 0x048 + + + + S0_CTRL + Slave Control Register + 0x100 + 0x0000000 + + + CLKENABLED + I2C Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + + + S0_MAXWORDS + Slave MaxWords Register + 0x104 + + + S0_ADDRESS + Slave I2C Address Value + 0x108 + + + S0_ADDRESSMASK + Slave I2C Address Mask value + 0x10c + + + S0_DATA + Slave Data Input/Output + 0x110 + + + S0_LASTADDRESS + Slave I2C Last Address value + 0x114 + read-only + + + S0_STATUS + Slave I2C Controller Status Register + 0x118 + read-only + 0x0000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_BUSY + I2C Raw Busy value + [29:29] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + + + S0_STATE + Internal STATE of I2C Slave Controller + 0x11c + read-only + + + S0_TXCOUNT + Slave TX Count Register + 0x120 + read-only + + + S0_RXCOUNT + Slave RX Count Register + 0x124 + read-only + + + S0_IRQ_ENB + Slave Interrupt Enable Register + 0x128 + read-write + 0x0000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + I2C_START + I2C Start Condition + [8:8] + + + I2C_STOP + I2C Stop Condition + [9:9] + + + TXUNDERFLOW + TX FIFO Underflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + S0_IRQ_RAW + Slave Raw Interrupt Status Register + 0x12c + read-only + + + S0_IRQ_END + Slave Enabled Interrupt Status Register + 0x130 + read-only + + + S0_IRQ_CLR + Slave Clear Interrupt Status Register + 0x134 + write-only + oneToClear + + + S0_RXFIFOIRQTRG + Slave Rx FIFO IRQ Trigger Level + 0x138 + + + S0_TXFIFOIRQTRG + Slave Tx FIFO IRQ Trigger Level + 0x13c + + + S0_FIFO_CLR + Slave Clear FIFO Register + 0x140 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + S0_ADDRESSB + Slave I2C Address B Value + 0x144 + + + S0_ADDRESSMASKB + Slave I2C Address B Mask value + 0x148 + + + PERID + Peripheral ID Register + 0xffc + read-only + 0x001407e1 + + + + + I2CB + 0x40061000 + + + + diff --git a/va108xx/svd/va108xx.svd.patched b/va108xx/svd/va108xx.svd.patched new file mode 100644 index 0000000..39c07b4 --- /dev/null +++ b/va108xx/svd/va108xx.svd.patched @@ -0,0 +1,2883 @@ + + + VORAGO TECHNOLOGIES + SST + va108xx + M0 + 1.1 + ARM 32-bit Cortex-M0 Microcontroller based device, CPU clock up to 50MHz + VORAGO Technologies \n +\n +----------------------------------------------------------------------------\n + Copyright (c) 2013-2016 VORAGO Technologies\n +\n + BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND BY ALL THE TERMS\n + AND CONDITIONS OF THE VORAGO TECHNOLOGIES END USER LICENSE AGREEMENT. \n +\n + THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\n + OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\n + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\n + VORAGO TECHNOLOGIES SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE\n + FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\n + + CM0 + r0p0 + little + false + false + 2 + false + + system_VA108xx + VOR_ + 8 + 32 + 0x20 + read-write + 0x00000000 + 0xFFFFFFFF + + + SYSCONFIG + 1.0 + System Configuration Peripheral + 0x40000000 + + 0x0 + 0x1000 + registers + + + + RST_STAT + System Reset Status + 0x0 + read-write + 0x00000001 + + + POR + Power On Reset Status + [0:0] + + + EXTRST + External Reset Status + [1:1] + + + SYSRSTREQ + SYSRESETREQ Reset Status + [2:2] + + + LOOKUP + LOOKUP Reset Status + [3:3] + + + WATCHDOG + WATCHDOG Reset Status + [4:4] + + + MEMERR + Memory Error Reset Status + [5:5] + + + + + RST_CNTL_ROM + ROM Reset Control + 0x4 + 0x0000001F + + + RST_CNTL_RAM + RAM Reset Control + 0x8 + 0x0000001F + + + ROM_PROT + ROM Protection Configuration + 0xC + 0x00000001 + + + WREN + ROM Write Enable Bit + [0:0] + + + + + ROM_SCRUB + ROM Scrub Period Configuration + 0x10 + read-write + 0x00000000 + + + VALUE + Counter divide value + [23:0] + + + RESET + Reset Counter + [31:31] + write-only + oneToClear + + + + + RAM_SCRUB + RAM Scrub Period Configuration + 0x14 + + + ROM_TRAP_ADDR + ROM Trap Address + 0x18 + 0x00000000 + + + ADDR + Trap Address Match Bits + [15:2] + + + ENABLE + Trap Enable Bit + [31:31] + + + + + ROM_TRAP_SYND + ROM Trap Syndrome + 0x1C + 0x00000000 + + + SYND + Trap Syndrom Bits + [19:0] + + + + + RAM_TRAP_ADDR + RAM Trap Address + 0x20 + + + RAM_TRAP_SYND + RAM Trap Syndrome + 0x24 + + + IRQ_ENB + Enable EDAC Error Interrupt Register + 0x28 + read-write + 0x00000000 + + + RAMSBE + RAM Single Bit Interrupt + [0:0] + + + RAMMBE + RAM Multi Bit Interrupt + [1:1] + + + ROMSBE + ROM Single Bit Interrupt + [2:2] + + + ROMMBE + ROM Multi Bit Interrupt + [3:3] + + + + + IRQ_RAW + Raw EDAC Error Interrupt Status + 0x2C + read-only + 0x00000000 + + + IRQ_END + Enabled EDAC Error Interrupt Status + 0x30 + read-only + 0x00000000 + + + IRQ_CLR + Clear EDAC Error Interrupt Status + 0x34 + write-only + 0x00000000 + oneToClear + + + RAM_SBE + Count of RAM EDAC Single Bit Errors + 0x38 + 0x00000000 + + + RAM_MBE + Count of RAM EDAC Multi Bit Errors + 0x3C + + + ROM_SBE + Count of ROM EDAC Single Bit Errors + 0x40 + + + ROM_MBE + Count of ROM EDAC Multi Bit Errors + 0x44 + + + IOCONFIG_CLKDIV0 + IO Configuration Clock Divider Register + 0x48 + read-only + 0x00000000 + + + 7 + 0x4 + 1-7 + IOCONFIG_CLKDIV%s + IO Configuration Clock Divider Register + 0x4C + 0x00000000 + + + ROM_RETRIES + ROM BOOT Retry count + 0x68 + read-only + 0x00000000 + + + REFRESH_CONFIG + Register Refresh Control + 0x6C + 0x00000000 + + + TIM_RESET + TIM Reset Control + 0x70 + 0xFFFFFFFF + + + TIM_CLK_ENABLE + TIM Enable Control + 0x74 + 0x00000000 + + + PERIPHERAL_RESET + Peripheral Reset Control + 0x78 + 0xFFFFFFFF + + + PORTA + Reset PORTA + 0 + 1 + + + PORTB + Reset PORTB + 1 + 1 + + + SPI_0 + Reset SPI[0] + 4 + 1 + + + SPI_1 + Reset SPI[1] + 5 + 1 + + + SPI_2 + Reset SPI[2] + 6 + 1 + + + UART_0 + Reset UART[0] + 8 + 1 + + + UART_1 + Reset UART[1] + 9 + 1 + + + I2C_0 + Reset I2C[0] + 16 + 1 + + + I2C_1 + Reset I2C[1] + 17 + 1 + + + IRQSEL + Reset IRQ selector + 21 + 1 + + + IOCONFIG + Reset IO Configuration block + 22 + 1 + + + UTILITY + Reset Utility Block + 23 + 1 + + + GPIO + Reset GPIO + 24 + 1 + + + + + PERIPHERAL_CLK_ENABLE + Peripheral Enable Control + 0x7C + 0x00000000 + + + PORTA + Enable PORTA clock + 0 + 1 + + + PORTB + Enable PORTB clock + 1 + 1 + + + SPI_0 + Enable SPI[0] clock + 4 + 1 + + + SPI_1 + Enable SPI[1] clock + 5 + 1 + + + SPI_2 + Enable SPI[2] clock + 6 + 1 + + + UART_0 + Enable UART[0] clock + 8 + 1 + + + UART_1 + Enable UART[1] clock + 9 + 1 + + + I2C_0 + Enable I2C[0] clock + 16 + 1 + + + I2C_1 + Enable I2C[1] clock + 17 + 1 + + + IRQSEL + Enable IRQ selector clock + 21 + 1 + + + IOCONFIG + Enable IO Configuration block clock + 22 + 1 + + + UTILITY + Enable utility clock + 23 + 1 + + + GPIO + Enable GPIO clock + 24 + 1 + + + + + LOCKUP_RESET + Lockup Reset Configuration + 0x80 + 0x00000001 + + + LREN + Lockup Reset Enable Bit + [0:0] + + + + + EF_CONFIG + EFuse Config Register + 0xFF0 + read-only + 0x00000000 + + + EF_ID + EFuse ID Register + 0xFF4 + read-only + 0x00000000 + + + PROCID + Processor ID Register + 0xFF8 + read-only + 0x040017E3 + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x008007E1 + + + + + IRQSEL + 1.0 + Interrupt Selector Peripheral + 0x40001000 + + 0x0 + 0x1000 + registers + + + OC0 + 0 + + + OC1 + 1 + + + OC2 + 2 + + + OC3 + 3 + + + OC4 + 4 + + + OC5 + 5 + + + OC6 + 6 + + + OC7 + 7 + + + OC8 + 8 + + + OC9 + 9 + + + OC10 + 10 + + + OC11 + 11 + + + OC12 + 12 + + + OC13 + 13 + + + OC14 + 14 + + + OC15 + 15 + + + OC16 + 16 + + + OC17 + 17 + + + OC18 + 18 + + + OC19 + 19 + + + OC20 + 20 + + + OC21 + 21 + + + OC22 + 22 + + + OC23 + 23 + + + OC24 + 24 + + + OC25 + 25 + + + OC26 + 26 + + + OC27 + 27 + + + OC28 + 28 + + + OC29 + 29 + + + OC30 + 30 + + + OC31 + 31 + + + + INT_RAM_SBE + Internal Memory RAM SBE Interrupt Redirect Selection + 0x1C0 + read-write + 0xFFFFFFFF + + + 32 + 0x4 + PORTA[%s] + PORTA Interrupt Redirect Selection + 0x0 + + + 32 + 0x4 + PORTB[%s] + PORTB Interrupt Redirect Selection + 0x80 + + + 32 + 0x4 + TIM[%s] + TIM Interrupt Redirect Selection + 0x100 + + + 4 + 0x4 + UART[%s] + UART Interrupt Redirect Selection + 0x180 + + + 4 + 0x4 + SPI[%s] + SPI Interrupt Redirect Selection + 0x190 + + + 4 + 0x4 + I2C_MS[%s] + Master I2C Interrupt Redirect Selection + 0x1A0 + + + 4 + 0x4 + I2C_SL[%s] + Slave I2C Interrupt Redirect Selection + 0x1B0 + + + INT_RAM_MBE + Internal Memory RAM MBE Interrupt Redirect Selection + 0x1C4 + + + INT_ROM_SBE + Internal Memory ROM SBE Interrupt Redirect Selection + 0x1C8 + + + INT_ROM_MBE + Internal Memory ROM MBE Interrupt Redirect Selection + 0x1CC + + + TXEV + Processor TXEV Interrupt Redirect Selection + 0x1D0 + + + NMI + NMI Status Register + 0x8F8 + read-only + 0x00000000 + + + ACTIVE + Active + [0:0] + + + + + RXEV + RXEV Status Register + 0x8F4 + + + WATCHDOG + WATCHDOG Status Register + 0x8F0 + + + MERESET + MERESET Status Register + 0x8EC + + + EDBGRQ + EDBGRQ Status Register + 0x8E8 + + + 32 + 0x4 + IRQS[%s] + Interrupt Status Register + 0x800 + + + PERID + Peripheral ID Register + 0xFFC + 0x20 + read-only + 0x008007E1 + + + + + IOCONFIG + 1.0 + IO Pin Configuration Peripheral + 0x40002000 + + 0x0 + 0x1000 + registers + + + + 32 + 0x4 + PORTA[%s] + PORTA Pin Configuration Register + 0x0 + 0x00000000 + + + FLTTYPE + Input Filter Selectoin + [2:0] + + + SYNC + Synchronize to system clock + 0 + + + DIRECT + Direct input, no synchronization + 1 + + + FILTER1 + Require 2 samples to have the same value + 2 + + + FILTER2 + Require 3 samples to have the same value + 3 + + + FILTER3 + Require 4 samples to have the same value + 4 + + + FILTER4 + Require 5 samples to have the same value + 5 + + + + + FLTCLK + Input Filter Clock Selection + [5:3] + + + INVINP + Input Invert Selection + [6:6] + + + IEWO + Input Enable While Output enabled + [7:7] + + + OPENDRN + Output Open Drain Mode + [8:8] + + + INVOUT + Output Invert Selection + [9:9] + + + PLEVEL + Internal Pull up/down level + [10:10] + + + PEN + Enable Internal Pull up/down + [11:11] + + + PWOA + Enable Pull when output active + [12:12] + + + FUNSEL + Pin Function Selection + [15:13] + + + IODIS + IO Pin Disable + [16:16] + + + + + PORTB[%s] + PORTB Pin Configuration Register + 0x80 + 0x00000800 + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x008207E1 + + + + + UTILITY + 1.0 + Utility Peripheral + 0x40003000 + + 0x0 + 0x1000 + registers + + + + SYND_DATA0 + Synd Data 0 Register + 0x0 + 0x00000000 + + + SYND_DATA1 + Synd Data 1 Register + 0x4 + 0x00000000 + + + SYND_SYND + Synd Parity Register + 0x8 + 0x00000000 + + + SYND_ENC_32 + Synd 32 bit Encoded Syndrome + 0xC + read-only + 0x00000000 + + + SYND_CHECK_32_DATA + Synd 32 bit Corrected Data + 0x10 + read-only + 0x00000000 + + + SYND_CHECK_32_SYND + Synd 32 bit Corrected Syndrome and Status + 0x14 + read-only + 0x00000000 + + + SYND_ENC_64 + Synd 64 bit Encoded Syndrome + 0x18 + read-only + 0x00000000 + + + SYND_CHECK_64_DATA0 + Synd 64 bit Corrected Data 0 + 0x1C + read-only + 0x00000000 + + + SYND_CHECK_64_DATA1 + Synd 64 bit Corrected Data 1 + 0x20 + read-only + 0x00000000 + + + SYND_CHECK_64_SYND + Synd 64 bit Corrected Parity and Status + 0x24 + read-only + 0x00000000 + + + SYND_ENC_32_52 + Synd 32/52 bit Encoded Syndrome + 0x28 + read-only + 0x00000000 + + + SYND_CHECK_32_52_DATA + Synd 32/52 bit Corrected Data + 0x2C + read-only + 0x00000000 + + + SYND_CHECK_32_52_SYND + Synd 32/52 bit Corrected Syndrome and Status + 0x30 + read-only + 0x00000000 + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x008207E1 + + + + + PORTA + 1.0 + GPIO Peripheral + GPIO + 0x50000000 + + 0x0 + 0x1000 + registers + + + + DATAIN + Data In Register + 0x0 + read-only + 0x00000000 + + + 4 + 0x1 + DATAINBYTE[%s] + Data In Register by Byte + DATAIN + 0x0 + 0x8 + read-only + 0x00000000 + + + DATAINRAW + Data In Raw Register + 0x4 + 0x00000000 + + + DATAINRAWBYTE[%s] + Data In Raw Register by Byte + DATAINRAW + 0x4 + 0x00000000 + + + DATAOUT + Data Out Register + 0x8 + write-only + 0x00000000 + + + 4 + 0x1 + DATAOUTBYTE[%s] + Data Out Register by Byte + DATAOUT + 0x8 + 0x8 + write-only + 0x00000000 + + + DATAOUTRAW + Data Out Register + 0xC + 0x00000000 + + + DATAOUTRAWBYTE[%s] + Data Out Register by Byte + DATAOUTRAW + 0xC + 0x00000000 + + + SETOUT + Set Out Register + 0x10 + 0x00000000 + + + SETOUTBYTE[%s] + Set Out Register by Byte + SETOUT + 0x10 + 0x00000000 + + + CLROUT + Clear Out Register + 0x14 + 0x00000000 + + + CLROUTBYTE[%s] + Clear Out Register by Byte + CLROUT + 0x14 + 0x00000000 + + + TOGOUT + Toggle Out Register + 0x18 + 0x00000000 + + + TOGOUTBYTE[%s] + Toggle Out Register by Byte + TOGOUT + 0x18 + 0x00000000 + + + DATAMASK + Data mask Register + 0x1C + 0x00000000 + + + 4 + 0x1 + DATAMASKBYTE[%s] + Data Out Register by Byte + DATAMASK + 0x1C + 0x8 + 0x00000000 + + + DIR + Direction Register (1:Output, 0:Input) + 0x20 + 0x00000000 + + + DIRBYTE[%s] + Direction Register by Byte + DIR + 0x20 + 0x00000000 + + + PULSE + Pulse Mode Register + 0x24 + 0x00000000 + + + PULSEBYTE[%s] + Pulse Mode Register by Byte + PULSE + 0x24 + 0x00000000 + + + PULSEBASE + Pulse Base Value Register + 0x28 + 0x00000000 + + + PULSEBASEBYTE[%s] + Pulse Base Mode Register by Byte + PULSEBASE + 0x28 + 0x00000000 + + + DELAY1 + Delay1 Register + 0x2C + 0x00000000 + + + DELAY1BYTE[%s] + Delay1 Register by Byte + DELAY1 + 0x2C + 0x00000000 + + + DELAY2 + Delay2 Register + 0x30 + 0x20 + read-write + 0x00000000 + + + DELAY2BYTE[%s] + Delay2 Register by Byte + DELAY2 + 0x30 + 0x00000000 + + + IRQ_SEN + Interrupt Sense Register (1:Level Sensitive, 0:Edge Sensitive) + 0x34 + 0x00000000 + + + IRQ_EDGE + Interrupt Both Edge Register (1:Both Edges, 0:Single Edge) + 0x38 + 0x00000000 + + + IRQ_EVT + Interrupt Event Register (1:HighLevel/L->H Edge, 0:LowLevel/H->L Edge) + 0x3C + 0x00000000 + + + IRQ_ENB + Interrupt Enable Register + 0x40 + 0x00000000 + + + IRQ_RAW + Raw Interrupt Status + 0x44 + read-only + 0x00000000 + + + IRQ_END + Masked Interrupt Status + 0x48 + read-only + 0x00000000 + + + EDGE_STATUS + Edge Status Register + 0x4C + read-write + 0x00000000 + + + PERID + Peripheral ID Register + 0xFFC + 0x20 + read-only + 0x001007E1 + + + + + PORTB + 0x50001000 + + + TIM0 + 1.0 + Timer/Counter Peripheral + Timer_Counter + 0x40020000 + + 0x0 + 0x1000 + registers + + + + CTRL + Control Register + 0x0 + read-write + + + ENABLE + Counter Enable + [0:0] + + + ACTIVE + Counter Active + [1:1] + read-only + + + AUTO_DISABLE + Auto Disables the counter (set ENABLE to 0) when the count reaches 0 + [2:2] + + + AUTO_DEACTIVATE + Auto Deactivate the counter (set ACTIVE to 0) when the count reaches 0 + [3:3] + + + IRQ_ENB + Interrupt Enable + [4:4] + + + STATUS_SEL + Counter Status Selection + [7:5] + + + DONE + Single cycle pulse when the counter reaches 0 + 0 + + + ACTIVE + Returns the counter ACTIVE bit + 1 + + + TOGGLE + Toggles the STATUS bit everytime the counter reaches 0. Basically a divide by 2 counter output. + 2 + + + PWMA + Selects the Pulse Width Modulated output. It 1 when the counter value is >= the PWMA_VALUE + 3 + + + PWMB + Selects the Pulse Width Modulated output. It 1 when the counter value is < the PWMA_VALUE and value is > PWMA_VALUE + 4 + + + ENABLED + Returns the counter ENABLED bit + 5 + + + PWMA_ACTIVE + Selects the Pulse Width Modulated output. It 1 when the counter value is <= the PWMA_VALUE and value is >= 0 + 6 + + + + + STATUS_INV + Invert the Output Status + [8:8] + + + REQ_STOP + Stop Request + [9:9] + + + + + RST_VALUE + The value that counter start from after reaching 0. + 0x4 + + + CNT_VALUE + The current value of the counter + 0x8 + + + ENABLE + Alternate access to the Counter ENABLE bit in the CTRL Register + 0xC + + + ENABLE + Counter Enable + [0:0] + + + + + CSD_CTRL + The Cascade Control Register. Controls the counter external enable signals + 0x10 + + + CSDEN0 + Cascade 0 Enable + [0:0] + + + CSDINV0 + Cascade 0 Invert + [1:1] + + + CSDEN1 + Cascade 1 Enable + [2:2] + + + CSDINV1 + Cascade 1 Invert + [3:3] + + + DCASOP + Dual Cascade Operation (0:AND, 1:OR) + [4:4] + + + CSDTRG0 + Cascade 0 Enabled as Trigger + [6:6] + + + CSDTRG1 + Cascade 1 Enabled as Trigger + [7:7] + + + CSDEN2 + Cascade 2 Enable + [8:8] + + + CSDINV2 + Cascade 2 Invert + [9:9] + + + CSDXXX2 + Cascade 2 test mode + [11:11] + + + CSDTRG2 + Cascade 2 Enabled as Trigger + 10 + 1 + + + + + CASCADE0 + Cascade Enable Selection + 0x14 + + + CASSEL + Cascade Selection + [7:0] + + + + + CASCADE1 + Cascade Enable Selection + 0x18 + + + CASCADE2 + Cascade Enable Selection + 0x1C + + + PWM_VALUE + The Pulse Width Modulation Value + 0x20 + + + PWMA_VALUE + The Pulse Width Modulation ValueA + PWM_VALUE + 0x20 + + + PWMB_VALUE + The Pulse Width Modulation ValueB + 0x24 + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x001107E1 + + + + + TIM1 + 0x40021000 + + + TIM2 + 0x40022000 + + + TIM3 + 0x40023000 + + + TIM4 + 0x40024000 + + + TIM5 + 0x40025000 + + + TIM6 + 0x40026000 + + + TIM7 + 0x40027000 + + + TIM8 + 0x40028000 + + + TIM9 + 0x40029000 + + + TIM10 + 0x4002A000 + + + TIM11 + 0x4002B000 + + + TIM12 + 0x4002C000 + + + TIM13 + 0x4002D000 + + + TIM14 + 0x4002E000 + + + TIM15 + 0x4002F000 + + + TIM16 + 0x40030000 + + + TIM17 + 0x40031000 + + + TIM18 + 0x40032000 + + + TIM19 + 0x40033000 + + + TIM20 + 0x40034000 + + + TIM21 + 0x40035000 + + + TIM22 + 0x40036000 + + + TIM23 + 0x40037000 + + + UARTA + 1.0 + UART Peripheral + UART + 0x40040000 + + 0x0 + 0x1000 + registers + + + + DATA + Data In/Out Register + 0x0 + 0x00000000 + + + ENABLE + Enable Register + 0x4 + 0x00000000 + + + RXENABLE + Rx Enable + [0:0] + + + TXENABLE + Tx Enable + [1:1] + + + + + CTRL + Control Register + 0x8 + 0x00000000 + + + PAREN + Parity Enable + [0:0] + + + PAREVEN + Parity Even/Odd(1/0) + [1:1] + + + PARSTK + Parity Sticky + [2:2] + + + STOPBITS + Stop Bits 1/2(0/1) + [3:3] + + + WORDSIZE + Word Size in Bits 5/6/7/8(00/01/10/11) + [5:4] + + + LOOPBACK + Loopback Enable + [6:6] + + + LOOPBACKBLK + Loopback Block + [7:7] + + + AUTOCTS + Enable Auto CTS mode + [8:8] + + + DEFRTS + Default RTSn value + [9:9] + + + AUTORTS + Enable Auto RTS mode + [10:10] + + + BAUD8 + Enable BAUD8 mode + [11:11] + + + + + CLKSCALE + Clock Scale Register + 0xC + 0x00000000 + + + FRAC + Fractional Divide (64ths) + [5:0] + + + INT + Integer Divide + [23:6] + + + RESET + Reset Baud Counter + [31:31] + write-only + + + + + RXSTATUS + Status Register + 0x10 + read-only + 0x00000000 + + + RDAVL + Read Data Available + [0:0] + + + RDNFULL + Read Fifo NOT Full + [1:1] + + + RXBUSY + RX Busy Receiving + [2:2] + + + RXTO + RX Receive Timeout + [3:3] + + + RXOVR + Read Fifo Overflow + [4:4] + + + RXFRM + RX Framing Error + [5:5] + + + RXPAR + RX Parity Error + [6:6] + + + RXBRK + RX Break Error + [7:7] + + + RXBUSYBRK + RX Busy Receiving Break + [8:8] + + + RXADDR9 + Address Match for 9 bit mode + [9:9] + + + RXRTSN + RX RTSn Output Value + [15:15] + + + + + TXSTATUS + Status Register + 0x14 + read-only + 0x00000000 + + + WRRDY + Write Fifo NOT Full + [0:0] + + + WRBUSY + Write Fifo Full + [1:1] + + + TXBUSY + TX Busy Transmitting + [2:2] + + + WRLOST + Write Data Lost (Fifo Overflow) + [3:3] + + + TXCTSN + TX CTSn Input Value + [15:15] + + + + + FIFO_CLR + Clear FIFO Register + 0x18 + write-only + 0x00000000 + + + RXSTS + Clear Rx Status + [0:0] + + + TXSTS + Clear Tx Status + [1:1] + + + RXFIFO + Clear Rx FIFO + [2:2] + + + TXFIFO + Clear Tx FIFO + [3:3] + + + + + TXBREAK + Break Transmit Register + 0x1C + write-only + 0x00000000 + + + ADDR9 + Address9 Register + 0x20 + read-write + 0x00000000 + + + ADDR9MASK + Address9 Mask Register + 0x24 + read-write + 0x00000000 + + + IRQ_ENB + IRQ Enable Register + 0x28 + read-write + 0x00000000 + + + IRQ_RX + RX Interrupt + [0:0] + + + IRQ_RX_STATUS + RX Status Interrupt + [1:1] + + + IRQ_RX_TO + RX Timeout Interrupt + [2:2] + + + IRQ_TX + TX Interrupt + [4:4] + + + IRQ_TX_STATUS + TX Status Interrupt + [5:5] + + + IRQ_TX_EMPTY + TX Empty Interrupt + [6:6] + + + IRQ_TX_CTS + TX CTS Change Interrupt + [7:7] + + + + + IRQ_RAW + IRQ Raw Status Register + 0x2C + read-only + 0x00000000 + + + IRQ_END + IRQ Enabled Status Register + 0x30 + read-only + 0x00000000 + + + IRQ_CLR + IRQ Clear Status Register + 0x34 + write-only + 0x00000000 + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x38 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x3C + + + RXFIFORTSTRG + Rx FIFO RTS Trigger Level + 0x40 + + + STATE + Internal STATE of UART Controller + 0x44 + 0x20 + read-only + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x001207E1 + + + + + UARTB + 0x40041000 + + + SPIA + 1.0 + SPI Peripheral + SPI + 0x40050000 + + 0x0 + 0x1000 + registers + + + + CTRL0 + Control Register 0 + 0x0 + 0x00000000 + + + SIZE + Data Size(0x3=>4, 0xf=>16) + [3:0] + + + SPO + SPI Clock Polarity + [6:6] + + + SPH + SPI Clock Phase + [7:7] + + + SCRDV + Serial Clock Rate divide+1 value + [15:8] + + + + + CTRL1 + Control Register 1 + 0x4 + 0x00000000 + + + LBM + Loop Back + [0:0] + + + ENABLE + Enable + [1:1] + + + MS + Master/Slave (0:Master, 1:Slave) + [2:2] + + + SOD + Slave output Disable + [3:3] + + + SS + Slave Select + [6:4] + + + BLOCKMODE + Block Mode Enable + [7:7] + + + BMSTART + Block Mode Start Status Enable + [8:8] + + + BMSTALL + Block Mode Stall Enable + [9:9] + + + MDLYCAP + Master Delayed Capture Enable + [10:10] + + + MTXPAUSE + Master Tx Pause Enable + [11:11] + + + + + DATA + Data Input/Output + 0x8 + + + STATUS + Status Register + 0xC + read-only + 0x00000000 + + + TFE + Transmit FIFO empty + [0:0] + + + TNF + Transmit FIFO not full + [1:1] + + + RNE + Receive FIFO not empty + [2:2] + + + RFF + Receive FIFO Full + [3:3] + + + BUSY + Busy + [4:4] + + + RXDATAFIRST + Pending Data is first Byte in BLOCKMODE + [5:5] + + + RXTRIGGER + RX FIFO Above Trigger Level + [6:6] + + + TXTRIGGER + TX FIFO Below Trigger Level + [7:7] + + + + + CLKPRESCALE + Clock Pre Scale divide value + 0x10 + + + IRQ_ENB + Interrupt Enable Register + 0x14 + read-write + 0x00000000 + + + RORIM + RX Overrun + [0:0] + + + RTIM + RX Timeout + [1:1] + + + RXIM + RX Fifo is at least half full + [2:2] + + + TXIM + TX Fifo is at least half empty + [3:3] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x18 + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x1C + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x20 + write-only + oneToClear + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x24 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x28 + + + FIFO_CLR + Clear FIFO Register + 0x2C + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + STATE + Internal STATE of SPI Controller + 0x30 + read-only + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x001207E1 + + + + + SPIB + 0x40051000 + + + SPIC + 0x40052000 + + + I2CA + 1.0 + I2C Peripheral + I2C + 0x40060000 + + 0x0 + 0x1000 + registers + + + + CTRL + Control Register + 0x0 + 0x00000000 + + + CLKENABLED + I2C CLK Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + ALGFILTER + Enable Input Analog Glitch Filter + [5:5] + + + DLGFILTER + Enable Input Digital Glitch Filter + [6:6] + + + LOOPBACK + Enable LoopBack Mode + [8:8] + + + TMCONFIGENB + Enable Timing Config Register + [9:9] + + + + + CLKSCALE + Clock Scale divide value + 0x4 + + + VALUE + Enable FastMode + [30:0] + + + FASTMODE + Enable FastMode + [31:31] + + + + + WORDS + Word Count value + 0x8 + + + ADDRESS + I2C Address value + 0xC + + + DATA + Data Input/Output + 0x10 + + + CMD + Command Register + 0x14 + + + STATUS + I2C Controller Status Register + 0x18 + read-only + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + I2C_IDLE + I2C bus is Idle + 0 + 1 + + + IDLE + Controller is Idle + 1 + 1 + + + + + STATE + Internal STATE of I2C Master Controller + 0x1C + read-only + + + TXCOUNT + TX Count Register + 0x20 + read-only + + + RXCOUNT + RX Count Register + 0x24 + read-only + + + IRQ_ENB + Interrupt Enable Register + 0x28 + read-write + 0x00000000 + + + I2CIDLE + I2C Bus is Idle + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + STALLED + Controller is Stalled + [3:3] + + + ARBLOST + I2C Arbitration was lost + [4:4] + + + NACKADDR + I2C Address was not Acknowledged + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + CLKLOTO + I2C Clock Low Timeout + [7:7] + + + TXOVERFLOW + TX FIFO Overflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + IRQ_RAW + Raw Interrupt Status Register + 0x2C + read-only + + + IRQ_END + Enabled Interrupt Status Register + 0x30 + read-only + + + IRQ_CLR + Clear Interrupt Status Register + 0x34 + write-only + oneToClear + + + RXFIFOIRQTRG + Rx FIFO IRQ Trigger Level + 0x38 + + + TXFIFOIRQTRG + Tx FIFO IRQ Trigger Level + 0x3C + + + FIFO_CLR + Clear FIFO Register + 0x40 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + TMCONFIG + Timing Config Register + 0x44 + + + CLKTOLIMIT + Clock Low Timeout Limit Register + 0x48 + + + S0_CTRL + Slave Control Register + 0x100 + 0x00000000 + + + CLKENABLED + I2C Enabled + [0:0] + + + ENABLED + I2C Activated + [1:1] + + + ENABLE + I2C Active + [2:2] + + + TXFEMD + TX FIFIO Empty Mode + [3:3] + + + RXFFMD + RX FIFO Full Mode + [4:4] + + + + + S0_MAXWORDS + Slave MaxWords Register + 0x104 + + + S0_ADDRESS + Slave I2C Address Value + 0x108 + + + S0_ADDRESSMASK + Slave I2C Address Mask value + 0x10C + + + S0_DATA + Slave Data Input/Output + 0x110 + + + S0_LASTADDRESS + Slave I2C Last Address value + 0x114 + read-only + + + S0_STATUS + Slave I2C Controller Status Register + 0x118 + read-only + 0x00000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + RXNEMPTY + RX FIFO is Not Empty + [8:8] + + + RXFULL + RX FIFO is Full + [9:9] + + + RXTRIGGER + RX FIFO Above Trigger Level + [11:11] + + + TXEMPTY + TX FIFO is Empty + [12:12] + + + TXNFULL + TX FIFO is Full + [13:13] + + + TXTRIGGER + TX FIFO Below Trigger Level + [15:15] + + + RAW_BUSY + I2C Raw Busy value + [29:29] + + + RAW_SDA + I2C Raw SDA value + [30:30] + + + RAW_SCL + I2C Raw SCL value + [31:31] + + + + + S0_STATE + Internal STATE of I2C Slave Controller + 0x11C + read-only + + + S0_TXCOUNT + Slave TX Count Register + 0x120 + read-only + + + S0_RXCOUNT + Slave RX Count Register + 0x124 + read-only + + + S0_IRQ_ENB + Slave Interrupt Enable Register + 0x128 + read-write + 0x00000000 + + + COMPLETED + Controller Complted a Transaction + [0:0] + + + IDLE + Controller is Idle + [1:1] + + + WAITING + Controller is Waiting + [2:2] + + + TXSTALLED + Controller is Tx Stalled + [3:3] + + + RXSTALLED + Controller is Rx Stalled + [4:4] + + + ADDRESSMATCH + I2C Address Match + [5:5] + + + NACKDATA + I2C Data was not Acknowledged + [6:6] + + + RXDATAFIRST + Pending Data is first Byte following Address + [7:7] + + + I2C_START + I2C Start Condition + [8:8] + + + I2C_STOP + I2C Stop Condition + [9:9] + + + TXUNDERFLOW + TX FIFO Underflowed + [10:10] + + + RXOVERFLOW + TX FIFO Overflowed + [11:11] + + + TXREADY + TX FIFO Ready + [12:12] + + + RXREADY + RX FIFO Ready + [13:13] + + + TXEMPTY + TX FIFO Empty + [14:14] + + + RXFULL + RX FIFO Full + [15:15] + + + + + S0_IRQ_RAW + Slave Raw Interrupt Status Register + 0x12C + read-only + + + S0_IRQ_END + Slave Enabled Interrupt Status Register + 0x130 + read-only + + + S0_IRQ_CLR + Slave Clear Interrupt Status Register + 0x134 + write-only + oneToClear + + + S0_RXFIFOIRQTRG + Slave Rx FIFO IRQ Trigger Level + 0x138 + + + S0_TXFIFOIRQTRG + Slave Tx FIFO IRQ Trigger Level + 0x13C + + + S0_FIFO_CLR + Slave Clear FIFO Register + 0x140 + write-only + + + RXFIFO + Clear Rx FIFO + [0:0] + + + TXFIFO + Clear Tx FIFO + [1:1] + + + + + S0_ADDRESSB + Slave I2C Address B Value + 0x144 + + + S0_ADDRESSMASKB + Slave I2C Address B Mask value + 0x148 + + + PERID + Peripheral ID Register + 0xFFC + read-only + 0x001407E1 + + + + + I2CB + 0x40061000 + + + \ No newline at end of file diff --git a/vorago-reb1 b/vorago-reb1 deleted file mode 160000 index bdd804f..0000000 --- a/vorago-reb1 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bdd804f88ba82d3ece4bc68b8cd7d91834e15330 diff --git a/vorago-reb1/.cargo/config.toml b/vorago-reb1/.cargo/config.toml new file mode 100644 index 0000000..dd54ddd --- /dev/null +++ b/vorago-reb1/.cargo/config.toml @@ -0,0 +1,36 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x jlink.gdb" +# runner = "gdb-multiarch -q -x jlink.gdb" +# runner = "gdb -q -x openocd.gdb" + +rustflags = [ + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", "link-arg=--nmagic", + + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # if you run into problems with LLD switch to the GNU linker by commenting out + # this line + # "-C", "linker=arm-none-eabi-ld", + + # if you need to link to pre-compiled C libraries provided by a C toolchain + # use GCC as the linker by commenting out both lines above and then + # uncommenting the three lines below + # "-C", "linker=arm-none-eabi-gcc", + # "-C", "link-arg=-Wl,-Tlink.x", + # "-C", "link-arg=-nostartfiles", +] + +[build] +# Pick ONE of these compilation targets +target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) +# target = "thumbv8m.base-none-eabi" # Cortex-M23 +# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) +# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) \ No newline at end of file diff --git a/vorago-reb1/.github/bors.toml b/vorago-reb1/.github/bors.toml new file mode 100644 index 0000000..1779788 --- /dev/null +++ b/vorago-reb1/.github/bors.toml @@ -0,0 +1,2 @@ +status = ["ci"] +delete_merged_branches = true diff --git a/vorago-reb1/.github/workflows/ci.yml b/vorago-reb1/.github/workflows/ci.yml new file mode 100644 index 0000000..8caa486 --- /dev/null +++ b/vorago-reb1/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +on: [push] + +name: ci + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - uses: actions-rs/cargo@v1 + with: + command: check + - uses: actions-rs/cargo@v1 + with: + command: check + args: --examples + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv6m-none-eabi + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + + ci: + if: ${{ success() }} + # all new jobs must be added to this list + needs: [check, fmt, clippy] + runs-on: ubuntu-latest + steps: + - name: CI succeeded + run: exit 0 \ No newline at end of file diff --git a/vorago-reb1/.gitignore b/vorago-reb1/.gitignore new file mode 100644 index 0000000..22d3516 --- /dev/null +++ b/vorago-reb1/.gitignore @@ -0,0 +1,15 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + + +# Added by cargo + +/target diff --git a/vorago-reb1/CHANGELOG.md b/vorago-reb1/CHANGELOG.md new file mode 100644 index 0000000..d263f10 --- /dev/null +++ b/vorago-reb1/CHANGELOG.md @@ -0,0 +1,35 @@ +Change Log +======= + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [unreleased] + +## [v0.4.0] + +- Update manifest file to have correct links and license +- Update some dependencies + - `cortex-m-rtic` (dev-depencency) to 1.1.2 + - Other dependencies: Only revision has changed + +## [v0.3.2] + +- Bump HAL dependency to v0.5.0. Changed API, especially for IRQ handling + +## [v0.3.1] + +- Updated ADC code and dependency + +## [v0.3.0] + +- Completed baseline features to support all sensors on the REB1 sevice +- Relicensed as Apache-2.0 and moved to https://egit.irs.uni-stuttgart.de/rust/vorago-reb1 + +## [v0.2.3] + +- Added basic accelerometer example. Board in not populated so it is not complete, but + it provides a starting point +- Added ADC base library and example building on the new max116xx-10bit device driver crate diff --git a/vorago-reb1/Cargo.toml b/vorago-reb1/Cargo.toml new file mode 100644 index 0000000..f046493 --- /dev/null +++ b/vorago-reb1/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "vorago-reb1" +version = "0.4.0" +authors = ["Robin Mueller "] +edition = "2021" +description = "Board Support Crate for the Vorago REB1 development board" +homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1" +repository = "https://egit.irs.uni-stuttgart.de/rust/vorago-reb1" +license = "Apache-2.0" +keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"] +categories = ["aerospace", "embedded", "no-std", "hardware-support"] + +[dependencies] +cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7" +embedded-hal = "1" +dummy-pin = "1" + +[dependencies.max116xx-10bit] +version = "0.3" +git = "https://egit.irs.uni-stuttgart.de/rust/max116xx-10bit" +branch = "bump-embedded-hal" + +[dependencies.va108xx-hal] +version = "0.6" +path = "../va108xx-hal" +features = ["rt"] + +[features] +rt = ["va108xx-hal/rt"] + +[dev-dependencies] +cortex-m-rtic = "1.1" +panic-halt = "0.2" +nb = "1" + +[dev-dependencies.rtt-target] +version = "0.5" + +[dev-dependencies.panic-rtt-target] +version = "0.1" diff --git a/vorago-reb1/LICENSE-APACHE b/vorago-reb1/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vorago-reb1/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/vorago-reb1/NOTICE b/vorago-reb1/NOTICE new file mode 100644 index 0000000..d23e5ce --- /dev/null +++ b/vorago-reb1/NOTICE @@ -0,0 +1,3 @@ +Rust Board Support Package (HAL) crate for the Vorago REB1 development board + +This software contains code developed at the University of Stuttgart. \ No newline at end of file diff --git a/vorago-reb1/README.md b/vorago-reb1/README.md new file mode 100644 index 0000000..65331b2 --- /dev/null +++ b/vorago-reb1/README.md @@ -0,0 +1,83 @@ +[![Crates.io](https://img.shields.io/crates/v/vorago-reb1)](https://crates.io/crates/vorago-reb1) +[![ci](https://github.com/us-irs/vorago-reb1-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/us-irs/vorago-reb1-rs/actions/workflows/ci.yml) +[![docs.rs](https://img.shields.io/docsrs/vorago-reb1)](https://docs.rs/vorago-reb1) + +# Rust BSP for the Vorago REB1 development board + +This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board. +Its aim is to provide drivers for the board features of the REB1 board + +The BSP builds on top of the [HAL crate for VA108xx devices](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal). + +## Building + +Building an application requires the `thumbv6m-none-eabi` cross-compiler toolchain. +If you have not installed it yet, you can do so with + +```sh +rustup target add thumbv6m-none-eabi +``` + +This repository provides some example applications to show how the BSP is used. For example +you can build the blinky example with + +```sh +cargo build --example blinky-leds +``` + +If you have not done this yet, it is recommended to read some of the excellent resources +available to learn Rust: + +- [Rust Embedded Book](https://docs.rust-embedded.org/book/) +- [Rust Discovery Book](https://docs.rust-embedded.org/discovery/) + +## Flashing from the command line + +A `jlink.gdb` file is provided to allow flashing of the board from the command line. + + +1. Ensure that you have a suitable GDB application like `arm-none-eabi-gdb` or `gdb-multiarch` + installed first. On Windows, you can use [xPacks](https://xpack.github.io/arm-none-eabi-gcc/). + On Linux, you can install `gdb-multiarch` from the package manager. + +2. Install the [JLink Tools](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack). + +3. Start the JLink GDB server with the GUI or from the command line. The device should be recognized + automatically + +4. Make sure to select an appropriate runner in the `.cargo/config.toml` file depending on which + GDB application you are using + +5. Use + + ```sh + cargo run --example blinky-leds + ``` + + to flash the board. The debugger should stop at the start of the main. + +## Debugging with VS Code + +The REB1 board features an on-board JTAG, so all that is required to debug the board is a +Micro-USB cable. + +You can debug applications on the REB1 board with a graphical user interface using VS Code with +the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug). + +Some sample configuration files for VS code were provided as well. You can simply use `Run and Debug` +to automatically rebuild and flash your application. + +The `tasks.json` and the `launch.json` files are generic and you can use them immediately by +opening the folder in VS code or adding it to a workspace. + +If you would like to use a custom GDB application, you can specify the gdb binary in the following +configuration variables in your `settings.json`: + +- `"cortex-debug.gdbPath"` +- `"cortex-debug.gdbPath.linux"` +- `"cortex-debug.gdbPath.windows"` +- `"cortex-debug.gdbPath.osx"` + +## Flashing the non-volatile memory + +Coming Soon diff --git a/vorago-reb1/automation/Dockerfile b/vorago-reb1/automation/Dockerfile new file mode 100644 index 0000000..5fb8a3d --- /dev/null +++ b/vorago-reb1/automation/Dockerfile @@ -0,0 +1,11 @@ +# Run the following commands from root directory to build and run locally +# docker build -f automation/Dockerfile -t . +# docker run -it +FROM rust:latest +RUN apt-get update +RUN apt-get --yes upgrade +# tzdata is a dependency, won't install otherwise +ARG DEBIAN_FRONTEND=noninteractive + +RUN rustup target add thumbv6m-none-eabi && \ + rustup component add rustfmt clippy diff --git a/vorago-reb1/automation/Jenkinsfile b/vorago-reb1/automation/Jenkinsfile new file mode 100644 index 0000000..c67b034 --- /dev/null +++ b/vorago-reb1/automation/Jenkinsfile @@ -0,0 +1,50 @@ +pipeline { + agent any + + stages { + stage('Clippy') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo clippy' + } + } + stage('Rustfmt') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo fmt' + } + } + stage('Check') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo check --target thumbv6m-none-eabi' + } + } + stage('Check Examples') { + agent { + dockerfile { + dir 'automation' + reuseNode true + } + } + steps { + sh 'cargo check --target thumbv6m-none-eabi --examples' + } + } + } +} \ No newline at end of file diff --git a/vorago-reb1/examples/adt75-temp-sensor.rs b/vorago-reb1/examples/adt75-temp-sensor.rs new file mode 100644 index 0000000..9326643 --- /dev/null +++ b/vorago-reb1/examples/adt75-temp-sensor.rs @@ -0,0 +1,25 @@ +#![no_main] +#![no_std] +use cortex_m_rt::entry; +use embedded_hal::delay::DelayNs; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{pac, prelude::*, timer::set_up_ms_delay_provider}; +use vorago_reb1::temp_sensor::Adt75TempSensor; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- Vorago Temperature Sensor and I2C Example --"); + let mut dp = pac::Peripherals::take().unwrap(); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + let mut temp_sensor = Adt75TempSensor::new(dp.i2ca, 50.MHz(), Some(&mut dp.sysconfig)) + .expect("Creating temperature sensor struct failed"); + loop { + let temp = temp_sensor + .read_temperature() + .expect("Failed reading temperature"); + rprintln!("Temperature in Celcius: {}", temp); + delay.delay_ms(500); + } +} diff --git a/vorago-reb1/examples/adxl343-accelerometer.rs b/vorago-reb1/examples/adxl343-accelerometer.rs new file mode 100644 index 0000000..5bd6a9a --- /dev/null +++ b/vorago-reb1/examples/adxl343-accelerometer.rs @@ -0,0 +1,78 @@ +//! ADXL343 accelerometer example +//! +//! Please note that the default REB1 board is not populated with the ADXL343BCCZ-RL7. +//! To use this example, this chip needs to be soldered onto the board. +#![no_main] +#![no_std] +use cortex_m_rt::entry; +use embedded_hal::spi::SpiBus; +use embedded_hal::{delay::DelayNs, digital::OutputPin}; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + gpio::PinsA, + pac, + prelude::*, + spi::{Spi, SpiConfig, TransferConfig}, + timer::set_up_ms_delay_provider, +}; + +const READ_MASK: u8 = 1 << 7; +const _MULTI_BYTE_MASK: u8 = 1 << 6; +const DEVID_REG: u8 = 0x00; + +const POWER_CTL_REG: u8 = 0x2D; +const PWR_MEASUREMENT_MODE_MASK: u8 = 1 << 3; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- Vorago Accelerometer Example --"); + let mut dp = pac::Peripherals::take().unwrap(); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); + let spi_cfg = SpiConfig::default(); + let (sck, mosi, miso) = ( + pinsa.pa20.into_funsel_2(), + pinsa.pa19.into_funsel_2(), + pinsa.pa18.into_funsel_2(), + ); + let cs_pin = pinsa.pa16.into_funsel_2(); + + // Need to set the ADC chip select low + let mut adc_cs = pinsa.pa17.into_push_pull_output(); + adc_cs + .set_high() + .expect("Setting ADC chip select high failed"); + + let transfer_cfg = TransferConfig::new( + 1.MHz(), + embedded_hal::spi::MODE_3, + Some(cs_pin), + false, + true, + ); + let mut spi = Spi::spib( + dp.spib, + (sck, miso, mosi), + 50.MHz(), + spi_cfg, + Some(&mut dp.sysconfig), + Some(&transfer_cfg.downgrade()), + ); + + let mut tx_rx_buf: [u8; 3] = [0; 3]; + tx_rx_buf[0] = READ_MASK | DEVID_REG; + spi.transfer_in_place(&mut tx_rx_buf[0..2]) + .expect("Reading DEVID register failed"); + rprintln!("DEVID register: {}", tx_rx_buf[1]); + + tx_rx_buf[0] = POWER_CTL_REG; + tx_rx_buf[1] = PWR_MEASUREMENT_MODE_MASK; + spi.write(&tx_rx_buf[0..2]) + .expect("Enabling measurement mode failed"); + + loop { + delay.delay_ms(500); + } +} diff --git a/vorago-reb1/examples/blinky-button-irq.rs b/vorago-reb1/examples/blinky-button-irq.rs new file mode 100644 index 0000000..0f29f5f --- /dev/null +++ b/vorago-reb1/examples/blinky-button-irq.rs @@ -0,0 +1,106 @@ +//! Blinky button application for the REB1 board +#![no_main] +#![no_std] + +use core::cell::RefCell; + +use cortex_m::interrupt::Mutex; +use cortex_m_rt::entry; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + clock::{set_clk_div_register, FilterClkSel}, + gpio::{FilterType, InterruptEdge, PinsA}, + pac::{self, interrupt}, + prelude::*, + timer::{default_ms_irq_handler, set_up_ms_tick, IrqCfg}, +}; +use vorago_reb1::button::Button; +use vorago_reb1::leds::Leds; + +static LEDS: Mutex>> = Mutex::new(RefCell::new(None)); +static BUTTON: Mutex>> = Mutex::new(RefCell::new(None)); + +#[derive(Debug, PartialEq)] +pub enum PressMode { + Toggle, + Keep, +} + +// You can change the press mode here +const PRESS_MODE: PressMode = PressMode::Keep; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- Vorago Button IRQ Example --"); + let mut dp = pac::Peripherals::take().unwrap(); + let pinsa = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let edge_irq = match PRESS_MODE { + PressMode::Toggle => InterruptEdge::HighToLow, + PressMode::Keep => InterruptEdge::BothEdges, + }; + + // Configure an edge interrupt on the button and route it to interrupt vector 15 + let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq( + edge_irq, + IrqCfg::new(pac::interrupt::OC15, true, true), + Some(&mut dp.sysconfig), + Some(&mut dp.irqsel), + ); + + if PRESS_MODE == PressMode::Toggle { + // This filter debounces the switch for edge based interrupts + button = button.filter_type(FilterType::FilterFourClockCycles, FilterClkSel::Clk1); + set_clk_div_register(&mut dp.sysconfig, FilterClkSel::Clk1, 50_000); + } + + set_up_ms_tick( + IrqCfg::new(pac::Interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + let mut leds = Leds::new( + pinsa.pa10.into_push_pull_output(), + pinsa.pa7.into_push_pull_output(), + pinsa.pa6.into_push_pull_output(), + ); + for led in leds.iter_mut() { + led.off(); + } + // Make both button and LEDs accessible from the IRQ handler as well + cortex_m::interrupt::free(|cs| { + LEDS.borrow(cs).replace(Some(leds)); + BUTTON.borrow(cs).replace(Some(button)); + }); + loop { + cortex_m::asm::nop(); + } +} + +#[interrupt] +fn OC0() { + default_ms_irq_handler(); +} + +#[interrupt] +fn OC15() { + cortex_m::interrupt::free(|cs| { + if PRESS_MODE == PressMode::Toggle { + if let Some(ref mut leds) = LEDS.borrow(cs).borrow_mut().as_deref_mut() { + leds[0].toggle(); + } + } else if let (Some(ref mut leds), Some(ref mut button)) = ( + LEDS.borrow(cs).borrow_mut().as_deref_mut(), + BUTTON.borrow(cs).borrow_mut().as_mut(), + ) { + if button.released() { + leds[0].off(); + } else { + leds[0].on(); + } + } + }); +} diff --git a/vorago-reb1/examples/blinky-button-rtic.rs b/vorago-reb1/examples/blinky-button-rtic.rs new file mode 100644 index 0000000..ecfa587 --- /dev/null +++ b/vorago-reb1/examples/blinky-button-rtic.rs @@ -0,0 +1,144 @@ +//! Blinky button application for the REB1 board using RTIC +#![no_main] +#![no_std] + +#[rtic::app(device = pac)] +mod app { + use panic_rtt_target as _; + use rtt_target::{rprintln, rtt_init_default, set_print_channel}; + use va108xx_hal::{ + clock::{set_clk_div_register, FilterClkSel}, + gpio::{FilterType, InterruptEdge, PinsA}, + pac, + prelude::*, + timer::{default_ms_irq_handler, set_up_ms_tick, IrqCfg}, + }; + use vorago_reb1::button::Button; + use vorago_reb1::leds::Leds; + + #[derive(Debug, PartialEq)] + pub enum PressMode { + Toggle, + Keep, + } + + #[derive(Debug, PartialEq)] + pub enum CfgMode { + Prompt, + Fixed, + } + + const CFG_MODE: CfgMode = CfgMode::Fixed; + // You can change the press mode here + const DEFAULT_MODE: PressMode = PressMode::Toggle; + + #[local] + struct Local { + leds: Leds, + button: Button, + mode: PressMode, + } + + #[shared] + struct Shared {} + + #[init] + fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) { + let channels = rtt_init_default!(); + set_print_channel(channels.up.0); + rprintln!("-- Vorago Button IRQ Example --"); + let mode = match CFG_MODE { + // Ask mode from user via RTT + CfgMode::Prompt => prompt_mode(channels.down.0), + // Use mode hardcoded in `DEFAULT_MODE` + CfgMode::Fixed => DEFAULT_MODE, + }; + rprintln!("Using {:?} mode", mode); + + let mut dp = ctx.device; + let pinsa = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let edge_irq = match mode { + PressMode::Toggle => InterruptEdge::HighToLow, + PressMode::Keep => InterruptEdge::BothEdges, + }; + + // Configure an edge interrupt on the button and route it to interrupt vector 15 + let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq( + edge_irq, + IrqCfg::new(pac::interrupt::OC15, true, true), + Some(&mut dp.sysconfig), + Some(&mut dp.irqsel), + ); + + if mode == PressMode::Toggle { + // This filter debounces the switch for edge based interrupts + button = button.filter_type(FilterType::FilterFourClockCycles, FilterClkSel::Clk1); + set_clk_div_register(&mut dp.sysconfig, FilterClkSel::Clk1, 50_000); + } + let mut leds = Leds::new( + pinsa.pa10.into_push_pull_output(), + pinsa.pa7.into_push_pull_output(), + pinsa.pa6.into_push_pull_output(), + ); + for led in leds.iter_mut() { + led.off(); + } + set_up_ms_tick( + IrqCfg::new(pac::Interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + (Shared {}, Local { leds, button, mode }, init::Monotonics()) + } + + // `shared` cannot be accessed from this context + #[idle] + fn idle(_cx: idle::Context) -> ! { + loop { + cortex_m::asm::nop(); + } + } + + #[task(binds = OC15, local=[button, leds, mode])] + fn button_task(cx: button_task::Context) { + let leds = cx.local.leds; + let button = cx.local.button; + let mode = cx.local.mode; + if *mode == PressMode::Toggle { + leds[0].toggle(); + } else { + if button.released() { + leds[0].off(); + } else { + leds[0].on(); + } + } + } + + #[task(binds = OC0)] + fn ms_tick(_cx: ms_tick::Context) { + default_ms_irq_handler(); + } + + fn prompt_mode(mut down_channel: rtt_target::DownChannel) -> PressMode { + rprintln!("Using prompt mode"); + rprintln!("Please enter the mode [0: Toggle, 1: Keep]"); + let mut read_buf: [u8; 16] = [0; 16]; + let mut read; + loop { + read = down_channel.read(&mut read_buf); + for i in 0..read { + let val = read_buf[i] as char; + if val == '0' || val == '1' { + return if val == '0' { + PressMode::Toggle + } else { + PressMode::Keep + }; + } + } + } + } +} diff --git a/vorago-reb1/examples/blinky-leds.rs b/vorago-reb1/examples/blinky-leds.rs new file mode 100644 index 0000000..4e28871 --- /dev/null +++ b/vorago-reb1/examples/blinky-leds.rs @@ -0,0 +1,115 @@ +//! Blinky examples using the PAC directly, the HAL, or the BSP +//! +//! Additional note on LEDs: +//! Be not afraid: Pulling the GPIOs low makes the LEDs blink. See REB1 +//! schematic for more details. +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::delay::DelayNs; +use embedded_hal::digital::{OutputPin, StatefulOutputPin}; +use panic_halt as _; +use va108xx_hal::{gpio::pins::PinsA, pac, prelude::*, timer::set_up_ms_delay_provider}; +use vorago_reb1::leds::Leds; + +// REB LED pin definitions. All on port A +const LED_D2: u32 = 1 << 10; +const LED_D3: u32 = 1 << 7; +const LED_D4: u32 = 1 << 6; + +#[allow(dead_code)] +enum LibType { + Pac, + Hal, + Bsp, +} + +#[entry] +fn main() -> ! { + let mut dp = pac::Peripherals::take().unwrap(); + + let lib_type = LibType::Bsp; + + match lib_type { + LibType::Pac => { + // Enable all peripheral clocks + dp.sysconfig + .peripheral_clk_enable() + .modify(|_, w| unsafe { w.bits(0xffffffff) }); + dp.porta + .dir() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + dp.porta + .datamask() + .modify(|_, w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + for _ in 0..10 { + dp.porta + .clrout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + dp.porta + .setout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(5_000_000); + } + loop { + dp.porta + .togout() + .write(|w| unsafe { w.bits(LED_D2 | LED_D3 | LED_D4) }); + cortex_m::asm::delay(25_000_000); + } + } + LibType::Hal => { + let pins = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let mut led1 = pins.pa10.into_readable_push_pull_output(); + let mut led2 = pins.pa7.into_readable_push_pull_output(); + let mut led3 = pins.pa6.into_readable_push_pull_output(); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + for _ in 0..10 { + led1.set_low().ok(); + led2.set_low().ok(); + led3.set_low().ok(); + delay.delay_ms(200); + led1.set_high().ok(); + led2.set_high().ok(); + led3.set_high().ok(); + delay.delay_ms(200); + } + loop { + led1.toggle().ok(); + delay.delay_ms(200); + led2.toggle().ok(); + delay.delay_ms(200); + // Alternatively use deidscted register. + led3.toggle_with_toggle_reg(); + delay.delay_ms(200); + } + } + LibType::Bsp => { + let pinsa = PinsA::new(&mut dp.sysconfig, Some(dp.ioconfig), dp.porta); + let mut leds = Leds::new( + pinsa.pa10.into_push_pull_output(), + pinsa.pa7.into_push_pull_output(), + pinsa.pa6.into_push_pull_output(), + ); + let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); + loop { + for _ in 0..10 { + // Blink all LEDs quickly + for led in leds.iter_mut() { + led.toggle(); + } + delay.delay_ms(500); + } + // Now use a wave pattern + loop { + for led in leds.iter_mut() { + led.toggle(); + delay.delay_ms(200); + } + } + } + } + } +} diff --git a/vorago-reb1/examples/max11619-adc.rs b/vorago-reb1/examples/max11619-adc.rs new file mode 100644 index 0000000..73eda4e --- /dev/null +++ b/vorago-reb1/examples/max11619-adc.rs @@ -0,0 +1,345 @@ +//! MAX11619 ADC example applikcation +#![no_main] +#![no_std] + +use core::convert::Infallible; + +use cortex_m_rt::entry; +use embedded_hal::digital::OutputPin; +use embedded_hal::spi::{SpiBus, SpiDevice}; +use embedded_hal::{delay::DelayNs, spi}; +use max116xx_10bit::VoltageRefMode; +use max116xx_10bit::{AveragingConversions, AveragingResults}; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::spi::{NoneT, OptionalHwCs}; +use va108xx_hal::timer::CountDownTimer; +use va108xx_hal::{ + gpio::PinsA, + pac::{self, interrupt}, + prelude::*, + spi::{Spi, SpiBase, SpiConfig, TransferConfig}, + timer::{default_ms_irq_handler, set_up_ms_tick, DelayMs, IrqCfg}, +}; +use va108xx_hal::{port_mux, FunSel, PortSel}; +use vorago_reb1::max11619::{ + max11619_externally_clocked_no_wakeup, max11619_externally_clocked_with_wakeup, + max11619_internally_clocked, EocPin, AN2_CHANNEL, POTENTIOMETER_CHANNEL, +}; + +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum ExampleMode { + UsingEoc, + NotUsingEoc, + NotUsingEocWithDelay, +} + +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum ReadMode { + Single, + Multiple, + MultipleNToHighest, + AverageN, +} + +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum MuxMode { + None, + PortB19to17, +} + +const EXAMPLE_MODE: ExampleMode = ExampleMode::NotUsingEoc; +const READ_MODE: ReadMode = ReadMode::Multiple; +const MUX_MODE: MuxMode = MuxMode::None; + +// This is probably more or less a re-implementation of https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice.html. +// Users should look at the embedded-hal-bus crate for sharing the bus. +pub struct SpiWithHwCs { + inner: SpiBase, + delay_provider: Delay, + hw_cs: HwCs, +} + +impl> SpiWithHwCs { + pub fn new(spi: SpiBase, hw_cs: HwCs, delay_provider: Delay) -> Self { + Self { + inner: spi, + hw_cs, + delay_provider, + } + } +} + +impl embedded_hal::spi::ErrorType for SpiWithHwCs { + type Error = Infallible; +} + +impl> SpiDevice for SpiWithHwCs { + fn transaction( + &mut self, + operations: &mut [spi::Operation<'_, u8>], + ) -> Result<(), Self::Error> { + // Only the HW CS is configured here. This is not really necessary, but showcases + // that we could scale this multiple SPI devices. + self.inner.cfg_hw_cs_with_pin(&self.hw_cs); + for operation in operations { + match operation { + spi::Operation::Read(buf) => self.inner.read(buf).ok().unwrap(), + spi::Operation::Write(buf) => self.inner.write(buf).ok().unwrap(), + spi::Operation::Transfer(read, write) => { + self.inner.transfer(read, write).ok().unwrap() + } + spi::Operation::TransferInPlace(buf) => { + self.inner.transfer_in_place(buf).ok().unwrap() + } + spi::Operation::DelayNs(delay) => self.delay_provider.delay_ns(*delay), + }; + } + self.inner.cfg_hw_cs_disable(); + Ok(()) + } +} + +#[entry] +fn main() -> ! { + rtt_init_print!(); + rprintln!("-- Vorago ADC Example --"); + + let mut dp = pac::Peripherals::take().unwrap(); + let tim0 = set_up_ms_tick( + IrqCfg::new(pac::Interrupt::OC0, true, true), + &mut dp.sysconfig, + Some(&mut dp.irqsel), + 50.MHz(), + dp.tim0, + ); + let delay = DelayMs::new(tim0).unwrap(); + unsafe { + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); + } + + let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); + let spi_cfg = SpiConfig::default(); + let (sck, mosi, miso) = ( + pinsa.pa20.into_funsel_2(), + pinsa.pa19.into_funsel_2(), + pinsa.pa18.into_funsel_2(), + ); + + if MUX_MODE == MuxMode::PortB19to17 { + port_mux(&mut dp.ioconfig, PortSel::PortB, 19, FunSel::Sel1).ok(); + port_mux(&mut dp.ioconfig, PortSel::PortB, 18, FunSel::Sel2).ok(); + port_mux(&mut dp.ioconfig, PortSel::PortB, 17, FunSel::Sel1).ok(); + port_mux(&mut dp.ioconfig, PortSel::PortB, 16, FunSel::Sel1).ok(); + } + // Set the accelerometer chip select low in case the board slot is populated + let mut accel_cs = pinsa.pa16.into_push_pull_output(); + accel_cs + .set_high() + .expect("Setting accelerometer chip select high failed"); + + let transfer_cfg = TransferConfig::::new(3.MHz(), spi::MODE_0, None, true, false); + let spi = Spi::spib( + dp.spib, + (sck, miso, mosi), + 50.MHz(), + spi_cfg, + Some(&mut dp.sysconfig), + Some(&transfer_cfg.downgrade()), + ) + .downgrade(); + let delay_provider = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1); + let spi_with_hwcs = SpiWithHwCs::new(spi, pinsa.pa17.into_funsel_2(), delay_provider); + match EXAMPLE_MODE { + ExampleMode::NotUsingEoc => spi_example_externally_clocked(spi_with_hwcs, delay), + ExampleMode::UsingEoc => { + spi_example_internally_clocked(spi_with_hwcs, delay, pinsa.pa14.into_floating_input()); + } + ExampleMode::NotUsingEocWithDelay => { + let delay_us = CountDownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim2); + spi_example_externally_clocked_with_delay(spi_with_hwcs, delay, delay_us); + } + } +} + +#[interrupt] +#[allow(non_snake_case)] +fn OC0() { + default_ms_irq_handler(); +} + +/// Use the SPI clock as the conversion clock +fn spi_example_externally_clocked(spi: impl SpiDevice, mut delay: DelayMs) -> ! { + let mut adc = max11619_externally_clocked_no_wakeup(spi) + .expect("Creating externally clocked MAX11619 device failed"); + if READ_MODE == ReadMode::AverageN { + adc.averaging( + AveragingConversions::FourConversions, + AveragingResults::FourResults, + ) + .expect("Error setting up averaging register"); + } + let mut cmd_buf: [u8; 32] = [0; 32]; + let mut counter = 0; + loop { + rprintln!("-- Measurement {} --", counter); + + match READ_MODE { + ReadMode::Single => { + rprintln!("Reading single potentiometer channel"); + let pot_val = adc + .read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL) + .expect("Creating externally clocked MAX11619 ADC failed"); + rprintln!("Single channel read:"); + rprintln!("\tPotentiometer value: {}", pot_val); + } + ReadMode::Multiple => { + let mut res_buf: [u16; 4] = [0; 4]; + adc.read_multiple_channels_0_to_n( + &mut cmd_buf, + &mut res_buf.iter_mut(), + POTENTIOMETER_CHANNEL, + ) + .expect("Multi-Channel read failed"); + print_res_buf(&res_buf); + } + ReadMode::MultipleNToHighest => { + let mut res_buf: [u16; 2] = [0; 2]; + adc.read_multiple_channels_n_to_highest( + &mut cmd_buf, + &mut res_buf.iter_mut(), + AN2_CHANNEL, + ) + .expect("Multi-Channel read failed"); + rprintln!("Multi channel read from 2 to 3:"); + rprintln!("\tAN2 value: {}", res_buf[0]); + rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]); + } + ReadMode::AverageN => { + rprintln!("Scanning and averaging not possible for externally clocked mode"); + } + } + counter += 1; + delay.delay_ms(500); + } +} + +fn spi_example_externally_clocked_with_delay( + spi: impl SpiDevice, + mut delay: DelayMs, + mut delay_us: impl DelayNs, +) -> ! { + let mut adc = + max11619_externally_clocked_with_wakeup(spi).expect("Creating MAX116xx device failed"); + let mut cmd_buf: [u8; 32] = [0; 32]; + let mut counter = 0; + loop { + rprintln!("-- Measurement {} --", counter); + + match READ_MODE { + ReadMode::Single => { + rprintln!("Reading single potentiometer channel"); + let pot_val = adc + .read_single_channel(&mut cmd_buf, POTENTIOMETER_CHANNEL, &mut delay_us) + .expect("Creating externally clocked MAX11619 ADC failed"); + rprintln!("Single channel read:"); + rprintln!("\tPotentiometer value: {}", pot_val); + } + ReadMode::Multiple => { + let mut res_buf: [u16; 4] = [0; 4]; + adc.read_multiple_channels_0_to_n( + &mut cmd_buf, + &mut res_buf.iter_mut(), + POTENTIOMETER_CHANNEL, + &mut delay_us, + ) + .expect("Multi-Channel read failed"); + print_res_buf(&res_buf); + } + ReadMode::MultipleNToHighest => { + let mut res_buf: [u16; 2] = [0; 2]; + adc.read_multiple_channels_n_to_highest( + &mut cmd_buf, + &mut res_buf.iter_mut(), + AN2_CHANNEL, + &mut delay_us, + ) + .expect("Multi-Channel read failed"); + rprintln!("Multi channel read from 2 to 3:"); + rprintln!("\tAN2 value: {}", res_buf[0]); + rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]); + } + ReadMode::AverageN => { + rprintln!("Scanning and averaging not possible for externally clocked mode"); + } + } + counter += 1; + delay.delay_ms(500); + } +} + +/// This function uses the EOC pin to determine whether the conversion finished +fn spi_example_internally_clocked(spi: impl SpiDevice, mut delay: DelayMs, eoc_pin: EocPin) -> ! { + let mut adc = max11619_internally_clocked( + spi, + eoc_pin, + VoltageRefMode::ExternalSingleEndedNoWakeupDelay, + ) + .expect("Creating MAX116xx device failed"); + let mut counter = 0; + loop { + rprintln!("-- Measurement {} --", counter); + + match READ_MODE { + ReadMode::Single => { + adc.request_single_channel(POTENTIOMETER_CHANNEL) + .expect("Requesting single channel value failed"); + + let pot_val = nb::block!(adc.get_single_channel()) + .expect("Reading single channel value failed"); + rprintln!("\tPotentiometer value: {}", pot_val); + } + ReadMode::Multiple => { + adc.request_multiple_channels_0_to_n(POTENTIOMETER_CHANNEL) + .expect("Requesting single channel value failed"); + let mut res_buf: [u16; 4] = [0; 4]; + nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut())) + .expect("Requesting multiple channel values failed"); + print_res_buf(&res_buf); + } + ReadMode::MultipleNToHighest => { + adc.request_multiple_channels_n_to_highest(AN2_CHANNEL) + .expect("Requesting single channel value failed"); + let mut res_buf: [u16; 4] = [0; 4]; + nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut())) + .expect("Requesting multiple channel values failed"); + rprintln!("Multi channel read from 2 to 3:"); + rprintln!("\tAN2 value: {}", res_buf[0]); + rprintln!("\tAN3 / Potentiometer value: {}", res_buf[1]); + } + ReadMode::AverageN => { + adc.request_channel_n_repeatedly(POTENTIOMETER_CHANNEL) + .expect("Reading channel multiple times failed"); + let mut res_buf: [u16; 16] = [0; 16]; + nb::block!(adc.get_multi_channel(&mut res_buf.iter_mut())) + .expect("Requesting multiple channel values failed"); + rprintln!("Reading potentiometer 4 times"); + rprintln!("\tValue 0: {}", res_buf[0]); + rprintln!("\tValue 1: {}", res_buf[1]); + rprintln!("\tValue 2: {}", res_buf[2]); + rprintln!("\tValue 3: {}", res_buf[3]); + } + } + + counter += 1; + delay.delay_ms(500); + } +} + +fn print_res_buf(buf: &[u16; 4]) { + rprintln!("Multi channel read from 0 to 3:"); + rprintln!("\tAN0 value: {}", buf[0]); + rprintln!("\tAN1 value: {}", buf[1]); + rprintln!("\tAN2 value: {}", buf[2]); + rprintln!("\tAN3 / Potentiometer value: {}", buf[3]); +} diff --git a/vorago-reb1/jlink.gdb b/vorago-reb1/jlink.gdb new file mode 100644 index 0000000..20ff2d5 --- /dev/null +++ b/vorago-reb1/jlink.gdb @@ -0,0 +1,10 @@ +target remote localhost:2331 + +monitor reset + +# *try* to stop at the user entry point (it might be gone due to inlining) +break main + +load + +continue diff --git a/vorago-reb1/memory.x b/vorago-reb1/memory.x new file mode 100644 index 0000000..1ca0e97 --- /dev/null +++ b/vorago-reb1/memory.x @@ -0,0 +1,10 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128K */ + RAM : ORIGIN = 0x10000000, LENGTH = 0x08000 /* 32K */ +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/vorago-reb1/src/button.rs b/vorago-reb1/src/button.rs new file mode 100644 index 0000000..b191829 --- /dev/null +++ b/vorago-reb1/src/button.rs @@ -0,0 +1,66 @@ +//! # API for the REB1 button +//! +//! ## Examples +//! +//! - [Button Blinky with IRQs](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-irq.rs) +//! - [Button Blinky with IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-rtic.rs) +use embedded_hal::digital::InputPin; +use va108xx_hal::{ + gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11}, + pac, IrqCfg, +}; + +pub struct Button { + button: Pin, +} + +impl Button { + pub fn new(pin: Pin) -> Button { + Button { button: pin } + } + + #[inline] + pub fn pressed(&mut self) -> bool { + self.button.is_low().ok().unwrap() + } + + #[inline] + pub fn released(&mut self) -> bool { + self.button.is_high().ok().unwrap() + } + + /// Configures an IRQ on edge. + pub fn edge_irq( + mut self, + edge_type: InterruptEdge, + irq_cfg: IrqCfg, + syscfg: Option<&mut pac::Sysconfig>, + irqsel: Option<&mut pac::Irqsel>, + ) -> Self { + self.button = self + .button + .interrupt_edge(edge_type, irq_cfg, syscfg, irqsel); + self + } + + /// Configures an IRQ on level. + pub fn level_irq( + mut self, + level: InterruptLevel, + irq_cfg: IrqCfg, + syscfg: Option<&mut pac::Sysconfig>, + irqsel: Option<&mut pac::Irqsel>, + ) -> Self { + self.button = self.button.interrupt_level(level, irq_cfg, syscfg, irqsel); + self + } + + /// Configures a filter on the button. This can be useful for debouncing the switch. + /// + /// Please note that you still have to set a clock divisor yourself using the + /// [`va108xx_hal::clock::set_clk_div_register`] function in order for this to work. + pub fn filter_type(mut self, filter: FilterType, clksel: FilterClkSel) -> Self { + self.button = self.button.filter_type(filter, clksel); + self + } +} diff --git a/vorago-reb1/src/leds.rs b/vorago-reb1/src/leds.rs new file mode 100644 index 0000000..36e2246 --- /dev/null +++ b/vorago-reb1/src/leds.rs @@ -0,0 +1,96 @@ +//! # API for using the REB1 LEDs +//! +//! ## Examples +//! +//! - [LED example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-leds.rs) +//! - [Button Blinky using IRQs](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-irq.rs) +//! - [Button Blinky using IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-rtic.rs) +use embedded_hal::digital::OutputPin; +use va108xx_hal::{ + gpio::dynpins::DynPin, + gpio::pins::{Pin, PushPullOutput, PA10, PA6, PA7}, +}; + +pub type LD2 = Pin; +pub type LD3 = Pin; +pub type LD4 = Pin; + +pub struct Leds { + leds: [Led; 3], +} + +impl Leds { + pub fn new(led_pin1: LD2, led_pin2: LD3, led_pin3: LD4) -> Leds { + Leds { + leds: [led_pin1.into(), led_pin2.into(), led_pin3.into()], + } + } +} + +impl core::ops::Deref for Leds { + type Target = [Led]; + + fn deref(&self) -> &[Led] { + &self.leds + } +} + +impl core::ops::DerefMut for Leds { + fn deref_mut(&mut self) -> &mut [Led] { + &mut self.leds + } +} + +impl core::ops::Index for Leds { + type Output = Led; + + fn index(&self, i: usize) -> &Led { + &self.leds[i] + } +} + +impl core::ops::IndexMut for Leds { + fn index_mut(&mut self, i: usize) -> &mut Led { + &mut self.leds[i] + } +} + +pub struct Led { + pin: DynPin, +} + +macro_rules! ctor { + ($($ldx:ident),+) => { + $( + impl From<$ldx> for Led { + fn from(led: $ldx) -> Self { + Led { + pin: led.into() + } + } + } + )+ + } +} + +ctor!(LD2, LD3, LD4); + +impl Led { + /// Turns the LED off. Setting the pin high actually turns the LED off + #[inline] + pub fn off(&mut self) { + self.pin.set_high().ok(); + } + + /// Turns the LED on. Setting the pin low actually turns the LED on + #[inline] + pub fn on(&mut self) { + self.pin.set_low().ok(); + } + + /// Toggles the LED + #[inline] + pub fn toggle(&mut self) { + self.pin.toggle_with_toggle_reg().ok(); + } +} diff --git a/vorago-reb1/src/lib.rs b/vorago-reb1/src/lib.rs new file mode 100644 index 0000000..e2fd4e2 --- /dev/null +++ b/vorago-reb1/src/lib.rs @@ -0,0 +1,6 @@ +#![no_std] + +pub mod button; +pub mod leds; +pub mod max11619; +pub mod temp_sensor; diff --git a/vorago-reb1/src/max11619.rs b/vorago-reb1/src/max11619.rs new file mode 100644 index 0000000..ff2f9ee --- /dev/null +++ b/vorago-reb1/src/max11619.rs @@ -0,0 +1,55 @@ +//! This module provides a thin REB1 specific layer on top of the `max116xx_10bit` driver crate +//! +//! ## Examples +//! +//! - [ADC example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/max11619-adc.rs) +use core::convert::Infallible; +use embedded_hal::spi::SpiDevice; +use max116xx_10bit::{ + Error, ExternallyClocked, InternallyClockedInternallyTimedSerialInterface, Max116xx10Bit, + Max116xx10BitEocExt, VoltageRefMode, WithWakeupDelay, WithoutWakeupDelay, +}; +use va108xx_hal::gpio::{Floating, Input, Pin, PA14}; + +pub type Max11619ExternallyClockedNoWakeup = + Max116xx10Bit; +pub type Max11619ExternallyClockedWithWakeup = + Max116xx10Bit; +pub type Max11619InternallyClocked = + Max116xx10BitEocExt; +pub type EocPin = Pin>; + +pub const AN0_CHANNEL: u8 = 0; +pub const AN1_CHANNEL: u8 = 1; +pub const AN2_CHANNEL: u8 = 2; +pub const POTENTIOMETER_CHANNEL: u8 = 3; + +pub fn max11619_externally_clocked_no_wakeup( + spi: Spi, +) -> Result, Error> { + let mut adc = Max116xx10Bit::max11619(spi)?; + adc.reset(false)?; + adc.setup()?; + Ok(adc) +} + +pub fn max11619_externally_clocked_with_wakeup( + spi: Spi, +) -> Result, Error> { + let mut adc = Max116xx10Bit::max11619(spi)?.into_ext_clkd_with_int_ref_wakeup_delay(); + adc.reset(false)?; + adc.setup()?; + Ok(adc) +} + +pub fn max11619_internally_clocked( + spi: Spi, + eoc: EocPin, + v_ref: VoltageRefMode, +) -> Result, Error> { + let mut adc = Max116xx10Bit::max11619(spi)? + .into_int_clkd_int_timed_through_ser_if_without_wakeup(v_ref, eoc)?; + adc.reset(false)?; + adc.setup()?; + Ok(adc) +} diff --git a/vorago-reb1/src/temp_sensor.rs b/vorago-reb1/src/temp_sensor.rs new file mode 100644 index 0000000..3cffe55 --- /dev/null +++ b/vorago-reb1/src/temp_sensor.rs @@ -0,0 +1,79 @@ +//! # API for the On-Board Analog Devices ADT75 temperature sensor +//! +//! [Datasheet](https://www.analog.com/media/en/technical-documentation/data-sheets/ADT75.pdf) +//! +//! ## Examples +//! +//! - [Temperature Sensor example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/adt75-temp-sensor.rs) +use embedded_hal::i2c::{I2c, SevenBitAddress}; +use va108xx_hal::{ + i2c::{Error, I2cMaster, I2cSpeed, MasterConfig}, + pac, + time::Hertz, +}; + +const ADT75_I2C_ADDR: u8 = 0b1001000; + +pub struct Adt75TempSensor { + sensor_if: I2cMaster, + cmd_buf: [u8; 1], + current_reg: RegAddresses, +} + +#[derive(PartialEq, Eq, Debug, Copy, Clone)] +pub enum RegAddresses { + Temperature = 0x00, + Configuration = 0x01, + THystSetpoint = 0x02, + TOsSetPoint = 0x03, + OneShot = 0x04, +} + +impl Adt75TempSensor { + pub fn new( + i2ca: pac::I2ca, + sys_clk: impl Into + Copy, + sys_cfg: Option<&mut pac::Sysconfig>, + ) -> Result { + let mut sensor = Adt75TempSensor { + sensor_if: I2cMaster::i2ca( + i2ca, + MasterConfig::default(), + sys_clk, + I2cSpeed::Regular100khz, + sys_cfg, + ), + cmd_buf: [RegAddresses::Temperature as u8], + current_reg: RegAddresses::Temperature, + }; + sensor.select_reg(RegAddresses::Temperature)?; + Ok(sensor) + } + + pub fn select_reg(&mut self, reg: RegAddresses) -> Result<(), Error> { + if reg != self.current_reg { + self.cmd_buf[0] = reg as u8; + self.current_reg = reg; + self.sensor_if.write(ADT75_I2C_ADDR, &self.cmd_buf[0..1])?; + } + Ok(()) + } + + pub fn read_temperature(&mut self) -> Result { + if self.current_reg != RegAddresses::Temperature { + self.select_reg(RegAddresses::Temperature)?; + } + let mut reply: [u8; 2] = [0; 2]; + self.sensor_if.read(ADT75_I2C_ADDR, &mut reply)?; + let adc_code = (((reply[0] as u16) << 8) | reply[1] as u16) >> 4; + let temp_celcius: f32 = if ((adc_code >> 11) & 0x01) == 0 { + // Sign bit not set, positiv value + // Divide ADC code by 16 according to datasheet + adc_code as f32 / 16.0 + } else { + // Calculation for negative values, assuming all 12 bits are used + (adc_code - 4096) as f32 / 16.0 + }; + Ok(temp_celcius) + } +} diff --git a/.vscode/launch.json b/vscode/launch.json similarity index 79% rename from .vscode/launch.json rename to vscode/launch.json index 6104dc2..0498f52 100644 --- a/.vscode/launch.json +++ b/vscode/launch.json @@ -2,12 +2,10 @@ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - // You can set the "gdbPath" setting in a custom settings.json to use a non-default // GDB application "version": "0.2.0", "configurations": [ - { "type": "cortex-debug", "request": "launch", @@ -15,11 +13,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build led blinky", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-leds", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -28,11 +26,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build hal tests", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/tests", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -41,11 +39,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build rtt", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/rtt-log", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -54,11 +52,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build button blinky", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-irq", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -67,11 +65,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build systick", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/timer-ticks", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -84,7 +82,7 @@ "preLaunchTask": "rust: cargo build uart", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -93,11 +91,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build spi", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/spi", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -110,7 +108,7 @@ "preLaunchTask": "rust: cargo build temp sensor", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adt75-temp-sensor", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -123,7 +121,7 @@ "preLaunchTask": "rust: cargo build button blinky rtic", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-rtic", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -132,11 +130,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build pwm", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/pwm", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -145,11 +143,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build cascade", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/cascade", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -158,11 +156,24 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build accelerometer", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adxl343-accelerometer", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", + }, + { + "type": "cortex-debug", + "request": "launch", + "name": "Blinky HAL", + "servertype": "jlink", + "cwd": "${workspaceRoot}", + "device": "Cortex-M0", + "svdFile": "./va108xx/svd/va108xx.svd.patched", + "preLaunchTask": "blinky-hal", + "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adxl343-accelerometer", + "interface": "jtag", + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -171,11 +182,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "./va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build adc", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/max11619-adc", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, { "type": "cortex-debug", @@ -184,11 +195,11 @@ "servertype": "jlink", "cwd": "${workspaceRoot}", "device": "Cortex-M0", - "svdFile": "${workspaceFolder}/va108xx/svd/va108xx-base.svd.patched", + "svdFile": "./va108xx/svd/va108xx.svd.patched", "preLaunchTask": "rust: cargo build uart irq", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart-irq-rtic", "interface": "jtag", - "runToMain": true, + "runToEntryPoint": "main", }, ] } \ No newline at end of file diff --git a/.vscode/settings-default.json b/vscode/settings.json similarity index 100% rename from .vscode/settings-default.json rename to vscode/settings.json diff --git a/.vscode/tasks.json b/vscode/tasks.json similarity index 66% rename from .vscode/tasks.json rename to vscode/tasks.json index 89fa87f..ae76f96 100644 --- a/.vscode/tasks.json +++ b/vscode/tasks.json @@ -20,8 +20,13 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "tests", - "--features", "rt" + "build", + "-p", + "va108xx-hal", + "--bin", + "tests", + "--features", + "rt" ], "group": { "kind": "build", @@ -33,7 +38,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "rtt-log", + "build", + "-p", + "va108xx-hal", + "--example", + "rtt-log", ], "group": { "kind": "build", @@ -45,8 +54,13 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", - "timer-ticks", "--features", "rt" + "build", + "-p", + "va108xx-hal", + "--example", + "timer-ticks", + "--features", + "rt" ], "group": { "kind": "build", @@ -58,7 +72,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "uart", + "build", + "-p", + "va108xx-hal", + "--example", + "uart", ], "group": { "kind": "build", @@ -70,7 +88,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "spi", + "build", + "-p", + "va108xx-hal", + "--example", + "spi", ], "group": { "kind": "build", @@ -82,7 +104,13 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "pwm", "--features", "rt" + "build", + "-p", + "va108xx-hal", + "--example", + "pwm", + "--features", + "rt" ], "group": { "kind": "build", @@ -94,7 +122,13 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "cascade", "--features", "rt" + "build", + "-p", + "va108xx-hal", + "--example", + "cascade", + "--features", + "rt" ], "group": { "kind": "build", @@ -106,20 +140,42 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "va108xx-hal", "--example", "uart-irq-rtic", "--features", "rt" + "build", + "-p", + "va108xx-hal", + "--example", + "uart-irq-rtic", + "--features", + "rt" ], "group": { "kind": "build", "isDefault": true } }, - + { + "label": "blinky-hal", + "type": "shell", + "command": "~/.cargo/bin/cargo", // note: full path to the cargo + "args": [ + "build", + "--example", + "blinky", + ], + "group": { + "kind": "build", + } + }, { "label": "rust: cargo build led blinky", "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "blinky-leds", + "build", + "-p", + "vorago-reb1", + "--example", + "blinky-leds", ], "group": { "kind": "build", @@ -131,7 +187,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "blinky-button-irq", + "build", + "-p", + "vorago-reb1", + "--example", + "blinky-button-irq", ], "group": { "kind": "build", @@ -143,7 +203,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "adt75-temp-sensor", + "build", + "-p", + "vorago-reb1", + "--example", + "adt75-temp-sensor", ], "group": { "kind": "build", @@ -155,7 +219,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "blinky-button-rtic", + "build", + "-p", + "vorago-reb1", + "--example", + "blinky-button-rtic", ], "group": { "kind": "build", @@ -167,7 +235,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "adxl343-accelerometer" + "build", + "-p", + "vorago-reb1", + "--example", + "adxl343-accelerometer" ], "group": { "kind": "build", @@ -179,7 +251,11 @@ "type": "shell", "command": "~/.cargo/bin/cargo", // note: full path to the cargo "args": [ - "build", "-p", "vorago-reb1", "--example", "max11619-adc", + "build", + "-p", + "vorago-reb1", + "--example", + "max11619-adc", ], "group": { "kind": "build",