├── .github ├── CODEOWNERS └── workflows │ ├── rustfmt.yaml │ ├── clippy.yaml │ ├── changelog.yaml │ ├── e310x.yaml │ ├── e310x-hal.yaml │ └── hifive1.yaml ├── .gitignore ├── hifive1 ├── hifive1-link.x ├── memory-hifive1.x ├── memory-hifive1-revb.x ├── memory-lofive-r1.x ├── src │ ├── lib.rs │ ├── clock.rs │ ├── flash.rs │ ├── stdout.rs │ └── led.rs ├── Cargo.toml ├── CHANGELOG.md ├── build.rs └── README.md ├── e310x ├── memory.x ├── update.sh ├── build.rs ├── Cargo.toml ├── src │ ├── wdog │ │ ├── wdogkey.rs │ │ ├── wdogs.rs │ │ ├── wdogfeed.rs │ │ ├── wdogcount.rs │ │ └── wdogcmp.rs │ ├── pmu │ │ ├── pmusleep.rs │ │ ├── pmukey.rs │ │ └── pmuie.rs │ ├── aonclk.rs │ ├── backup.rs │ ├── otp │ │ ├── addr.rs │ │ ├── mpp.rs │ │ ├── mrr.rs │ │ ├── mode.rs │ │ ├── lock.rs │ │ ├── clock.rs │ │ ├── vppen.rs │ │ ├── vrren.rs │ │ ├── rsctrl.rs │ │ ├── data_in.rs │ │ ├── select.rs │ │ ├── data_out.rs │ │ ├── write_en.rs │ │ └── output_en.rs │ ├── qspi0 │ │ ├── csid.rs │ │ ├── csdef.rs │ │ ├── fctrl.rs │ │ ├── rxmark.rs │ │ ├── txmark.rs │ │ ├── sckdiv.rs │ │ ├── txdata.rs │ │ ├── ie.rs │ │ ├── ip.rs │ │ ├── rxdata.rs │ │ ├── sckmode.rs │ │ ├── delay0.rs │ │ ├── delay1.rs │ │ └── csmode.rs │ ├── rtc │ │ ├── rtcs.rs │ │ ├── rtclo.rs │ │ ├── rtccmp.rs │ │ ├── rtchi.rs │ │ └── rtccfg.rs │ ├── pwm0 │ │ ├── count.rs │ │ ├── pwms.rs │ │ ├── cmp0.rs │ │ ├── cmp1.rs │ │ ├── cmp2.rs │ │ └── cmp3.rs │ ├── i2c0 │ │ ├── cr_sr.rs │ │ ├── txr_rxr.rs │ │ ├── prer_hi.rs │ │ ├── prer_lo.rs │ │ ├── ctr.rs │ │ ├── sr.rs │ │ └── cr.rs │ ├── backup │ │ └── backup.rs │ ├── prci │ │ ├── coreclkcfg.rs │ │ ├── hfxosccfg.rs │ │ ├── plloutdiv.rs │ │ └── hfrosccfg.rs │ ├── uart0 │ │ ├── div.rs │ │ ├── ie.rs │ │ ├── ip.rs │ │ ├── txdata.rs │ │ ├── rxdata.rs │ │ ├── rxctrl.rs │ │ └── txctrl.rs │ └── aonclk │ │ └── lfrosccfg.rs ├── settings.yaml ├── CHANGELOG.md ├── README.md └── device.x ├── e310x-hal ├── src │ ├── asynch │ │ └── prelude.rs │ ├── asynch.rs │ ├── stdout.rs │ ├── core │ │ ├── mod.rs │ │ └── counters.rs │ ├── prelude.rs │ ├── time.rs │ ├── spi │ │ ├── shared_bus.rs │ │ ├── config.rs │ │ ├── exclusive_device.rs │ │ └── shared_device.rs │ ├── spi.rs │ ├── delay.rs │ ├── rtc.rs │ ├── lib.rs │ └── wdog.rs ├── Cargo.toml ├── README.md └── CHANGELOG.md ├── hifive1-examples ├── examples │ ├── sh_hello_world.rs │ ├── hello_world.rs │ ├── sh_led_blink.rs │ ├── led_blink.rs │ ├── led_pwm.rs │ ├── sh_rgb_blink.rs │ ├── button_poll.rs │ ├── rgb_blink.rs │ ├── led_blink_interrupt.rs │ ├── i2c_max3010x.rs │ └── spi_rc522.rs ├── gdb_init ├── gdb_init_sh ├── .cargo │ └── config.toml ├── Cargo.toml ├── openocd.sh └── src │ └── main.rs ├── hifive1-async-examples ├── gdb_init ├── gdb_init_sh ├── Cargo.toml ├── .cargo │ └── config.toml ├── openocd.sh ├── src │ └── main.rs └── examples │ └── button_led.rs ├── Cargo.toml ├── .cargo └── config.toml └── README.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @rust-embedded/riscv -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Cargo.lock 2 | target/ 3 | .vscode/ 4 | -------------------------------------------------------------------------------- /hifive1/hifive1-link.x: -------------------------------------------------------------------------------- 1 | INCLUDE hifive1-memory.x 2 | INCLUDE link.x 3 | -------------------------------------------------------------------------------- /e310x/memory.x: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | RAM : ORIGIN = 0x80000000, LENGTH = 16K 4 | } 5 | 6 | -------------------------------------------------------------------------------- /e310x-hal/src/asynch/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Prelude 2 | pub use embedded_hal_async::digital::Wait as _eha_Wait; 3 | -------------------------------------------------------------------------------- /e310x-hal/src/asynch.rs: -------------------------------------------------------------------------------- 1 | //! Asynchronous HAL for the E310x family of microcontrollers 2 | //! 3 | //! This is an implementation of the [`embedded-hal-async`] traits for the E310x 4 | //! family of microcontrollers. 5 | 6 | #![deny(missing_docs)] 7 | 8 | pub mod digital; 9 | pub mod prelude; 10 | -------------------------------------------------------------------------------- /hifive1-examples/examples/sh_hello_world.rs: -------------------------------------------------------------------------------- 1 | //! Prints "hello world!" to the host console using semihosting. 2 | 3 | #![no_std] 4 | #![no_main] 5 | 6 | extern crate hifive1; 7 | use semihosting::{println, process::exit}; 8 | 9 | #[riscv_rt::entry] 10 | fn main() -> ! { 11 | println!("Hello, world!"); 12 | exit(0); 13 | } 14 | -------------------------------------------------------------------------------- /hifive1-examples/gdb_init: -------------------------------------------------------------------------------- 1 | # GDB init file for HiFive1 boards 2 | 3 | # set history save on # uncomment to save history 4 | set confirm off 5 | set remotetimeout 240 6 | set print asm-demangle on 7 | 8 | target extended-remote :3333 9 | monitor reset halt 10 | load 11 | continue # uncomment to start running after loading 12 | # quit # uncomment to exit after loading 13 | -------------------------------------------------------------------------------- /hifive1-async-examples/gdb_init: -------------------------------------------------------------------------------- 1 | # GDB init file for HiFive1 boards 2 | 3 | # set history save on # uncomment to save history 4 | set confirm off 5 | set remotetimeout 240 6 | set print asm-demangle on 7 | 8 | target extended-remote :3333 9 | monitor reset halt 10 | load 11 | continue # uncomment to start running after loading 12 | # quit # uncomment to exit after loading 13 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "e310x", 5 | "e310x-hal", 6 | "hifive1", 7 | "hifive1-examples", 8 | "hifive1-async-examples", 9 | ] 10 | default-members = [ 11 | "e310x", 12 | "e310x-hal", 13 | "hifive1", 14 | ] 15 | 16 | [workspace.dependencies] 17 | critical-section = "1.2.0" 18 | riscv = "0.15.0" 19 | riscv-peripheral = "0.4.0" 20 | riscv-rt = "0.16.0" 21 | -------------------------------------------------------------------------------- /hifive1-examples/gdb_init_sh: -------------------------------------------------------------------------------- 1 | # GDB init file for HiFive1 boards (including semihosting) 2 | 3 | # set history save on # uncomment to save history 4 | set confirm off 5 | set remotetimeout 240 6 | set print asm-demangle on 7 | 8 | target extended-remote :3333 9 | monitor reset halt 10 | monitor arm semihosting enable 11 | load 12 | continue # uncomment to start running after loading 13 | # quit # uncomment to exit after loading 14 | -------------------------------------------------------------------------------- /e310x/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x 3 | set -e 4 | 5 | # used svd2rust 0.37.0 6 | rm -rf src 7 | mkdir src 8 | svd2rust --target riscv --settings settings.yaml --feature-group -g -i e310x.svd 9 | rm -f features.toml 10 | mv generic.rs src/ 11 | form -i lib.rs -o src/ 12 | rm lib.rs 13 | cargo fmt 14 | 15 | # combine generated device.x with memory.x 16 | mv device.x ints.x 17 | cat memory.x ints.x > device.x 18 | rm -f ints.x -------------------------------------------------------------------------------- /hifive1-async-examples/gdb_init_sh: -------------------------------------------------------------------------------- 1 | # GDB init file for HiFive1 boards (including semihosting) 2 | 3 | # set history save on # uncomment to save history 4 | set confirm off 5 | set remotetimeout 240 6 | set print asm-demangle on 7 | 8 | target extended-remote :3333 9 | monitor reset halt 10 | monitor arm semihosting enable 11 | load 12 | continue # uncomment to start running after loading 13 | # quit # uncomment to exit after loading 14 | -------------------------------------------------------------------------------- /hifive1/memory-hifive1.x: -------------------------------------------------------------------------------- 1 | INCLUDE device.x 2 | MEMORY 3 | { 4 | FLASH : ORIGIN = 0x20000000, LENGTH = 16M 5 | } 6 | 7 | REGION_ALIAS("REGION_TEXT", FLASH); 8 | REGION_ALIAS("REGION_RODATA", FLASH); 9 | REGION_ALIAS("REGION_DATA", RAM); 10 | REGION_ALIAS("REGION_BSS", RAM); 11 | REGION_ALIAS("REGION_HEAP", RAM); 12 | REGION_ALIAS("REGION_STACK", RAM); 13 | 14 | /* Skip first 4M allocated for bootloader */ 15 | _stext = 0x20400000; 16 | -------------------------------------------------------------------------------- /hifive1/memory-hifive1-revb.x: -------------------------------------------------------------------------------- 1 | INCLUDE device.x 2 | MEMORY 3 | { 4 | FLASH : ORIGIN = 0x20000000, LENGTH = 4M 5 | } 6 | 7 | REGION_ALIAS("REGION_TEXT", FLASH); 8 | REGION_ALIAS("REGION_RODATA", FLASH); 9 | REGION_ALIAS("REGION_DATA", RAM); 10 | REGION_ALIAS("REGION_BSS", RAM); 11 | REGION_ALIAS("REGION_HEAP", RAM); 12 | REGION_ALIAS("REGION_STACK", RAM); 13 | 14 | /* Skip first 64k allocated for bootloader */ 15 | _stext = 0x20010000; 16 | -------------------------------------------------------------------------------- /hifive1/memory-lofive-r1.x: -------------------------------------------------------------------------------- 1 | INCLUDE device.x 2 | MEMORY 3 | { 4 | FLASH : ORIGIN = 0x20000000, LENGTH = 16M 5 | } 6 | 7 | REGION_ALIAS("REGION_TEXT", FLASH); 8 | REGION_ALIAS("REGION_RODATA", FLASH); 9 | REGION_ALIAS("REGION_DATA", RAM); 10 | REGION_ALIAS("REGION_BSS", RAM); 11 | REGION_ALIAS("REGION_HEAP", RAM); 12 | REGION_ALIAS("REGION_STACK", RAM); 13 | 14 | /* Skip first 4M allocated for bootloader */ 15 | _stext = 0x20400000; 16 | -------------------------------------------------------------------------------- /.github/workflows/rustfmt.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | pull_request: 5 | merge_group: 6 | 7 | name: Code formatting check 8 | 9 | jobs: 10 | fmt: 11 | name: Rustfmt 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Update Rust toolchain 16 | run: rustup update stable && rustup default stable 17 | - name: Check code formatting 18 | run: cargo fmt --all -- --check --verbose 19 | -------------------------------------------------------------------------------- /hifive1-async-examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hifive1-async-examples" 3 | version = "0.1.0" 4 | edition = "2021" 5 | rust-version = "1.83" 6 | 7 | [dependencies] 8 | embassy-executor = { version = "0.9.1", features = ["arch-riscv32", "executor-thread"] } #embassy executor for async tasks 9 | hifive1 = { path = "../hifive1", version = "0.13.0", features = ["board-hifive1-revb", "async"] } # Change to your boardW 10 | riscv = { workspace = true } 11 | riscv-rt = { workspace = true, features = [] } 12 | panic-halt = "1.0.0" 13 | 14 | [features] 15 | v-trap = ["hifive1/v-trap"] 16 | -------------------------------------------------------------------------------- /e310x-hal/src/stdout.rs: -------------------------------------------------------------------------------- 1 | //! Stdout 2 | use core::fmt::{Error, Result, Write}; 3 | 4 | /// Stdout implements the core::fmt::Write trait for embedded_io::Write implementations. 5 | pub struct Stdout<'p, T: 'p>(pub &'p mut T); 6 | 7 | impl Write for Stdout<'_, T> { 8 | fn write_str(&mut self, s: &str) -> Result { 9 | for byte in s.as_bytes() { 10 | if *byte == b'\n' { 11 | self.0.write(b"\r").map_err(|_| Error)?; 12 | } 13 | self.0.write(&[*byte]).map_err(|_| Error)?; 14 | } 15 | Ok(()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /hifive1-async-examples/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] 2 | runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel" # Uncomment for QEMU 3 | # runner = "riscv64-unknown-elf-gdb -q -x gdb_init" # Uncomment for hardware (no semihosting) 4 | # runner = "riscv64-unknown-elf-gdb -q -x gdb_init_sh" # Uncomment for hardware (semihosting) 5 | rustflags = [ 6 | "-C", "link-arg=-Thifive1-link.x", 7 | "--cfg", "portable_atomic_target_feature=\"zaamo\"", 8 | ] 9 | 10 | [build] 11 | target = "riscv32imc-unknown-none-elf" 12 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] 2 | runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel" # Uncomment for QEMU 3 | # runner = "riscv64-unknown-elf-gdb -q -x hifive1-examples/gdb_init" # Uncomment for hardware (no semihosting) 4 | # runner = "riscv64-unknown-elf-gdb -q -x hifive1-examples/gdb_init_sh" # Uncomment for hardware (semihosting) 5 | rustflags = [ 6 | # "-C", "link-arg=-Thifive1-link.x", 7 | "--cfg", "portable_atomic_target_feature=\"zaamo\"", 8 | ] 9 | 10 | [build] 11 | target = "riscv32imc-unknown-none-elf" 12 | -------------------------------------------------------------------------------- /hifive1-examples/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] 2 | runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel" # Uncomment for QEMU 3 | # runner = "riscv64-unknown-elf-gdb -q -x gdb_init" # Uncomment for hardware (no semihosting) 4 | # runner = "riscv64-unknown-elf-gdb -q -x gdb_init_sh" # Uncomment for hardware (semihosting) 5 | rustflags = [ 6 | "-C", "link-arg=-Thifive1-link.x", 7 | "--cfg", "portable_atomic_target_feature=\"zaamo\"", 8 | ] 9 | 10 | [build] 11 | target = "riscv32imc-unknown-none-elf" 12 | 13 | [env] 14 | RISCV_RT_BASE_ISA = "rv32i" 15 | -------------------------------------------------------------------------------- /hifive1/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Board support crate for HiFive1 and LoFive boards 2 | 3 | #![deny(missing_docs)] 4 | #![no_std] 5 | 6 | pub use e310x_hal as hal; 7 | 8 | pub mod clock; 9 | pub use clock::configure as configure_clocks; 10 | 11 | pub mod flash; 12 | 13 | #[cfg(any( 14 | feature = "board-hifive1", 15 | feature = "board-hifive1-revb", 16 | feature = "board-redv" 17 | ))] 18 | pub mod led; 19 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 20 | pub use led::{rgb, Led, BLUE, GREEN, RED}; 21 | #[cfg(feature = "board-redv")] 22 | pub use led::{Led, BLUE}; 23 | 24 | pub mod stdout; 25 | pub use stdout::configure as configure_stdout; 26 | 27 | #[doc(hidden)] 28 | #[cfg(any( 29 | feature = "board-hifive1", 30 | feature = "board-hifive1-revb", 31 | feature = "board-redv" 32 | ))] 33 | pub mod gpio; 34 | -------------------------------------------------------------------------------- /hifive1-examples/examples/hello_world.rs: -------------------------------------------------------------------------------- 1 | //! Prints "hello world!" to the host console using the UART0 peripheral. 2 | 3 | #![no_std] 4 | #![no_main] 5 | 6 | extern crate panic_halt; 7 | use hifive1::{ 8 | clock, 9 | hal::{prelude::*, DeviceResources}, 10 | pin, sprintln, stdout, 11 | }; 12 | 13 | #[riscv_rt::entry] 14 | fn main() -> ! { 15 | let dr = DeviceResources::take().unwrap(); 16 | let p = dr.peripherals; 17 | let pins = dr.pins; 18 | 19 | // Configure clocks 20 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 21 | 22 | // Configure UART for stdout 23 | stdout::configure( 24 | p.UART0, 25 | pin!(pins, uart0_tx), 26 | pin!(pins, uart0_rx), 27 | 115_200.bps(), 28 | clocks, 29 | ); 30 | 31 | sprintln!("Hello, world!"); 32 | loop { 33 | riscv::asm::wfi(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /hifive1-examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hifive1-examples" 3 | version = "0.1.0" 4 | repository = "https://github.com/riscv-rust/e310x" 5 | authors = ["David Craven "] 6 | categories = ["embedded", "hardware-support", "no-std"] 7 | description = "Running examples for HiFive1 and LoFive boards" 8 | keywords = ["riscv", "register", "peripheral"] 9 | license = "ISC" 10 | edition = "2021" 11 | rust-version = "1.79" 12 | 13 | [dependencies] 14 | critical-section = { workspace = true } 15 | hifive1 = { path = "../hifive1", version = "0.13.0", features = ["board-hifive1-revb"] } # Change to your board 16 | riscv = { workspace = true } 17 | riscv-rt = { workspace = true, features = [] } 18 | panic-halt = "1.0.0" 19 | semihosting = { version = "0.1", features = ["stdio", "panic-handler"] } 20 | max3010x = "0.2.0" 21 | mfrc522 = "0.8.0" 22 | 23 | [features] 24 | v-trap = ["hifive1/v-trap"] 25 | -------------------------------------------------------------------------------- /hifive1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hifive1" 3 | version = "0.13.0" 4 | repository = "https://github.com/riscv-rust/e310x" 5 | authors = ["David Craven "] 6 | categories = ["embedded", "hardware-support", "no-std"] 7 | description = "Board support crate for HiFive1 and LoFive boards" 8 | keywords = ["riscv", "register", "peripheral"] 9 | license = "ISC" 10 | edition = "2021" 11 | rust-version = "1.79" 12 | 13 | [dependencies] 14 | critical-section = { workspace = true } 15 | e310x-hal = { path = "../e310x-hal", version = "0.12.0" } 16 | nb = "1.0.0" 17 | riscv = { workspace = true } 18 | 19 | [features] 20 | board-hifive1 = [] 21 | board-hifive1-revb = ["e310x-hal/g002"] 22 | board-redv = ["e310x-hal/g002"] 23 | board-lofive = [] 24 | board-lofive-r1 = ["e310x-hal/g002"] 25 | v-trap = ["e310x-hal/v-trap"] 26 | async = ["e310x-hal/async"] 27 | 28 | [package.metadata.docs.rs] 29 | features = ['board-hifive1-revb'] 30 | -------------------------------------------------------------------------------- /e310x/build.rs: -------------------------------------------------------------------------------- 1 | #![doc = r" Builder file for Peripheral access crate generated by svd2rust tool"] 2 | use std::env; 3 | use std::fs::File; 4 | use std::io::Write; 5 | use std::path::PathBuf; 6 | fn main() { 7 | if env::var_os("CARGO_FEATURE_RT").is_some() { 8 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 9 | File::create(out.join("device.x")) 10 | .unwrap() 11 | .write_all(include_bytes!("device.x")) 12 | .unwrap(); 13 | println!("cargo:rustc-link-search={}", out.display()); 14 | println!("cargo:rerun-if-changed=device.x"); 15 | println!("cargo:rustc-env=RISCV_RT_BASE_ISA=rv32i"); 16 | println!("cargo:rerun-if-env-changed=RISCV_RT_BASE_ISA"); 17 | println!("cargo:rustc-env=RISCV_MTVEC_ALIGN=64"); 18 | println!("cargo:rerun-if-env-changed=RISCV_MTVEC_ALIGN"); 19 | } 20 | println!("cargo:rerun-if-changed=build.rs"); 21 | } 22 | -------------------------------------------------------------------------------- /e310x/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "e310x" 3 | version = "0.12.0" 4 | repository = "https://github.com/riscv-rust/e310x" 5 | authors = ["David Craven ", "The RISC-V Team "] 6 | categories = ["embedded", "hardware-support", "no-std"] 7 | description = "With svd2rust generated peripherals for Freedom E310 MCU's." 8 | keywords = ["riscv", "register", "peripheral"] 9 | license = "ISC" 10 | rust-version = "1.76" 11 | edition = "2021" 12 | 13 | [dependencies] 14 | critical-section = { workspace = true, optional = true } 15 | riscv = { workspace = true } 16 | riscv-peripheral = { workspace = true } 17 | riscv-rt = { workspace = true, optional = true, features = ["no-interrupts", "single-hart"] } 18 | vcell = "0.1.3" 19 | 20 | [features] 21 | rt = ["riscv-rt"] 22 | v-trap = ["rt", "riscv-rt/v-trap"] 23 | g002 = [] 24 | 25 | [package.metadata.docs.rs] 26 | features = ["rt", "g002", "critical-section"] 27 | -------------------------------------------------------------------------------- /e310x-hal/src/core/mod.rs: -------------------------------------------------------------------------------- 1 | //! E31 core peripherals 2 | 3 | pub mod counters; 4 | 5 | use e310x::{Clint, Plic}; 6 | 7 | /// Core peripherals 8 | pub struct CorePeripherals { 9 | /// Core Local Interruptor (CLINT) 10 | pub clint: Clint, 11 | /// Platform-Level Interrupt Controller (PLIC) 12 | pub plic: Plic, 13 | /// Performance counters 14 | pub counters: counters::PerformanceCounters, 15 | } 16 | 17 | impl CorePeripherals { 18 | pub(crate) const fn new(clint: Clint, plic: Plic) -> Self { 19 | Self { 20 | clint, 21 | plic, 22 | counters: counters::PerformanceCounters::new(), 23 | } 24 | } 25 | 26 | /// Steal the peripherals 27 | /// 28 | /// # Safety 29 | /// 30 | /// Using this function may break the guarantees of the singleton pattern. 31 | pub unsafe fn steal() -> Self { 32 | Self::new(Clint::steal(), Plic::steal()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /e310x-hal/src/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Prelude 2 | 3 | pub use crate::clock::AonExt as _e310x_hal_clock_AonExt; 4 | pub use crate::clock::PrciExt as _e310x_hal_clock_PrciExt; 5 | pub use crate::gpio::GpioExt as _e310x_hal_gpio_GpioExt; 6 | pub use crate::rtc::RtcExt as _e310x_hal_rtc_RtcExt; 7 | pub use crate::time::U32Ext as _e310x_hal_time_U32Ext; 8 | pub use crate::wdog::WdogExt as _e310x_hal_wdog_WdogExt; 9 | pub use e310x::interrupt::{ 10 | CoreInterrupt, Exception, ExceptionNumber, ExternalInterrupt, InterruptNumber, Priority, 11 | PriorityNumber, 12 | }; 13 | pub use embedded_hal::{ 14 | self, 15 | delay::DelayNs, 16 | digital::{InputPin, OutputPin, StatefulOutputPin}, 17 | i2c::I2c as _embedded_hal_i2c_I2c, 18 | pwm::SetDutyCycle, 19 | spi::{SpiBus, SpiDevice}, 20 | }; 21 | 22 | pub use embedded_hal_nb::{ 23 | self, 24 | serial::{Read as _embedded_hal_nb_Read, Write as _embedded_hal_nb_Write}, 25 | spi::FullDuplex, 26 | }; 27 | 28 | pub use embedded_io; 29 | -------------------------------------------------------------------------------- /e310x/src/wdog/wdogkey.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `wdogkey` writer"] 2 | pub type W = crate::W; 3 | impl core::fmt::Debug for crate::generic::Reg { 4 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 5 | write!(f, "(not readable)") 6 | } 7 | } 8 | impl W {} 9 | #[doc = "Watchdog Key Register\n\nYou can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`wdogkey::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 10 | pub struct WdogkeySpec; 11 | impl crate::RegisterSpec for WdogkeySpec { 12 | type Ux = u32; 13 | } 14 | #[doc = "`write(|w| ..)` method takes [`wdogkey::W`](W) writer structure"] 15 | impl crate::Writable for WdogkeySpec { 16 | type Safety = crate::Unsafe; 17 | } 18 | #[doc = "`reset()` method sets wdogkey to value 0x0051_f15e"] 19 | impl crate::Resettable for WdogkeySpec { 20 | const RESET_VALUE: u32 = 0x0051_f15e; 21 | } 22 | -------------------------------------------------------------------------------- /e310x/src/pmu/pmusleep.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `pmusleep` writer"] 2 | pub type W = crate::W; 3 | #[doc = "Field `sleep` writer - "] 4 | pub type SleepW<'a, REG> = crate::BitWriter<'a, REG>; 5 | impl W { 6 | #[doc = "Bit 0"] 7 | #[inline(always)] 8 | pub fn sleep(&mut self) -> SleepW<'_, PmusleepSpec> { 9 | SleepW::new(self, 0) 10 | } 11 | } 12 | #[doc = "PMU Sleep Register\n\nYou can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`pmusleep::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 13 | pub struct PmusleepSpec; 14 | impl crate::RegisterSpec for PmusleepSpec { 15 | type Ux = u32; 16 | } 17 | #[doc = "`write(|w| ..)` method takes [`pmusleep::W`](W) writer structure"] 18 | impl crate::Writable for PmusleepSpec { 19 | type Safety = crate::Unsafe; 20 | } 21 | #[doc = "`reset()` method sets pmusleep to value 0"] 22 | impl crate::Resettable for PmusleepSpec {} 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # E301x crates 2 | 3 | This repository contains various crates useful for writing Rust programs on E310x microcontrollers: 4 | 5 | * [`e310x`]: Peripheral Access Crate (PAC) for E310x chips. 6 | * [`e310x-hal`]: HAL for the E310x family of microcontrollers. 7 | 8 | This project is developed and maintained by the [RISC-V team][team]. 9 | 10 | ### Contribution 11 | 12 | Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the 13 | work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 14 | additional terms or conditions. 15 | 16 | ## Code of Conduct 17 | 18 | Contribution to this crate is organized under the terms of the [Rust Code of 19 | Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises 20 | to intervene to uphold that code of conduct. 21 | 22 | [`riscv`]: https://crates.io/crates/e310x 23 | [team]: https://github.com/rust-embedded/wg#the-risc-v-team 24 | [CoC]: CODE_OF_CONDUCT.md 25 | -------------------------------------------------------------------------------- /e310x/src/aonclk.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[doc = "Register block"] 3 | pub struct RegisterBlock { 4 | _reserved0: [u8; 0x70], 5 | lfrosccfg: Lfrosccfg, 6 | } 7 | impl RegisterBlock { 8 | #[doc = "0x70 - AON Clock Configuration Register"] 9 | #[inline(always)] 10 | pub const fn lfrosccfg(&self) -> &Lfrosccfg { 11 | &self.lfrosccfg 12 | } 13 | } 14 | #[doc = "lfrosccfg (rw) register accessor: AON Clock Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`lfrosccfg::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`lfrosccfg::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@lfrosccfg`] module"] 15 | #[doc(alias = "lfrosccfg")] 16 | pub type Lfrosccfg = crate::Reg; 17 | #[doc = "AON Clock Configuration Register"] 18 | pub mod lfrosccfg; 19 | -------------------------------------------------------------------------------- /hifive1-examples/openocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script runs OpenOCD with the specified configuration file 4 | # for the HiFive1 board. The configuration file is selected based 5 | # on the revb argument, which is a boolean flag that indicates 6 | # whether the HiFive1 Rev B board is being used. If the revb 7 | # argument is not provided, the default configuration file for 8 | # the HiFive1 Rev A board is used. 9 | 10 | # Default path to OpenOCD 11 | OPENOCD_PATH="openocd" 12 | REVB=false 13 | 14 | # Parse command-line arguments 15 | while [[ "$#" -gt 0 ]]; do 16 | case $1 in 17 | -p|--path) OPENOCD_PATH="$2"; shift ;; 18 | revb) REVB=true ;; 19 | *) echo "Unknown parameter passed: $1"; exit 1 ;; 20 | esac 21 | shift 22 | done 23 | 24 | # Determine the configuration file based on the revb argument 25 | if [ "$REVB" = true ]; then 26 | CONFIG_FILE="sifive-hifive1-revb.cfg" 27 | else 28 | CONFIG_FILE="sifive-hifive1.cfg" 29 | fi 30 | 31 | # Run OpenOCD with the specified configuration file 32 | echo "Running $OPENOCD_PATH -f board/$CONFIG_FILE" 33 | $OPENOCD_PATH -f board/$CONFIG_FILE 34 | -------------------------------------------------------------------------------- /hifive1-async-examples/openocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script runs OpenOCD with the specified configuration file 4 | # for the HiFive1 board. The configuration file is selected based 5 | # on the revb argument, which is a boolean flag that indicates 6 | # whether the HiFive1 Rev B board is being used. If the revb 7 | # argument is not provided, the default configuration file for 8 | # the HiFive1 Rev A board is used. 9 | 10 | # Default path to OpenOCD 11 | OPENOCD_PATH="openocd" 12 | REVB=false 13 | 14 | # Parse command-line arguments 15 | while [[ "$#" -gt 0 ]]; do 16 | case $1 in 17 | -p|--path) OPENOCD_PATH="$2"; shift ;; 18 | revb) REVB=true ;; 19 | *) echo "Unknown parameter passed: $1"; exit 1 ;; 20 | esac 21 | shift 22 | done 23 | 24 | # Determine the configuration file based on the revb argument 25 | if [ "$REVB" = true ]; then 26 | CONFIG_FILE="sifive-hifive1-revb.cfg" 27 | else 28 | CONFIG_FILE="sifive-hifive1.cfg" 29 | fi 30 | 31 | # Run OpenOCD with the specified configuration file 32 | echo "Running $OPENOCD_PATH -f board/$CONFIG_FILE" 33 | $OPENOCD_PATH -f board/$CONFIG_FILE 34 | -------------------------------------------------------------------------------- /hifive1/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] 9 | 10 | - Update `e310x-hal` dependency and adapt code 11 | - Add async feature flag to enable embedded-hal-async digital module support 12 | 13 | ## [v0.13.0] - 2024-12-10 14 | 15 | - Fix Led implementation, as pins are configured as inverted outputs 16 | - Adapt to embedded-hal 1.0 17 | - Replace static muts with Mutexes 18 | - Apply clippy changes 19 | - Bump MSRV to 1.76 20 | - Adapt to new Cargo workspace 21 | - Use inline assembly instead of binary blobs for flash 22 | 23 | ## [v0.12.0] - 2023-03-28 24 | - Update e310x-hal to v0.11 with new svd2rust generated code 25 | 26 | ## [v0.11.0] - 2023-03-03 27 | 28 | ### Changed 29 | - Updated riscv dependency to v0.10 with interrupt/critical section changes 30 | 31 | ## [v0.10.0] - 2021-07-15 32 | 33 | ### Added 34 | 35 | - Added [SparkFun Red-V RedBoard](https://www.sparkfun.com/products/15594)` support 36 | -------------------------------------------------------------------------------- /hifive1-async-examples/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Prints "hello world!" to the host console using the on-board UART. 2 | //! 3 | //! # Note 4 | //! 5 | //! We have noticed that using the UART while debugging with GDB can cause 6 | //! the GDB session to hang. Thus, you will probably want to run this example 7 | //! without GDB. Otherwise, you might not be able to see the output. 8 | 9 | #![no_std] 10 | #![no_main] 11 | 12 | use hifive1::{ 13 | hal::{prelude::*, DeviceResources}, 14 | pin, sprintln, 15 | }; 16 | 17 | extern crate panic_halt; 18 | 19 | #[riscv_rt::entry] 20 | fn main() -> ! { 21 | let dr = DeviceResources::take().unwrap(); 22 | let p = dr.peripherals; 23 | let pins = dr.pins; 24 | 25 | // Configure clocks 26 | let clocks = hifive1::clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 27 | 28 | // Configure UART for stdout 29 | hifive1::stdout::configure( 30 | p.UART0, 31 | pin!(pins, uart0_tx), 32 | pin!(pins, uart0_rx), 33 | 115_200.bps(), 34 | clocks, 35 | ); 36 | 37 | sprintln!("Hello, world!"); 38 | 39 | loop { 40 | riscv::asm::wfi(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /hifive1-examples/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Prints "hello world!" to the host console using the on-board UART. 2 | //! 3 | //! # Note 4 | //! 5 | //! We have noticed that using the UART while debugging with GDB can cause 6 | //! the GDB session to hang. Thus, you will probably want to run this example 7 | //! without GDB. Otherwise, you might not be able to see the output. 8 | 9 | #![no_std] 10 | #![no_main] 11 | 12 | use hifive1::{ 13 | clock, 14 | hal::{prelude::*, DeviceResources}, 15 | pin, sprintln, stdout, 16 | }; 17 | 18 | extern crate panic_halt; 19 | 20 | #[riscv_rt::entry] 21 | fn main() -> ! { 22 | let dr = DeviceResources::take().unwrap(); 23 | let p = dr.peripherals; 24 | let pins = dr.pins; 25 | 26 | // Configure clocks 27 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 28 | 29 | // Configure UART for stdout 30 | stdout::configure( 31 | p.UART0, 32 | pin!(pins, uart0_tx), 33 | pin!(pins, uart0_rx), 34 | 115_200.bps(), 35 | clocks, 36 | ); 37 | 38 | sprintln!("Hello, world!"); 39 | 40 | loop { 41 | riscv::asm::wfi(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /e310x/src/backup.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | #[doc = "Register block"] 3 | pub struct RegisterBlock { 4 | _reserved0: [u8; 0x80], 5 | backup: [Backup; 16], 6 | } 7 | impl RegisterBlock { 8 | #[doc = "0x80..0xc0 - Backup Register"] 9 | #[inline(always)] 10 | pub const fn backup(&self, n: usize) -> &Backup { 11 | &self.backup[n] 12 | } 13 | #[doc = "Iterator for array of:"] 14 | #[doc = "0x80..0xc0 - Backup Register"] 15 | #[inline(always)] 16 | pub fn backup_iter(&self) -> impl Iterator { 17 | self.backup.iter() 18 | } 19 | } 20 | #[doc = "backup (rw) register accessor: Backup Register\n\nYou can [`read`](crate::Reg::read) this register and get [`backup::R`]. You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`backup::W`]. You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api).\n\nFor information about available fields see [`mod@backup`] module"] 21 | #[doc(alias = "backup")] 22 | pub type Backup = crate::Reg; 23 | #[doc = "Backup Register"] 24 | pub mod backup; 25 | -------------------------------------------------------------------------------- /e310x/src/otp/addr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `addr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `addr` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device address\n\nYou can [`read`](crate::Reg::read) this register and get [`addr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`addr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct AddrSpec; 13 | impl crate::RegisterSpec for AddrSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`addr::R`](R) reader structure"] 17 | impl crate::Readable for AddrSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`addr::W`](W) writer structure"] 19 | impl crate::Writable for AddrSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets addr to value 0"] 23 | impl crate::Resettable for AddrSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/mpp.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `mpp` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `mpp` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP write-voltage charge pump control\n\nYou can [`read`](crate::Reg::read) this register and get [`mpp::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`mpp::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct MppSpec; 13 | impl crate::RegisterSpec for MppSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`mpp::R`](R) reader structure"] 17 | impl crate::Readable for MppSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`mpp::W`](W) writer structure"] 19 | impl crate::Writable for MppSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets mpp to value 0"] 23 | impl crate::Resettable for MppSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/mrr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `mrr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `mrr` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP read-voltage regulator control\n\nYou can [`read`](crate::Reg::read) this register and get [`mrr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`mrr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct MrrSpec; 13 | impl crate::RegisterSpec for MrrSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`mrr::R`](R) reader structure"] 17 | impl crate::Readable for MrrSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`mrr::W`](W) writer structure"] 19 | impl crate::Writable for MrrSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets mrr to value 0"] 23 | impl crate::Resettable for MrrSpec {} 24 | -------------------------------------------------------------------------------- /e310x-hal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "e310x-hal" 3 | version = "0.12.0" 4 | authors = ["David Craven "] 5 | repository = "https://github.com/riscv-rust/e310x" 6 | categories = ["embedded", "hardware-support", "no-std"] 7 | description = "HAL for the E310x family of microcontrollers." 8 | keywords = ["riscv", "e310", "hal"] 9 | license = "ISC" 10 | edition = "2021" 11 | rust-version = "1.79" 12 | 13 | [dependencies] 14 | embedded-hal = "1.0.0" 15 | embedded-hal-nb = "1.0.0" 16 | embedded-io = "0.6.1" 17 | e310x = { path = "../e310x", version = "0.12.0", features = ["rt", "critical-section"] } 18 | nb = "1.0.0" 19 | portable-atomic = { version = "1.9", default-features = false } 20 | riscv = { workspace = true, features = ["critical-section-single-hart"] } 21 | 22 | # Async HAL dependencies 23 | riscv-rt = { workspace = true, optional = true } 24 | embedded-hal-async = { version = "1.0.0", optional = true } 25 | critical-section = { workspace = true, optional = true } 26 | 27 | [features] 28 | g002 = ["e310x/g002"] 29 | v-trap = ["e310x/v-trap"] 30 | async = ["riscv-rt", "embedded-hal-async", "critical-section"] 31 | 32 | [package.metadata.docs.rs] 33 | features = ["g002"] 34 | -------------------------------------------------------------------------------- /e310x/src/otp/mode.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `mode` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `mode` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device mode register\n\nYou can [`read`](crate::Reg::read) this register and get [`mode::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`mode::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct ModeSpec; 13 | impl crate::RegisterSpec for ModeSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`mode::R`](R) reader structure"] 17 | impl crate::Readable for ModeSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`mode::W`](W) writer structure"] 19 | impl crate::Writable for ModeSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets mode to value 0"] 23 | impl crate::Resettable for ModeSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/qspi0/csid.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `csid` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `csid` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Chip Select ID Register\n\nYou can [`read`](crate::Reg::read) this register and get [`csid::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`csid::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct CsidSpec; 13 | impl crate::RegisterSpec for CsidSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`csid::R`](R) reader structure"] 17 | impl crate::Readable for CsidSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`csid::W`](W) writer structure"] 19 | impl crate::Writable for CsidSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets csid to value 0"] 23 | impl crate::Resettable for CsidSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/rtc/rtcs.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rtcs` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rtcs` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "RTC Scaled Counter Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rtcs::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rtcs::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct RtcsSpec; 13 | impl crate::RegisterSpec for RtcsSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`rtcs::R`](R) reader structure"] 17 | impl crate::Readable for RtcsSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`rtcs::W`](W) writer structure"] 19 | impl crate::Writable for RtcsSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets rtcs to value 0"] 23 | impl crate::Resettable for RtcsSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/lock.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `lock` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `lock` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Programmed-I/O lock register\n\nYou can [`read`](crate::Reg::read) this register and get [`lock::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`lock::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct LockSpec; 13 | impl crate::RegisterSpec for LockSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`lock::R`](R) reader structure"] 17 | impl crate::Readable for LockSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`lock::W`](W) writer structure"] 19 | impl crate::Writable for LockSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets lock to value 0"] 23 | impl crate::Resettable for LockSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/pwm0/count.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `count` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `count` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Counter Register\n\nYou can [`read`](crate::Reg::read) this register and get [`count::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`count::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct CountSpec; 13 | impl crate::RegisterSpec for CountSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`count::R`](R) reader structure"] 17 | impl crate::Readable for CountSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`count::W`](W) writer structure"] 19 | impl crate::Writable for CountSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets count to value 0"] 23 | impl crate::Resettable for CountSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/pwm0/pwms.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `pwms` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `pwms` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Scaled Halfword Counter Register\n\nYou can [`read`](crate::Reg::read) this register and get [`pwms::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`pwms::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct PwmsSpec; 13 | impl crate::RegisterSpec for PwmsSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`pwms::R`](R) reader structure"] 17 | impl crate::Readable for PwmsSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`pwms::W`](W) writer structure"] 19 | impl crate::Writable for PwmsSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets pwms to value 0"] 23 | impl crate::Resettable for PwmsSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/clock.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `clock` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `clock` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device clock signal\n\nYou can [`read`](crate::Reg::read) this register and get [`clock::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`clock::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct ClockSpec; 13 | impl crate::RegisterSpec for ClockSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`clock::R`](R) reader structure"] 17 | impl crate::Readable for ClockSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`clock::W`](W) writer structure"] 19 | impl crate::Writable for ClockSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets clock to value 0"] 23 | impl crate::Resettable for ClockSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/vppen.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `vppen` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `vppen` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP write-voltage enable\n\nYou can [`read`](crate::Reg::read) this register and get [`vppen::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`vppen::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct VppenSpec; 13 | impl crate::RegisterSpec for VppenSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`vppen::R`](R) reader structure"] 17 | impl crate::Readable for VppenSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`vppen::W`](W) writer structure"] 19 | impl crate::Writable for VppenSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets vppen to value 0"] 23 | impl crate::Resettable for VppenSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/vrren.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `vrren` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `vrren` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP read-voltage enable\n\nYou can [`read`](crate::Reg::read) this register and get [`vrren::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`vrren::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct VrrenSpec; 13 | impl crate::RegisterSpec for VrrenSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`vrren::R`](R) reader structure"] 17 | impl crate::Readable for VrrenSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`vrren::W`](W) writer structure"] 19 | impl crate::Writable for VrrenSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets vrren to value 0"] 23 | impl crate::Resettable for VrrenSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/rtc/rtclo.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rtclo` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rtclo` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "RTC Counter Low Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rtclo::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rtclo::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct RtcloSpec; 13 | impl crate::RegisterSpec for RtcloSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`rtclo::R`](R) reader structure"] 17 | impl crate::Readable for RtcloSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`rtclo::W`](W) writer structure"] 19 | impl crate::Writable for RtcloSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets rtclo to value 0"] 23 | impl crate::Resettable for RtcloSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/i2c0/cr_sr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cr_sr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `cr_sr` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Command register / Status register\n\nYou can [`read`](crate::Reg::read) this register and get [`cr_sr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cr_sr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct CrSrSpec; 13 | impl crate::RegisterSpec for CrSrSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`cr_sr::R`](R) reader structure"] 17 | impl crate::Readable for CrSrSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`cr_sr::W`](W) writer structure"] 19 | impl crate::Writable for CrSrSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets cr_sr to value 0"] 23 | impl crate::Resettable for CrSrSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/pmu/pmukey.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `pmukey` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `pmukey` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "PMU Key Register\n\nYou can [`read`](crate::Reg::read) this register and get [`pmukey::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`pmukey::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct PmukeySpec; 13 | impl crate::RegisterSpec for PmukeySpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`pmukey::R`](R) reader structure"] 17 | impl crate::Readable for PmukeySpec {} 18 | #[doc = "`write(|w| ..)` method takes [`pmukey::W`](W) writer structure"] 19 | impl crate::Writable for PmukeySpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets pmukey to value 0"] 23 | impl crate::Resettable for PmukeySpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/rtc/rtccmp.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rtccmp` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rtccmp` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "RTC Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rtccmp::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rtccmp::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct RtccmpSpec; 13 | impl crate::RegisterSpec for RtccmpSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`rtccmp::R`](R) reader structure"] 17 | impl crate::Readable for RtccmpSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`rtccmp::W`](W) writer structure"] 19 | impl crate::Writable for RtccmpSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets rtccmp to value 0"] 23 | impl crate::Resettable for RtccmpSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/wdog/wdogs.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `wdogs` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `wdogs` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Watchdog Scaled Counter Register\n\nYou can [`read`](crate::Reg::read) this register and get [`wdogs::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`wdogs::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct WdogsSpec; 13 | impl crate::RegisterSpec for WdogsSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`wdogs::R`](R) reader structure"] 17 | impl crate::Readable for WdogsSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`wdogs::W`](W) writer structure"] 19 | impl crate::Writable for WdogsSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets wdogs to value 0"] 23 | impl crate::Resettable for WdogsSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/rsctrl.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rsctrl` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rsctrl` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP read sequencer control\n\nYou can [`read`](crate::Reg::read) this register and get [`rsctrl::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rsctrl::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct RsctrlSpec; 13 | impl crate::RegisterSpec for RsctrlSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`rsctrl::R`](R) reader structure"] 17 | impl crate::Readable for RsctrlSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`rsctrl::W`](W) writer structure"] 19 | impl crate::Writable for RsctrlSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets rsctrl to value 0"] 23 | impl crate::Resettable for RsctrlSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/backup/backup.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `backup[%s]` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `backup[%s]` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Backup Register\n\nYou can [`read`](crate::Reg::read) this register and get [`backup::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`backup::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct BackupSpec; 13 | impl crate::RegisterSpec for BackupSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`backup::R`](R) reader structure"] 17 | impl crate::Readable for BackupSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`backup::W`](W) writer structure"] 19 | impl crate::Writable for BackupSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets backup[%s] to value 0"] 23 | impl crate::Resettable for BackupSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/data_in.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `data_in` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `data_in` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device data input\n\nYou can [`read`](crate::Reg::read) this register and get [`data_in::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`data_in::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct DataInSpec; 13 | impl crate::RegisterSpec for DataInSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`data_in::R`](R) reader structure"] 17 | impl crate::Readable for DataInSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`data_in::W`](W) writer structure"] 19 | impl crate::Writable for DataInSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets data_in to value 0"] 23 | impl crate::Resettable for DataInSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/select.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `select` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `select` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device chip-select signal\n\nYou can [`read`](crate::Reg::read) this register and get [`select::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`select::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct SelectSpec; 13 | impl crate::RegisterSpec for SelectSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`select::R`](R) reader structure"] 17 | impl crate::Readable for SelectSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`select::W`](W) writer structure"] 19 | impl crate::Writable for SelectSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets select to value 0"] 23 | impl crate::Resettable for SelectSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/data_out.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `data_out` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `data_out` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device data output\n\nYou can [`read`](crate::Reg::read) this register and get [`data_out::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`data_out::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct DataOutSpec; 13 | impl crate::RegisterSpec for DataOutSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`data_out::R`](R) reader structure"] 17 | impl crate::Readable for DataOutSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`data_out::W`](W) writer structure"] 19 | impl crate::Writable for DataOutSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets data_out to value 0"] 23 | impl crate::Resettable for DataOutSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/write_en.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `write_en` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `write_en` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device write-enable signal\n\nYou can [`read`](crate::Reg::read) this register and get [`write_en::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`write_en::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct WriteEnSpec; 13 | impl crate::RegisterSpec for WriteEnSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`write_en::R`](R) reader structure"] 17 | impl crate::Readable for WriteEnSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`write_en::W`](W) writer structure"] 19 | impl crate::Writable for WriteEnSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets write_en to value 0"] 23 | impl crate::Resettable for WriteEnSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/wdog/wdogfeed.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `wdogfeed` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `wdogfeed` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Watchdog Feed Register\n\nYou can [`read`](crate::Reg::read) this register and get [`wdogfeed::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`wdogfeed::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct WdogfeedSpec; 13 | impl crate::RegisterSpec for WdogfeedSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`wdogfeed::R`](R) reader structure"] 17 | impl crate::Readable for WdogfeedSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`wdogfeed::W`](W) writer structure"] 19 | impl crate::Writable for WdogfeedSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets wdogfeed to value 0"] 23 | impl crate::Resettable for WdogfeedSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/otp/output_en.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `output_en` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `output_en` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "OTP device output-enable signal\n\nYou can [`read`](crate::Reg::read) this register and get [`output_en::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`output_en::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct OutputEnSpec; 13 | impl crate::RegisterSpec for OutputEnSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`output_en::R`](R) reader structure"] 17 | impl crate::Readable for OutputEnSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`output_en::W`](W) writer structure"] 19 | impl crate::Writable for OutputEnSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets output_en to value 0"] 23 | impl crate::Resettable for OutputEnSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/qspi0/csdef.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `csdef` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `csdef` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Chip Select Default Register\n\nYou can [`read`](crate::Reg::read) this register and get [`csdef::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`csdef::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct CsdefSpec; 13 | impl crate::RegisterSpec for CsdefSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`csdef::R`](R) reader structure"] 17 | impl crate::Readable for CsdefSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`csdef::W`](W) writer structure"] 19 | impl crate::Writable for CsdefSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets csdef to value 0xffff"] 23 | impl crate::Resettable for CsdefSpec { 24 | const RESET_VALUE: u32 = 0xffff; 25 | } 26 | -------------------------------------------------------------------------------- /e310x/src/wdog/wdogcount.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `wdogcount` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `wdogcount` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Watchdog Counter Register\n\nYou can [`read`](crate::Reg::read) this register and get [`wdogcount::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`wdogcount::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct WdogcountSpec; 13 | impl crate::RegisterSpec for WdogcountSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`wdogcount::R`](R) reader structure"] 17 | impl crate::Readable for WdogcountSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`wdogcount::W`](W) writer structure"] 19 | impl crate::Writable for WdogcountSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets wdogcount to value 0"] 23 | impl crate::Resettable for WdogcountSpec {} 24 | -------------------------------------------------------------------------------- /e310x/src/prci/coreclkcfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `coreclkcfg` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `coreclkcfg` writer"] 4 | pub type W = crate::W; 5 | impl core::fmt::Debug for R { 6 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 7 | write!(f, "{}", self.bits()) 8 | } 9 | } 10 | impl W {} 11 | #[doc = "Clock Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`coreclkcfg::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`coreclkcfg::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 12 | pub struct CoreclkcfgSpec; 13 | impl crate::RegisterSpec for CoreclkcfgSpec { 14 | type Ux = u32; 15 | } 16 | #[doc = "`read()` method returns [`coreclkcfg::R`](R) reader structure"] 17 | impl crate::Readable for CoreclkcfgSpec {} 18 | #[doc = "`write(|w| ..)` method takes [`coreclkcfg::W`](W) writer structure"] 19 | impl crate::Writable for CoreclkcfgSpec { 20 | type Safety = crate::Unsafe; 21 | } 22 | #[doc = "`reset()` method sets coreclkcfg to value 0"] 23 | impl crate::Resettable for CoreclkcfgSpec {} 24 | -------------------------------------------------------------------------------- /hifive1-examples/examples/sh_led_blink.rs: -------------------------------------------------------------------------------- 1 | //! Basic blinking LEDs example using mtime/mtimecmp registers for "sleep" in a loop. 2 | //! Blinks each led once and goes to the next one. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{prelude::*, DeviceResources}, 10 | pin, Led, 11 | }; 12 | use semihosting::{println, process::exit}; 13 | 14 | #[riscv_rt::entry] 15 | fn main() -> ! { 16 | let dr = DeviceResources::take().unwrap(); 17 | let cp = dr.core_peripherals; 18 | let p = dr.peripherals; 19 | let pins = dr.pins; 20 | 21 | // Configure clocks 22 | clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 23 | 24 | // get all 3 led pins in a tuple (each pin is it's own type here) 25 | let pin = pin!(pins, led_blue); 26 | let mut led = pin.into_inverted_output(); 27 | 28 | // Get the MTIMER peripheral from CLINT 29 | let mut mtimer = cp.clint.mtimer(); 30 | 31 | const N_TOGGLE: usize = 4; 32 | const STEP: u32 = 500; // 500 ms 33 | 34 | println!("Toggling LED {} times", N_TOGGLE); 35 | for _ in 0..N_TOGGLE { 36 | Led::toggle(&mut led); 37 | println!("LED toggled. New state: {}", led.is_on()); 38 | mtimer.delay_ms(STEP); 39 | } 40 | println!("Done toggling LED"); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /hifive1-examples/examples/led_blink.rs: -------------------------------------------------------------------------------- 1 | //! Basic blinking LED example using mtime/mtimecmp registers for "sleep" in a loop. 2 | //! Blinks the blue LED of RED-V board. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{prelude::*, DeviceResources}, 10 | pin, sprintln, stdout, Led, 11 | }; 12 | extern crate panic_halt; 13 | 14 | #[riscv_rt::entry] 15 | fn main() -> ! { 16 | let dr = DeviceResources::take().unwrap(); 17 | let cp = dr.core_peripherals; 18 | let p = dr.peripherals; 19 | let pins = dr.pins; 20 | 21 | // Configure clocks 22 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 23 | 24 | // Configure UART for stdout 25 | stdout::configure( 26 | p.UART0, 27 | pin!(pins, uart0_tx), 28 | pin!(pins, uart0_rx), 29 | 115_200.bps(), 30 | clocks, 31 | ); 32 | 33 | // get blue LED pin 34 | let pin = pin!(pins, led_blue); 35 | let mut led = pin.into_inverted_output(); 36 | 37 | // Get the MTIMER peripheral from CLINT 38 | let mut mtimer = cp.clint.mtimer(); 39 | 40 | const STEP: u32 = 1000; // 1s 41 | loop { 42 | Led::toggle(&mut led); 43 | sprintln!("LED toggled. New state: {}", led.is_on()); 44 | mtimer.delay_ms(STEP); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /e310x/settings.yaml: -------------------------------------------------------------------------------- 1 | riscv_config: 2 | core_interrupts: 3 | - name: "MachineSoft" 4 | value: 3 5 | description: "Machine Software Interrupt" 6 | - name: "MachineTimer" 7 | value: 7 8 | description: "Machine Timer Interrupt" 9 | - name: "MachineExternal" 10 | value: 11 11 | description: "Machine External Interrupt" 12 | 13 | priorities: 14 | - name: "P0" 15 | value: 0 16 | description: "Priority level 0" 17 | - name: "P1" 18 | value: 1 19 | description: "Priority level 1" 20 | - name: "P2" 21 | value: 2 22 | description: "Priority level 2" 23 | - name: "P3" 24 | value: 3 25 | description: "Priority level 3" 26 | - name: "P4" 27 | value: 4 28 | description: "Priority level 4" 29 | - name: "P5" 30 | value: 5 31 | description: "Priority level 5" 32 | - name: "P6" 33 | value: 6 34 | description: "Priority level 6" 35 | - name: "P7" 36 | value: 7 37 | description: "Priority level 7" 38 | 39 | harts: 40 | - name: "H0" 41 | value: 0 42 | description: "Hart 0" 43 | 44 | clint: 45 | name: "CLINT" 46 | mtime_freq: 32768 47 | 48 | plic: 49 | name: "PLIC" 50 | core_interrupt: "MachineExternal" 51 | hart_id: "H0" 52 | 53 | base_isa: "rv32i" 54 | mtvec_align: 64 55 | -------------------------------------------------------------------------------- /e310x-hal/src/time.rs: -------------------------------------------------------------------------------- 1 | //! Time units 2 | 3 | /// Bits per second 4 | #[derive(Clone, Copy)] 5 | pub struct Bps(pub u32); 6 | 7 | /// Hertz 8 | #[derive(Clone, Copy)] 9 | pub struct Hertz(pub u32); 10 | 11 | /// KiloHertz 12 | #[derive(Clone, Copy)] 13 | pub struct KiloHertz(pub u32); 14 | 15 | /// MegaHertz 16 | #[derive(Clone, Copy)] 17 | pub struct MegaHertz(pub u32); 18 | 19 | /// Extension trait that adds convenience methods to the `u32` type 20 | pub trait U32Ext { 21 | /// Wrap in `Bps` 22 | fn bps(self) -> Bps; 23 | 24 | /// Wrap in `Hertz` 25 | fn hz(self) -> Hertz; 26 | 27 | /// Wrap in `KiloHertz` 28 | fn khz(self) -> KiloHertz; 29 | 30 | /// Wrap in `MegaHertz` 31 | fn mhz(self) -> MegaHertz; 32 | } 33 | 34 | impl U32Ext for u32 { 35 | fn bps(self) -> Bps { 36 | Bps(self) 37 | } 38 | 39 | fn hz(self) -> Hertz { 40 | Hertz(self) 41 | } 42 | 43 | fn khz(self) -> KiloHertz { 44 | KiloHertz(self) 45 | } 46 | 47 | fn mhz(self) -> MegaHertz { 48 | MegaHertz(self) 49 | } 50 | } 51 | 52 | impl From for Hertz { 53 | fn from(val: KiloHertz) -> Self { 54 | Hertz(val.0 * 1_000) 55 | } 56 | } 57 | 58 | impl From for Hertz { 59 | fn from(val: MegaHertz) -> Self { 60 | Hertz(val.0 * 1_000_000) 61 | } 62 | } 63 | 64 | impl From for KiloHertz { 65 | fn from(val: MegaHertz) -> Self { 66 | KiloHertz(val.0 * 1_000) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /hifive1/src/clock.rs: -------------------------------------------------------------------------------- 1 | //! Board-specific clock configuration 2 | 3 | use e310x_hal::{ 4 | clock::{AonExt, Clocks, PrciExt}, 5 | e310x::{Aonclk, Prci}, 6 | time::Hertz, 7 | }; 8 | 9 | #[cfg(any( 10 | feature = "board-hifive1", 11 | feature = "board-hifive1-revb", 12 | feature = "board-redv" 13 | ))] 14 | /// Configures clock generation system. 15 | /// 16 | /// For HiFive1 and HiFive1 Rev B boards external oscillators are enabled for 17 | /// both high-frequency and low-frequency clocks. 18 | pub fn configure(prci: Prci, aonclk: Aonclk, target_coreclk: Hertz) -> Clocks { 19 | let coreclk = prci.constrain(); 20 | let coreclk = coreclk 21 | .use_external(Hertz(16_000_000)) 22 | .coreclk(target_coreclk); 23 | 24 | let aonclk = aonclk.constrain(); 25 | let aonclk = aonclk.use_external(Hertz(32_768)); 26 | 27 | Clocks::freeze(coreclk, aonclk) 28 | } 29 | 30 | #[cfg(any(feature = "board-lofive", feature = "board-lofive-r1"))] 31 | /// Configures clock generation system. 32 | /// 33 | /// For the LoFive and LoFive R1 boards, external oscillator is enabled for 34 | /// high-frequency clock. For low-frequency clock internal oscillator is used. 35 | pub fn configure(prci: Prci, aonclk: Aonclk, target_coreclk: Hertz) -> Clocks { 36 | let coreclk = prci.constrain(); 37 | let coreclk = coreclk 38 | .use_external(Hertz(16_000_000)) 39 | .coreclk(target_coreclk); 40 | 41 | let aonclk = aonclk.constrain(); 42 | 43 | Clocks::freeze(coreclk, aonclk) 44 | } 45 | -------------------------------------------------------------------------------- /e310x/src/uart0/div.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `div` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `div` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, DivSpec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Baud Rate Divisor Register\n\nYou can [`read`](crate::Reg::read) this register and get [`div::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`div::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct DivSpec; 25 | impl crate::RegisterSpec for DivSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`div::R`](R) reader structure"] 29 | impl crate::Readable for DivSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`div::W`](W) writer structure"] 31 | impl crate::Writable for DivSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets div to value 0"] 35 | impl crate::Resettable for DivSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/pwm0/cmp0.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cmp0` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `cmp0` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, Cmp0Spec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cmp0::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cmp0::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct Cmp0Spec; 25 | impl crate::RegisterSpec for Cmp0Spec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`cmp0::R`](R) reader structure"] 29 | impl crate::Readable for Cmp0Spec {} 30 | #[doc = "`write(|w| ..)` method takes [`cmp0::W`](W) writer structure"] 31 | impl crate::Writable for Cmp0Spec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets cmp0 to value 0"] 35 | impl crate::Resettable for Cmp0Spec {} 36 | -------------------------------------------------------------------------------- /e310x/src/pwm0/cmp1.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cmp1` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `cmp1` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, Cmp1Spec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cmp1::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cmp1::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct Cmp1Spec; 25 | impl crate::RegisterSpec for Cmp1Spec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`cmp1::R`](R) reader structure"] 29 | impl crate::Readable for Cmp1Spec {} 30 | #[doc = "`write(|w| ..)` method takes [`cmp1::W`](W) writer structure"] 31 | impl crate::Writable for Cmp1Spec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets cmp1 to value 0"] 35 | impl crate::Resettable for Cmp1Spec {} 36 | -------------------------------------------------------------------------------- /e310x/src/pwm0/cmp2.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cmp2` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `cmp2` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, Cmp2Spec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cmp2::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cmp2::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct Cmp2Spec; 25 | impl crate::RegisterSpec for Cmp2Spec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`cmp2::R`](R) reader structure"] 29 | impl crate::Readable for Cmp2Spec {} 30 | #[doc = "`write(|w| ..)` method takes [`cmp2::W`](W) writer structure"] 31 | impl crate::Writable for Cmp2Spec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets cmp2 to value 0"] 35 | impl crate::Resettable for Cmp2Spec {} 36 | -------------------------------------------------------------------------------- /e310x/src/pwm0/cmp3.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cmp3` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `cmp3` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, Cmp3Spec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`cmp3::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cmp3::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct Cmp3Spec; 25 | impl crate::RegisterSpec for Cmp3Spec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`cmp3::R`](R) reader structure"] 29 | impl crate::Readable for Cmp3Spec {} 30 | #[doc = "`write(|w| ..)` method takes [`cmp3::W`](W) writer structure"] 31 | impl crate::Writable for Cmp3Spec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets cmp3 to value 0"] 35 | impl crate::Resettable for Cmp3Spec {} 36 | -------------------------------------------------------------------------------- /e310x/src/rtc/rtchi.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rtchi` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rtchi` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, RtchiSpec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "RTC Counter High Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rtchi::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rtchi::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct RtchiSpec; 25 | impl crate::RegisterSpec for RtchiSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`rtchi::R`](R) reader structure"] 29 | impl crate::Readable for RtchiSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`rtchi::W`](W) writer structure"] 31 | impl crate::Writable for RtchiSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets rtchi to value 0"] 35 | impl crate::Resettable for RtchiSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/i2c0/txr_rxr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `txr_rxr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `txr_rxr` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `data` reader - "] 6 | pub type DataR = crate::FieldReader; 7 | #[doc = "Field `data` writer - "] 8 | pub type DataW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | impl R { 10 | #[doc = "Bits 0:7"] 11 | #[inline(always)] 12 | pub fn data(&self) -> DataR { 13 | DataR::new((self.bits & 0xff) as u8) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:7"] 18 | #[inline(always)] 19 | pub fn data(&mut self) -> DataW<'_, TxrRxrSpec> { 20 | DataW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Transmit register / Receive register\n\nYou can [`read`](crate::Reg::read) this register and get [`txr_rxr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`txr_rxr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct TxrRxrSpec; 25 | impl crate::RegisterSpec for TxrRxrSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`txr_rxr::R`](R) reader structure"] 29 | impl crate::Readable for TxrRxrSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`txr_rxr::W`](W) writer structure"] 31 | impl crate::Writable for TxrRxrSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets txr_rxr to value 0"] 35 | impl crate::Resettable for TxrRxrSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/i2c0/prer_hi.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `prer_hi` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `prer_hi` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | impl R { 10 | #[doc = "Bits 0:7"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xff) as u8) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:7"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, PrerHiSpec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Clock Prescale register hi-byte\n\nYou can [`read`](crate::Reg::read) this register and get [`prer_hi::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`prer_hi::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct PrerHiSpec; 25 | impl crate::RegisterSpec for PrerHiSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`prer_hi::R`](R) reader structure"] 29 | impl crate::Readable for PrerHiSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`prer_hi::W`](W) writer structure"] 31 | impl crate::Writable for PrerHiSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets prer_hi to value 0"] 35 | impl crate::Resettable for PrerHiSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/i2c0/prer_lo.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `prer_lo` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `prer_lo` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | impl R { 10 | #[doc = "Bits 0:7"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xff) as u8) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:7"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, PrerLoSpec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Clock Prescale register lo-byte\n\nYou can [`read`](crate::Reg::read) this register and get [`prer_lo::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`prer_lo::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct PrerLoSpec; 25 | impl crate::RegisterSpec for PrerLoSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`prer_lo::R`](R) reader structure"] 29 | impl crate::Readable for PrerLoSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`prer_lo::W`](W) writer structure"] 31 | impl crate::Writable for PrerLoSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets prer_lo to value 0"] 35 | impl crate::Resettable for PrerLoSpec {} 36 | -------------------------------------------------------------------------------- /hifive1-examples/examples/led_pwm.rs: -------------------------------------------------------------------------------- 1 | //! Demonstration of the PWM peripheral to control the brightness of an LED. 2 | //! 3 | //! # Hardware 4 | //! 5 | //! - HiFive1 or Red-V board 6 | //! - LED connected to pin 1 7 | #![no_std] 8 | #![no_main] 9 | 10 | use hifive1::{ 11 | clock, 12 | hal::{prelude::*, DeviceResources}, 13 | pin, sprintln, stdout, 14 | }; 15 | extern crate panic_halt; 16 | 17 | #[riscv_rt::entry] 18 | fn main() -> ! { 19 | let dr = DeviceResources::take().unwrap(); 20 | let cp = dr.core_peripherals; 21 | let p = dr.peripherals; 22 | let pins = dr.pins; 23 | 24 | // Configure clocks 25 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 26 | 27 | // Configure UART for stdout 28 | stdout::configure( 29 | p.UART0, 30 | pin!(pins, uart0_tx), 31 | pin!(pins, uart0_rx), 32 | 115_200.bps(), 33 | clocks, 34 | ); 35 | 36 | // get blue LED pin 37 | let pin = pin!(pins, pwm0_cmp1).into_inverted_iof1(); 38 | 39 | let mut pwm0 = hifive1::hal::pwm::Pwm::new(p.PWM0); 40 | pwm0.set_period(255); 41 | 42 | let mut channel = pwm0.channel(pin); 43 | 44 | // Get the MTIMER peripheral from CLINT 45 | let mut mtimer = cp.clint.mtimer(); 46 | 47 | const STEP: u32 = 1000; // 1s 48 | const DUTY_DELTA: u8 = 32; 49 | 50 | let mut duty: u8 = 0; 51 | loop { 52 | sprintln!("Duty: {}", duty); 53 | channel.set_duty_cycle(duty as u16).unwrap(); 54 | duty = duty.wrapping_add(DUTY_DELTA); 55 | 56 | mtimer.delay_ms(STEP); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /e310x/src/wdog/wdogcmp.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `wdogcmp` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `wdogcmp` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `value` reader - "] 6 | pub type ValueR = crate::FieldReader; 7 | #[doc = "Field `value` writer - "] 8 | pub type ValueW<'a, REG> = crate::FieldWriter<'a, REG, 16, u16>; 9 | impl R { 10 | #[doc = "Bits 0:15"] 11 | #[inline(always)] 12 | pub fn value(&self) -> ValueR { 13 | ValueR::new((self.bits & 0xffff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:15"] 18 | #[inline(always)] 19 | pub fn value(&mut self) -> ValueW<'_, WdogcmpSpec> { 20 | ValueW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Watchdog Compare Register\n\nYou can [`read`](crate::Reg::read) this register and get [`wdogcmp::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`wdogcmp::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct WdogcmpSpec; 25 | impl crate::RegisterSpec for WdogcmpSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`wdogcmp::R`](R) reader structure"] 29 | impl crate::Readable for WdogcmpSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`wdogcmp::W`](W) writer structure"] 31 | impl crate::Writable for WdogcmpSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets wdogcmp to value 0"] 35 | impl crate::Resettable for WdogcmpSpec {} 36 | -------------------------------------------------------------------------------- /.github/workflows/clippy.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | pull_request: 5 | merge_group: 6 | 7 | name: Lints compliance check 8 | 9 | env: 10 | # Bypass clippy warnings produced by Svd2Rust 11 | CLIPPY_PARAMS: -W clippy::all -D warnings -A clippy::module_inception -A clippy::needless_lifetimes 12 | 13 | jobs: 14 | clippy: 15 | strategy: 16 | matrix: 17 | board: [hifive1, hifive1-revb, redv, lofive, lofive-r1] 18 | toolchain: [ stable, nightly ] 19 | include: 20 | # Nightly is only for reference and allowed to fail 21 | - toolchain: nightly 22 | experimental: true 23 | runs-on: ubuntu-latest 24 | continue-on-error: ${{ matrix.experimental || false }} 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Update Rust toolchain and install Clippy 28 | run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} && rustup component add clippy 29 | - name: Install Rust target 30 | run: rustup target install riscv32imc-unknown-none-elf 31 | - name: Run clippy (direct mode) 32 | run: cargo clippy --features board-${{ matrix.board }} -- $CLIPPY_PARAMS 33 | - name: Run clippy (vectored mode) 34 | run: cargo clippy --features v-trap,board-${{ matrix.board }} -- $CLIPPY_PARAMS 35 | 36 | # Job to check that all the lint checks succeeded 37 | clippy-check: 38 | needs: 39 | - clippy 40 | runs-on: ubuntu-latest 41 | if: always() 42 | steps: 43 | - run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' 44 | -------------------------------------------------------------------------------- /hifive1-examples/examples/sh_rgb_blink.rs: -------------------------------------------------------------------------------- 1 | //! Basic blinking LEDs example using mtime/mtimecmp registers for "sleep" in a loop. 2 | //! Blinks each led once and goes to the next one. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{prelude::*, DeviceResources}, 10 | pins, Led, 11 | }; 12 | use semihosting::{println, process::exit}; 13 | 14 | #[riscv_rt::entry] 15 | fn main() -> ! { 16 | let dr = DeviceResources::take().unwrap(); 17 | let cp = dr.core_peripherals; 18 | let p = dr.peripherals; 19 | let pins = dr.pins; 20 | 21 | // Configure clocks 22 | clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 23 | 24 | // get all 3 led pins in a tuple (each pin is it's own type here) 25 | let rgb_pins = pins!(pins, (led_red, led_green, led_blue)); 26 | let mut tleds = hifive1::rgb(rgb_pins.0, rgb_pins.1, rgb_pins.2); 27 | // get leds as the Led trait in an array so we can index them 28 | let mut ileds: [&mut dyn Led; 3] = [&mut tleds.0, &mut tleds.1, &mut tleds.2]; 29 | 30 | // Get the MTIMER peripheral from CLINT 31 | let mut mtimer = cp.clint.mtimer(); 32 | 33 | const N_TOGGLES: usize = 4; 34 | const STEP: u32 = 500; // 500ms 35 | 36 | println!("Toggling LEDs {} times", N_TOGGLES); 37 | for _ in 0..N_TOGGLES { 38 | for (i, led) in ileds.iter_mut().enumerate() { 39 | led.toggle().unwrap(); 40 | println!("LED {i} toggled. New state: {}", led.is_on()); 41 | mtimer.delay_ms(STEP); 42 | } 43 | } 44 | println!("Done toggling LEDs"); 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /e310x/src/qspi0/fctrl.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `fctrl` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `fctrl` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `en` reader - SPI Flash Mode Select"] 6 | pub type EnR = crate::BitReader; 7 | #[doc = "Field `en` writer - SPI Flash Mode Select"] 8 | pub type EnW<'a, REG> = crate::BitWriter<'a, REG>; 9 | impl R { 10 | #[doc = "Bit 0 - SPI Flash Mode Select"] 11 | #[inline(always)] 12 | pub fn en(&self) -> EnR { 13 | EnR::new((self.bits & 1) != 0) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bit 0 - SPI Flash Mode Select"] 18 | #[inline(always)] 19 | pub fn en(&mut self) -> EnW<'_, FctrlSpec> { 20 | EnW::new(self, 0) 21 | } 22 | } 23 | #[doc = "SPI Flash Interface Control Register\n\nYou can [`read`](crate::Reg::read) this register and get [`fctrl::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`fctrl::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct FctrlSpec; 25 | impl crate::RegisterSpec for FctrlSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`fctrl::R`](R) reader structure"] 29 | impl crate::Readable for FctrlSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`fctrl::W`](W) writer structure"] 31 | impl crate::Writable for FctrlSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets fctrl to value 0"] 35 | impl crate::Resettable for FctrlSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/qspi0/rxmark.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rxmark` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rxmark` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `rxmark` reader - Receive watermark"] 6 | pub type RxmarkR = crate::FieldReader; 7 | #[doc = "Field `rxmark` writer - Receive watermark"] 8 | pub type RxmarkW<'a, REG> = crate::FieldWriter<'a, REG, 3>; 9 | impl R { 10 | #[doc = "Bits 0:2 - Receive watermark"] 11 | #[inline(always)] 12 | pub fn rxmark(&self) -> RxmarkR { 13 | RxmarkR::new((self.bits & 7) as u8) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:2 - Receive watermark"] 18 | #[inline(always)] 19 | pub fn rxmark(&mut self) -> RxmarkW<'_, RxmarkSpec> { 20 | RxmarkW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Receive Watermark Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rxmark::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rxmark::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct RxmarkSpec; 25 | impl crate::RegisterSpec for RxmarkSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`rxmark::R`](R) reader structure"] 29 | impl crate::Readable for RxmarkSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`rxmark::W`](W) writer structure"] 31 | impl crate::Writable for RxmarkSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets rxmark to value 0"] 35 | impl crate::Resettable for RxmarkSpec {} 36 | -------------------------------------------------------------------------------- /e310x/src/qspi0/txmark.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `txmark` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `txmark` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `txmark` reader - Transmit watermark"] 6 | pub type TxmarkR = crate::FieldReader; 7 | #[doc = "Field `txmark` writer - Transmit watermark"] 8 | pub type TxmarkW<'a, REG> = crate::FieldWriter<'a, REG, 3>; 9 | impl R { 10 | #[doc = "Bits 0:2 - Transmit watermark"] 11 | #[inline(always)] 12 | pub fn txmark(&self) -> TxmarkR { 13 | TxmarkR::new((self.bits & 7) as u8) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:2 - Transmit watermark"] 18 | #[inline(always)] 19 | pub fn txmark(&mut self) -> TxmarkW<'_, TxmarkSpec> { 20 | TxmarkW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Transmit Watermark Register\n\nYou can [`read`](crate::Reg::read) this register and get [`txmark::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`txmark::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct TxmarkSpec; 25 | impl crate::RegisterSpec for TxmarkSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`txmark::R`](R) reader structure"] 29 | impl crate::Readable for TxmarkSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`txmark::W`](W) writer structure"] 31 | impl crate::Writable for TxmarkSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets txmark to value 0"] 35 | impl crate::Resettable for TxmarkSpec {} 36 | -------------------------------------------------------------------------------- /hifive1-examples/examples/button_poll.rs: -------------------------------------------------------------------------------- 1 | //! Example of polling a button and turning on an LED when the button is pressed. 2 | //! 3 | //! # Hardware 4 | //! 5 | //! - HiFive1 or RED-V board 6 | //! - A button connected to pin 9 7 | 8 | #![no_std] 9 | #![no_main] 10 | 11 | use hifive1::{ 12 | clock, 13 | hal::{prelude::*, DeviceResources}, 14 | pin, sprintln, stdout, Led, 15 | }; 16 | extern crate panic_halt; 17 | 18 | #[riscv_rt::entry] 19 | fn main() -> ! { 20 | let dr = DeviceResources::take().unwrap(); 21 | let cp = dr.core_peripherals; 22 | let p = dr.peripherals; 23 | let pins = dr.pins; 24 | 25 | // Configure clocks 26 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 27 | 28 | // Configure UART for stdout 29 | stdout::configure( 30 | p.UART0, 31 | pin!(pins, uart0_tx), 32 | pin!(pins, uart0_rx), 33 | 115_200.bps(), 34 | clocks, 35 | ); 36 | 37 | // Configure button pin as pull-up input 38 | let mut button = pins.pin9.into_pull_up_input(); 39 | 40 | // get blue LED pin 41 | let pin = pin!(pins, led_blue); 42 | let mut led = pin.into_inverted_output(); 43 | 44 | // Get the MTIMER peripheral from CLINT 45 | let mut mtimer = cp.clint.mtimer(); 46 | 47 | const STEP: u32 = 1000; // 1s 48 | loop { 49 | if button.is_low().unwrap() { 50 | sprintln!("Button pressed"); 51 | led.on(); 52 | } else { 53 | sprintln!("Button released"); 54 | led.off(); 55 | } 56 | sprintln!("LED is on: {}", led.is_on()); 57 | mtimer.delay_ms(STEP); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /e310x/src/qspi0/sckdiv.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `sckdiv` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `sckdiv` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `div` reader - Divisor for serial clock"] 6 | pub type DivR = crate::FieldReader; 7 | #[doc = "Field `div` writer - Divisor for serial clock"] 8 | pub type DivW<'a, REG> = crate::FieldWriter<'a, REG, 12, u16>; 9 | impl R { 10 | #[doc = "Bits 0:11 - Divisor for serial clock"] 11 | #[inline(always)] 12 | pub fn div(&self) -> DivR { 13 | DivR::new((self.bits & 0x0fff) as u16) 14 | } 15 | } 16 | impl W { 17 | #[doc = "Bits 0:11 - Divisor for serial clock"] 18 | #[inline(always)] 19 | pub fn div(&mut self) -> DivW<'_, SckdivSpec> { 20 | DivW::new(self, 0) 21 | } 22 | } 23 | #[doc = "Serial Clock Divisor Register\n\nYou can [`read`](crate::Reg::read) this register and get [`sckdiv::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`sckdiv::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 24 | pub struct SckdivSpec; 25 | impl crate::RegisterSpec for SckdivSpec { 26 | type Ux = u32; 27 | } 28 | #[doc = "`read()` method returns [`sckdiv::R`](R) reader structure"] 29 | impl crate::Readable for SckdivSpec {} 30 | #[doc = "`write(|w| ..)` method takes [`sckdiv::W`](W) writer structure"] 31 | impl crate::Writable for SckdivSpec { 32 | type Safety = crate::Unsafe; 33 | } 34 | #[doc = "`reset()` method sets sckdiv to value 0"] 35 | impl crate::Resettable for SckdivSpec {} 36 | -------------------------------------------------------------------------------- /hifive1-examples/examples/rgb_blink.rs: -------------------------------------------------------------------------------- 1 | //! Basic blinking LEDs example using mtime/mtimecmp registers for "sleep" in a loop. 2 | //! Blinks each led once and goes to the next one. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{prelude::*, DeviceResources}, 10 | pin, pins, sprintln, stdout, Led, 11 | }; 12 | extern crate panic_halt; 13 | 14 | #[riscv_rt::entry] 15 | fn main() -> ! { 16 | let dr = DeviceResources::take().unwrap(); 17 | let cp = dr.core_peripherals; 18 | let p = dr.peripherals; 19 | let pins = dr.pins; 20 | 21 | // Configure clocks 22 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 23 | 24 | // Configure UART for stdout 25 | stdout::configure( 26 | p.UART0, 27 | pin!(pins, uart0_tx), 28 | pin!(pins, uart0_rx), 29 | 115_200.bps(), 30 | clocks, 31 | ); 32 | 33 | // get all 3 led pins in a tuple (each pin is it's own type here) 34 | let rgb_pins = pins!(pins, (led_red, led_green, led_blue)); 35 | let mut tleds = hifive1::rgb(rgb_pins.0, rgb_pins.1, rgb_pins.2); 36 | // get leds as the Led trait in an array so we can index them 37 | let mut ileds: [&mut dyn Led; 3] = [&mut tleds.0, &mut tleds.1, &mut tleds.2]; 38 | 39 | // Get the MTIMER peripheral from CLINT 40 | let mut mtimer = cp.clint.mtimer(); 41 | 42 | const STEP: u32 = 1000; // 1s 43 | loop { 44 | for (i, led) in ileds.iter_mut().enumerate() { 45 | led.toggle().unwrap(); 46 | sprintln!("LED {} toggled. New state: {}", i, led.is_on()); 47 | mtimer.delay_ms(STEP); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /e310x/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] 9 | 10 | ### Changed 11 | 12 | - The I2C0 code is now gated under the `g002` feature 13 | - Regenerate code with `svd2rust` 0.37.0 14 | - Use `riscv` v0.15.0, `riscv-peripheral` v0.4.0, and `riscv-rt` v0.16.0 15 | - In vectored mode, align `mtvec` to 64 bytes 16 | 17 | ## [v0.12.0] - 2024-12-10 18 | 19 | ### Changed 20 | 21 | - Now CLINT and PLIC are provided by `riscv-peripheral` 0.2 22 | - Adapt crate to work with `riscv` 0.12 and `riscv-rt` 0.13 23 | - Bump MSRV to 1.76.0 required by `riscv-peripheral` 24 | - Regenerate code with `svd2rust` 0.34.0 25 | 26 | ## [v0.11.0] 27 | 28 | ### Changed 29 | - Update `riscv` dependency to version 0.10 30 | - Regenerate code with `svd2rust` v0.26.0 31 | 32 | ## [v0.10.0] - 2022-09-04 33 | 34 | ### Added 35 | 36 | ### Changed 37 | 38 | - Update `riscv` dependency to version 0.8 39 | - Regenerate code with `svd2rust` v0.19.0 40 | 41 | ### Fixed 42 | 43 | - Fix QSPI `delay0` and `delay1` reset values 44 | 45 | 46 | ## [v0.9.0] - 2020-11-01 47 | 48 | ### Changed 49 | 50 | - Update `riscv` dependency to version 0.6 51 | - Rename QSPI registers and fields to match the datasheet 52 | 53 | ### Fixed 54 | 55 | - Fix QSPI `ffmt.pad_cnt` field definition 56 | 57 | 58 | [Unreleased]: https://github.com/riscv-rust/e310x/compare/v0.10.0..HEAD 59 | [v0.10.0]: https://github.com/rust-embedded/riscv-rt/compare/v0.9.0...v0.10.0 60 | [v0.9.0]: https://github.com/riscv-rust/e310x/compare/v0.8.1...v0.9.0 61 | -------------------------------------------------------------------------------- /hifive1/build.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use std::{env, fs}; 3 | 4 | fn main() { 5 | // Put the memory definitions somewhere the linker can find it 6 | let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); 7 | println!("cargo:rustc-link-search={}", out_dir.display()); 8 | 9 | let boards: Vec<_> = env::vars() 10 | .filter_map(|(key, _value)| { 11 | if key.starts_with("CARGO_FEATURE_BOARD") { 12 | Some(key[20..].to_ascii_lowercase()) // Strip 'CARGO_FEATURE_BOARD_' 13 | } else { 14 | None 15 | } 16 | }) 17 | .collect(); 18 | 19 | assert!(!boards.is_empty(), "No board features selected"); 20 | 21 | assert_eq!( 22 | boards.len(), 23 | 1, 24 | "More than one board feature selected: {boards:?}" 25 | ); 26 | 27 | let board = boards.first().unwrap(); 28 | 29 | match board.as_str() { 30 | "hifive1" => { 31 | fs::copy("memory-hifive1.x", out_dir.join("hifive1-memory.x")).unwrap(); 32 | println!("cargo:rerun-if-changed=memory-hifive1.x"); 33 | } 34 | "hifive1_revb" | "redv" => { 35 | fs::copy("memory-hifive1-revb.x", out_dir.join("hifive1-memory.x")).unwrap(); 36 | println!("cargo:rerun-if-changed=memory-hifive1-revb.x"); 37 | } 38 | "lofive" | "lofive_r1" => { 39 | fs::copy("memory-lofive-r1.x", out_dir.join("hifive1-memory.x")).unwrap(); 40 | println!("cargo:rerun-if-changed=memory-lofive-r1.x"); 41 | } 42 | 43 | other => panic!("Unknown board: {other}"), 44 | } 45 | 46 | fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); 47 | println!("cargo:rerun-if-changed=hifive1-link.x"); 48 | } 49 | -------------------------------------------------------------------------------- /hifive1-examples/examples/led_blink_interrupt.rs: -------------------------------------------------------------------------------- 1 | //! Basic blinking LED example using mtime/mtimecmp registers for "sleep" in a loop. 2 | //! Blinks the blue LED of RED-V board. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{e310x::Clint, prelude::*, DeviceResources}, 10 | pin, sprintln, stdout, Led, 11 | }; 12 | extern crate panic_halt; 13 | 14 | #[riscv_rt::core_interrupt(CoreInterrupt::MachineTimer)] 15 | fn mtimer_handler() { 16 | let clint = unsafe { Clint::steal() }; 17 | let mtimer = clint.mtimer(); 18 | mtimer 19 | .mtimecmp0() 20 | .modify(|prev| *prev += mtimer.mtime_freq() as u64); 21 | } 22 | 23 | #[riscv_rt::entry] 24 | fn main() -> ! { 25 | let dr = DeviceResources::take().unwrap(); 26 | let cp = dr.core_peripherals; 27 | let p = dr.peripherals; 28 | let pins = dr.pins; 29 | 30 | // Configure clocks 31 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 32 | 33 | // Configure UART for stdout 34 | stdout::configure( 35 | p.UART0, 36 | pin!(pins, uart0_tx), 37 | pin!(pins, uart0_rx), 38 | 115_200.bps(), 39 | clocks, 40 | ); 41 | 42 | // get blue LED pin 43 | let pin = pin!(pins, led_blue); 44 | let mut led = pin.into_inverted_output(); 45 | 46 | // Get the MTIMER peripheral from CLINT 47 | let mtimer = cp.clint.mtimer(); 48 | mtimer.mtime().write(0); 49 | mtimer.mtimecmp0().write(mtimer.mtime_freq() as u64); // Set the first compare value 50 | 51 | unsafe { 52 | mtimer.enable(); 53 | riscv::interrupt::enable(); 54 | } 55 | 56 | loop { 57 | Led::toggle(&mut led); 58 | sprintln!("LED toggled. New state: {}", led.is_on()); 59 | riscv::asm::wfi(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yaml: -------------------------------------------------------------------------------- 1 | name: Changelog check 2 | 3 | on: 4 | merge_group: 5 | pull_request: 6 | types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] 7 | 8 | jobs: 9 | changelog-check: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v4 14 | 15 | - name: Check which component is modified 16 | uses: dorny/paths-filter@v2 17 | id: changes 18 | with: 19 | filters: | 20 | e310x: 21 | - 'e310x/**' 22 | e310x-hal: 23 | - 'e310x-hal/**' 24 | hifive1: 25 | - 'hifive1/**' 26 | 27 | - name: Check for CHANGELOG.md (e310x) 28 | if: steps.changes.outputs['e310x'] == 'true' 29 | uses: dangoslen/changelog-enforcer@v3 30 | with: 31 | changeLogPath: ./e310x/CHANGELOG.md 32 | skipLabels: 'skip changelog' 33 | missingUpdateErrorMessage: 'Please add a changelog entry in the e310x/CHANGELOG.md file.' 34 | 35 | - name: Check for CHANGELOG.md (e310x-hal) 36 | if: steps.changes.outputs['e310x-hal'] == 'true' 37 | uses: dangoslen/changelog-enforcer@v3 38 | with: 39 | changeLogPath: ./e310x-hal/CHANGELOG.md 40 | skipLabels: 'skip changelog' 41 | missingUpdateErrorMessage: 'Please add a changelog entry in the e310x-hal/CHANGELOG.md file.' 42 | 43 | - name: Check for CHANGELOG.md (hifive1) 44 | if: steps.changes.outputs['hifive1'] == 'true' 45 | uses: dangoslen/changelog-enforcer@v3 46 | with: 47 | changeLogPath: ./hifive1/CHANGELOG.md 48 | skipLabels: 'skip changelog' 49 | missingUpdateErrorMessage: 'Please add a changelog entry in the hifive1/CHANGELOG.md file.' 50 | -------------------------------------------------------------------------------- /e310x-hal/src/core/counters.rs: -------------------------------------------------------------------------------- 1 | //! Performance counters 2 | 3 | use riscv::register::{mcycle, mhpmcounter3, mhpmcounter4, minstret}; 4 | 5 | /// Opaque mcycle register 6 | pub struct MCYCLE; 7 | 8 | impl MCYCLE { 9 | /// Read mcycle and mcycleh registers. 10 | #[inline] 11 | pub fn value(&self) -> u64 { 12 | mcycle::read64() 13 | } 14 | } 15 | 16 | /// Opaque minstret register. 17 | pub struct MINSTRET; 18 | 19 | impl MINSTRET { 20 | /// Read minstret and minstreth registers. 21 | #[inline] 22 | pub fn value(&self) -> u64 { 23 | minstret::read64() 24 | } 25 | } 26 | 27 | /// Opaque mhpmcounter3 register. 28 | pub struct MHPMCOUNTER3; 29 | 30 | impl MHPMCOUNTER3 { 31 | /// Read mhpmcounter3 and mhpmcounter3h registers. 32 | #[inline] 33 | pub fn value(&self) -> u64 { 34 | mhpmcounter3::read64() 35 | } 36 | } 37 | 38 | /// Opaque mhpmcounter4 register. 39 | pub struct MHPMCOUNTER4; 40 | 41 | impl MHPMCOUNTER4 { 42 | /// Read mhpmcounter4 and mhpmcounter4h registers. 43 | #[inline] 44 | pub fn value(&self) -> u64 { 45 | mhpmcounter4::read64() 46 | } 47 | } 48 | 49 | /// Performance counters 50 | pub struct PerformanceCounters { 51 | /// 64-bit mcycle counter 52 | pub mcycle: MCYCLE, 53 | /// 64-bit minstret counter 54 | pub minstret: MINSTRET, 55 | /// 40-bit mhpmcounter3 counter 56 | pub mhpmcounter3: MHPMCOUNTER3, 57 | /// 40-bit mhpmcounter4 counter 58 | pub mhpmcounter4: MHPMCOUNTER4, 59 | // TODO: mhpmevent3, mhpmevent4 60 | } 61 | 62 | impl PerformanceCounters { 63 | pub(crate) const fn new() -> Self { 64 | Self { 65 | mcycle: MCYCLE, 66 | minstret: MINSTRET, 67 | mhpmcounter3: MHPMCOUNTER3, 68 | mhpmcounter4: MHPMCOUNTER4, 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /.github/workflows/e310x.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | pull_request: 5 | merge_group: 6 | 7 | name: Build check (e310x) 8 | 9 | jobs: 10 | # We check that the crate builds and links for all the toolchains and targets. 11 | build-riscv: 12 | strategy: 13 | matrix: 14 | # All generated code should be running on stable now, MRSV is 1.76.0 15 | toolchain: [ stable, nightly, 1.76.0 ] 16 | include: 17 | # Nightly is only for reference and allowed to fail 18 | - toolchain: nightly 19 | experimental: true 20 | runs-on: ubuntu-latest 21 | continue-on-error: ${{ matrix.experimental || false }} 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Update Rust toolchain 25 | run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} 26 | - name: Install Rust target 27 | run: rustup target install riscv32imc-unknown-none-elf 28 | - name: Build (no features) 29 | run: cargo build --package e310x 30 | - name: Build (all features) 31 | run: cargo build --package e310x --all-features 32 | 33 | # On MacOS and Ubuntu, we at least make sure that the crate builds and links. 34 | # On Windows, linking fails when the rt feature is enabled. 35 | build-others: 36 | strategy: 37 | matrix: 38 | os: [ macos-latest, ubuntu-latest ] 39 | runs-on: ${{ matrix.os }} 40 | steps: 41 | - uses: actions/checkout@v4 42 | - name: Update Rust toolchain 43 | run: rustup update stable && rustup default stable 44 | - name: Rename .cargo/config to .cargo/config.bak to ignore it 45 | run: mv .cargo/config.toml .cargo/config.bak 46 | - name: Build (no features) 47 | run: cargo test --package e310x 48 | - name: Build (all features) 49 | run: cargo test --package e310x --all-features 50 | -------------------------------------------------------------------------------- /e310x-hal/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/d/e310x-hal.svg)](https://crates.io/crates/e310x-hal) 2 | [![crates.io](https://img.shields.io/crates/v/e310x-hal.svg)](https://crates.io/crates/e310x-hal) 3 | [![Build Status](https://travis-ci.org/riscv-rust/e310x-hal.svg?branch=master)](https://travis-ci.org/riscv-rust/e310x-hal) 4 | 5 | # `e310x-hal` 6 | 7 | > HAL for the E310x family of microcontrollers. 8 | 9 | This project is developed and maintained by the [RISC-V team][team]. 10 | 11 | ## [Documentation](https://docs.rs/crate/e310x-hal) 12 | 13 | ## Minimum Supported Rust Version (MSRV) 14 | 15 | This crate is guaranteed to compile on stable Rust 1.79.0 and up. It *might* 16 | compile with older versions but that may change in any new patch release. 17 | 18 | ## License 19 | 20 | Copyright 2018-2019 [RISC-V team][team] 21 | 22 | Permission to use, copy, modify, and/or distribute this software for any purpose 23 | with or without fee is hereby granted, provided that the above copyright notice 24 | and this permission notice appear in all copies. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 27 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 28 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 29 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 30 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 31 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 32 | THIS SOFTWARE. 33 | 34 | ## Code of Conduct 35 | 36 | Contribution to this crate is organized under the terms of the [Rust Code of 37 | Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises 38 | to intervene to uphold that code of conduct. 39 | 40 | [CoC]: CODE_OF_CONDUCT.md 41 | [team]: https://github.com/rust-embedded/wg#the-risc-v-team 42 | -------------------------------------------------------------------------------- /.github/workflows/e310x-hal.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | pull_request: 5 | merge_group: 6 | 7 | name: Build check (e310x-hal) 8 | 9 | jobs: 10 | # We check that the crate builds and links for all the toolchains and targets. 11 | build-riscv: 12 | strategy: 13 | matrix: 14 | # All generated code should be running on stable now, MRSV is 1.79.0 15 | toolchain: [ stable, nightly, 1.79.0 ] 16 | include: 17 | # Nightly is only for reference and allowed to fail 18 | - toolchain: nightly 19 | experimental: true 20 | runs-on: ubuntu-latest 21 | continue-on-error: ${{ matrix.experimental || false }} 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Update Rust toolchain 25 | run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} 26 | - name: Install Rust target 27 | run: rustup target install riscv32imc-unknown-none-elf 28 | - name: Build (no features) 29 | run: cargo build --package e310x-hal 30 | - name: Build (all features) 31 | run: cargo build --package e310x-hal --all-features 32 | 33 | # On MacOS and Ubuntu, we at least make sure that the crate builds and links. 34 | # On Windows, linking fails when the rt feature is enabled. 35 | build-others: 36 | strategy: 37 | matrix: 38 | os: [ macos-latest, ubuntu-latest ] 39 | runs-on: ${{ matrix.os }} 40 | steps: 41 | - uses: actions/checkout@v4 42 | - name: Update Rust toolchain 43 | run: rustup update stable && rustup default stable 44 | - name: Rename .cargo/config to .cargo/config.bak to ignore it 45 | run: mv .cargo/config.toml .cargo/config.bak 46 | - name: Build (no features) 47 | run: cargo test --package e310x-hal 48 | - name: Build (all features) 49 | run: cargo test --package e310x-hal --all-features 50 | 51 | -------------------------------------------------------------------------------- /e310x/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/d/e310x.svg)](https://crates.io/crates/e310x) 2 | [![crates.io](https://img.shields.io/crates/v/e310x.svg)](https://crates.io/crates/e310x) 3 | 4 | # `e310x` 5 | 6 | > With svd2rust generated peripherals for Freedom E310 MCU's. 7 | 8 | This project is developed and maintained by the [RISC-V team][team]. 9 | 10 | ## [Documentation](https://docs.rs/crate/e310x) 11 | 12 | ## Minimum Supported Rust Version (MSRV) 13 | 14 | This crate is guaranteed to compile on stable Rust 1.72.0 and up. It *might* 15 | compile with older versions but that may change in any new patch release. 16 | 17 | ## Requirements 18 | 19 | Install [form](https://crates.io/crates/form) and [svd2rust](https://crates.io/crates/svd2rust) using cargo install 20 | 21 | ## License 22 | 23 | Copyright 2018-2023 [RISC-V team][team] 24 | 25 | Permission to use, copy, modify, and/or distribute this software for any purpose 26 | with or without fee is hereby granted, provided that the above copyright notice 27 | and this permission notice appear in all copies. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 30 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 32 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 33 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 34 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 35 | THIS SOFTWARE. 36 | 37 | ## Code of Conduct 38 | 39 | Contribution to this crate is organized under the terms of the [Rust Code of 40 | Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises 41 | to intervene to uphold that code of conduct. 42 | 43 | [CoC]: CODE_OF_CONDUCT.md 44 | [team]: https://github.com/rust-embedded/wg#the-risc-v-team 45 | -------------------------------------------------------------------------------- /e310x/src/uart0/ie.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `ie` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `ie` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `txwm` reader - "] 6 | pub type TxwmR = crate::BitReader; 7 | #[doc = "Field `txwm` writer - "] 8 | pub type TxwmW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `rxwm` reader - "] 10 | pub type RxwmR = crate::BitReader; 11 | #[doc = "Field `rxwm` writer - "] 12 | pub type RxwmW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 0"] 15 | #[inline(always)] 16 | pub fn txwm(&self) -> TxwmR { 17 | TxwmR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1"] 20 | #[inline(always)] 21 | pub fn rxwm(&self) -> RxwmR { 22 | RxwmR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0"] 27 | #[inline(always)] 28 | pub fn txwm(&mut self) -> TxwmW<'_, IeSpec> { 29 | TxwmW::new(self, 0) 30 | } 31 | #[doc = "Bit 1"] 32 | #[inline(always)] 33 | pub fn rxwm(&mut self) -> RxwmW<'_, IeSpec> { 34 | RxwmW::new(self, 1) 35 | } 36 | } 37 | #[doc = "Interrupt Enable Register\n\nYou can [`read`](crate::Reg::read) this register and get [`ie::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`ie::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct IeSpec; 39 | impl crate::RegisterSpec for IeSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`ie::R`](R) reader structure"] 43 | impl crate::Readable for IeSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`ie::W`](W) writer structure"] 45 | impl crate::Writable for IeSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets ie to value 0"] 49 | impl crate::Resettable for IeSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/uart0/ip.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `ip` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `ip` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `txwm` reader - "] 6 | pub type TxwmR = crate::BitReader; 7 | #[doc = "Field `txwm` writer - "] 8 | pub type TxwmW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `rxwm` reader - "] 10 | pub type RxwmR = crate::BitReader; 11 | #[doc = "Field `rxwm` writer - "] 12 | pub type RxwmW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 0"] 15 | #[inline(always)] 16 | pub fn txwm(&self) -> TxwmR { 17 | TxwmR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1"] 20 | #[inline(always)] 21 | pub fn rxwm(&self) -> RxwmR { 22 | RxwmR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0"] 27 | #[inline(always)] 28 | pub fn txwm(&mut self) -> TxwmW<'_, IpSpec> { 29 | TxwmW::new(self, 0) 30 | } 31 | #[doc = "Bit 1"] 32 | #[inline(always)] 33 | pub fn rxwm(&mut self) -> RxwmW<'_, IpSpec> { 34 | RxwmW::new(self, 1) 35 | } 36 | } 37 | #[doc = "Interrupt Pending Register\n\nYou can [`read`](crate::Reg::read) this register and get [`ip::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`ip::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct IpSpec; 39 | impl crate::RegisterSpec for IpSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`ip::R`](R) reader structure"] 43 | impl crate::Readable for IpSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`ip::W`](W) writer structure"] 45 | impl crate::Writable for IpSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets ip to value 0"] 49 | impl crate::Resettable for IpSpec {} 50 | -------------------------------------------------------------------------------- /hifive1-examples/examples/i2c_max3010x.rs: -------------------------------------------------------------------------------- 1 | //! Sample example for the MAX3010x pulse oximeter and heart rate sensor 2 | //! using the I2C interface. 3 | 4 | #![no_std] 5 | #![no_main] 6 | 7 | use hifive1::{ 8 | clock, 9 | hal::{ 10 | i2c::{I2c, Speed}, 11 | prelude::*, 12 | DeviceResources, 13 | }, 14 | pin, sprintln, 15 | }; 16 | use max3010x::{Led, Max3010x, SampleAveraging}; 17 | extern crate panic_halt; 18 | 19 | #[riscv_rt::entry] 20 | fn main() -> ! { 21 | let dr = DeviceResources::take().unwrap(); 22 | let cp = dr.core_peripherals; 23 | let p = dr.peripherals; 24 | let pins = dr.pins; 25 | 26 | // Configure clocks 27 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 28 | 29 | // Configure UART for stdout 30 | hifive1::stdout::configure( 31 | p.UART0, 32 | pin!(pins, uart0_tx), 33 | pin!(pins, uart0_rx), 34 | 115_200.bps(), 35 | clocks, 36 | ); 37 | 38 | let sda = pin!(pins, i2c0_sda).into_iof0(); 39 | let scl = pin!(pins, i2c0_scl).into_iof0(); 40 | let i2c = I2c::new(p.I2C0, sda, scl, Speed::Normal, clocks); 41 | 42 | let mut sensor = Max3010x::new_max30102(i2c); 43 | let part_id = sensor.get_part_id().unwrap(); 44 | sprintln!("Part ID: {:x}", part_id); // This should print "Part ID: 0x15" for a MAX30102. 45 | 46 | let mut sensor = sensor.into_heart_rate().unwrap(); 47 | sensor.set_sample_averaging(SampleAveraging::Sa4).unwrap(); 48 | sensor.set_pulse_amplitude(Led::All, 15).unwrap(); 49 | sensor.enable_fifo_rollover().unwrap(); 50 | 51 | let mut data = [0; 3]; 52 | 53 | // Get the MTIMER peripheral from CLINT 54 | let mut mtimer = cp.clint.mtimer(); 55 | const STEP: u32 = 1000; // 1s 56 | loop { 57 | let samples_read = sensor.read_fifo(&mut data).unwrap(); 58 | sprintln!("Samples read: {}", samples_read); 59 | mtimer.delay_ms(STEP); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /hifive1/src/flash.rs: -------------------------------------------------------------------------------- 1 | //! On-board SPI Flash 2 | 3 | use e310x_hal::clock::Clocks; 4 | use e310x_hal::e310x::Qspi0; 5 | 6 | #[cfg(target_arch = "riscv32")] 7 | core::arch::global_asm!( 8 | r#" 9 | .cfi_sections .debug_frame 10 | 11 | .section .data._setup_is25lp 12 | .global _setup_is25lp 13 | .cfi_startproc 14 | _setup_is25lp: 15 | li a1, 0x10014000 // QSPI0 base address 16 | 17 | // Disable mapped region 18 | sw zero,96(a1) // fctrl.en = 0 19 | 20 | // Construct ffmt value for 4 dummy cycles 21 | li a2, 0x00BB1447 22 | 23 | beqz a0, 2f 24 | 25 | // We need to set 8 dummy cycles instead of 4. 26 | // Issue a "Set Read Parameters" command. 27 | 28 | li a0,2 29 | sw a0,24(a1) // csmode = HOLD 30 | li a0,0xC0 31 | sw a0,72(a1) // txdata = 0xC0 32 | li a0,0xF0 33 | sw a0,72(a1) // txdata = 0xF0 34 | sw zero,24(a1) // csmode = AUTO 35 | 36 | // Discard two response bytes 37 | 1: lw a0,76(a1) 38 | bltz a0,1b 39 | 1: lw a0,76(a1) 40 | bltz a0,1b 41 | 42 | addi a2,a2,0x40 // ffmt: 4 -> 8 dummy cycles 43 | 2: 44 | sw a2,100(a1) // Write ffmt 45 | 46 | // Enable mapped region 47 | li a0, 1 48 | sw a0,96(a1) // fctrl.en = 1 49 | ret 50 | 51 | .cfi_endproc 52 | .size _setup_is25lp, . - _setup_is25lp 53 | "# 54 | ); 55 | 56 | /// Configure SPI Flash interface to maximum supported speed 57 | #[inline(always)] 58 | pub fn configure_spi_flash(qspi: &Qspi0, clocks: &Clocks) { 59 | unsafe { 60 | extern "C" { 61 | fn _setup_is25lp(dummy8: bool); 62 | } 63 | 64 | if clocks.coreclk().0 <= 208_000_000 { 65 | _setup_is25lp(false) 66 | } else { 67 | _setup_is25lp(true) 68 | } 69 | } 70 | qspi.sckdiv().modify(|_, w| unsafe { w.div().bits(0) }); 71 | } 72 | -------------------------------------------------------------------------------- /e310x/src/uart0/txdata.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `txdata` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `txdata` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `data` reader - "] 6 | pub type DataR = crate::FieldReader; 7 | #[doc = "Field `data` writer - "] 8 | pub type DataW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `full` reader - "] 10 | pub type FullR = crate::BitReader; 11 | #[doc = "Field `full` writer - "] 12 | pub type FullW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bits 0:7"] 15 | #[inline(always)] 16 | pub fn data(&self) -> DataR { 17 | DataR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bit 31"] 20 | #[inline(always)] 21 | pub fn full(&self) -> FullR { 22 | FullR::new(((self.bits >> 31) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7"] 27 | #[inline(always)] 28 | pub fn data(&mut self) -> DataW<'_, TxdataSpec> { 29 | DataW::new(self, 0) 30 | } 31 | #[doc = "Bit 31"] 32 | #[inline(always)] 33 | pub fn full(&mut self) -> FullW<'_, TxdataSpec> { 34 | FullW::new(self, 31) 35 | } 36 | } 37 | #[doc = "Transmit Data Register\n\nYou can [`read`](crate::Reg::read) this register and get [`txdata::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`txdata::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct TxdataSpec; 39 | impl crate::RegisterSpec for TxdataSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`txdata::R`](R) reader structure"] 43 | impl crate::Readable for TxdataSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`txdata::W`](W) writer structure"] 45 | impl crate::Writable for TxdataSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets txdata to value 0"] 49 | impl crate::Resettable for TxdataSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/uart0/rxdata.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rxdata` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rxdata` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `data` reader - "] 6 | pub type DataR = crate::FieldReader; 7 | #[doc = "Field `data` writer - "] 8 | pub type DataW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `empty` reader - "] 10 | pub type EmptyR = crate::BitReader; 11 | #[doc = "Field `empty` writer - "] 12 | pub type EmptyW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bits 0:7"] 15 | #[inline(always)] 16 | pub fn data(&self) -> DataR { 17 | DataR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bit 31"] 20 | #[inline(always)] 21 | pub fn empty(&self) -> EmptyR { 22 | EmptyR::new(((self.bits >> 31) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7"] 27 | #[inline(always)] 28 | pub fn data(&mut self) -> DataW<'_, RxdataSpec> { 29 | DataW::new(self, 0) 30 | } 31 | #[doc = "Bit 31"] 32 | #[inline(always)] 33 | pub fn empty(&mut self) -> EmptyW<'_, RxdataSpec> { 34 | EmptyW::new(self, 31) 35 | } 36 | } 37 | #[doc = "Receive Data Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rxdata::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rxdata::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct RxdataSpec; 39 | impl crate::RegisterSpec for RxdataSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`rxdata::R`](R) reader structure"] 43 | impl crate::Readable for RxdataSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`rxdata::W`](W) writer structure"] 45 | impl crate::Writable for RxdataSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets rxdata to value 0"] 49 | impl crate::Resettable for RxdataSpec {} 50 | -------------------------------------------------------------------------------- /e310x-hal/src/spi/shared_bus.rs: -------------------------------------------------------------------------------- 1 | use core::cell::RefCell; 2 | use core::ops::Deref; 3 | use embedded_hal::delay::DelayNs; 4 | use riscv::interrupt; 5 | 6 | use super::{PinCS, PinsNoCS, SpiBus, SpiConfig, SpiSharedDevice, SpiX}; 7 | 8 | /// Newtype for RefCell locked behind a Mutex. 9 | /// Used to hold the [SpiBus] instance so it can be used for multiple [SpiSharedDevice] instances. 10 | pub struct SharedBus(RefCell>); 11 | 12 | impl SharedBus 13 | where 14 | SPI: SpiX, 15 | PINS: PinsNoCS, 16 | { 17 | pub(crate) fn new(bus: SpiBus) -> Self { 18 | Self(RefCell::new(bus)) 19 | } 20 | 21 | /// Create a new shared device on this SPI bus. 22 | pub fn new_device<'bus, CS, D>( 23 | &'bus self, 24 | cs: CS, 25 | config: &SpiConfig, 26 | delay: D, 27 | ) -> SpiSharedDevice<'bus, SPI, PINS, CS, D> 28 | where 29 | CS: PinCS, 30 | D: DelayNs, 31 | { 32 | SpiSharedDevice::new(self, cs, config, delay) 33 | } 34 | } 35 | 36 | impl SharedBus 37 | where 38 | SPI: SpiX, 39 | PINS: PinsNoCS, 40 | { 41 | /// Set HOLD CS mode to per-frame operation, unless CSMODE is set to OFF 42 | pub fn start_frame(&mut self) { 43 | interrupt::free(|| { 44 | let mut bus = self.0.borrow_mut(); 45 | bus.start_frame(); 46 | }); 47 | } 48 | 49 | /// Finishes transfer by deasserting CS (only for hardware-controlled CS) 50 | pub fn end_frame(&mut self) { 51 | interrupt::free(|| { 52 | let mut bus = self.0.borrow_mut(); 53 | bus.end_frame(); 54 | }); 55 | } 56 | 57 | /// Releases the SPI peripheral and associated pins 58 | pub fn release(self) -> (SPI, PINS) { 59 | self.0.into_inner().release() 60 | } 61 | } 62 | 63 | impl Deref for SharedBus { 64 | type Target = RefCell>; 65 | 66 | fn deref(&self) -> &Self::Target { 67 | &self.0 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /e310x/src/uart0/rxctrl.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rxctrl` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rxctrl` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `enable` reader - "] 6 | pub type EnableR = crate::BitReader; 7 | #[doc = "Field `enable` writer - "] 8 | pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `counter` reader - "] 10 | pub type CounterR = crate::FieldReader; 11 | #[doc = "Field `counter` writer - "] 12 | pub type CounterW<'a, REG> = crate::FieldWriter<'a, REG, 3>; 13 | impl R { 14 | #[doc = "Bit 0"] 15 | #[inline(always)] 16 | pub fn enable(&self) -> EnableR { 17 | EnableR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bits 16:18"] 20 | #[inline(always)] 21 | pub fn counter(&self) -> CounterR { 22 | CounterR::new(((self.bits >> 16) & 7) as u8) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0"] 27 | #[inline(always)] 28 | pub fn enable(&mut self) -> EnableW<'_, RxctrlSpec> { 29 | EnableW::new(self, 0) 30 | } 31 | #[doc = "Bits 16:18"] 32 | #[inline(always)] 33 | pub fn counter(&mut self) -> CounterW<'_, RxctrlSpec> { 34 | CounterW::new(self, 16) 35 | } 36 | } 37 | #[doc = "Receive Control Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rxctrl::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rxctrl::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct RxctrlSpec; 39 | impl crate::RegisterSpec for RxctrlSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`rxctrl::R`](R) reader structure"] 43 | impl crate::Readable for RxctrlSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`rxctrl::W`](W) writer structure"] 45 | impl crate::Writable for RxctrlSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets rxctrl to value 0"] 49 | impl crate::Resettable for RxctrlSpec {} 50 | -------------------------------------------------------------------------------- /hifive1-examples/examples/spi_rc522.rs: -------------------------------------------------------------------------------- 1 | //! Basic example of the RC522 RFID reader using the SPI interface. 2 | 3 | #![no_std] 4 | #![no_main] 5 | 6 | use hifive1::{ 7 | clock, 8 | hal::{ 9 | prelude::*, 10 | spi::{SpiBus, SpiConfig, MODE_0}, 11 | DeviceResources, 12 | }, 13 | pin, sprintln, 14 | }; 15 | use mfrc522::{comm::blocking::spi::SpiInterface, Mfrc522}; 16 | extern crate panic_halt; 17 | 18 | #[riscv_rt::entry] 19 | fn main() -> ! { 20 | let dr = DeviceResources::take().unwrap(); 21 | let cp = dr.core_peripherals; 22 | let p = dr.peripherals; 23 | let pins = dr.pins; 24 | 25 | // Configure clocks 26 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 27 | 28 | // Configure UART for stdout 29 | hifive1::stdout::configure( 30 | p.UART0, 31 | pin!(pins, uart0_tx), 32 | pin!(pins, uart0_rx), 33 | 115_200.bps(), 34 | clocks, 35 | ); 36 | 37 | let sck = pin!(pins, spi1_sck).into_iof0(); 38 | let miso = pin!(pins, spi1_miso).into_iof0(); 39 | let mosi = pin!(pins, spi1_mosi).into_iof0(); 40 | let cs = pin!(pins, spi1_ss0).into_iof0(); 41 | 42 | let delay = riscv::delay::McycleDelay::new(clocks.coreclk().0); 43 | let spi_bus = SpiBus::new(p.QSPI1, (mosi, miso, sck, cs)); 44 | let spi_cfg = SpiConfig::new(MODE_0, 1_000_000.hz(), &clocks); 45 | let spi_device = spi_bus.new_device(&spi_cfg, delay); 46 | let spi_itf = SpiInterface::new(spi_device); 47 | 48 | let mut mfrc522 = match Mfrc522::new(spi_itf).init() { 49 | Ok(mfrc522) => mfrc522, 50 | Err(e) => { 51 | sprintln!("Error initializing sensor: {:?}", e); 52 | loop {} 53 | } 54 | }; 55 | // The reported version is expected to be 0x91 or 0x92 56 | let version = mfrc522.version().unwrap(); 57 | sprintln!("Version: {:x}", version); 58 | 59 | // Get the sleep struct from CLINT 60 | let mut mtimer = cp.clint.mtimer(); 61 | const STEP: u32 = 1000; // 1s 62 | loop { 63 | mtimer.delay_ms(STEP); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /e310x/src/prci/hfxosccfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `hfxosccfg` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `hfxosccfg` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `enable` reader - "] 6 | pub type EnableR = crate::BitReader; 7 | #[doc = "Field `enable` writer - "] 8 | pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `ready` reader - "] 10 | pub type ReadyR = crate::BitReader; 11 | #[doc = "Field `ready` writer - "] 12 | pub type ReadyW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 30"] 15 | #[inline(always)] 16 | pub fn enable(&self) -> EnableR { 17 | EnableR::new(((self.bits >> 30) & 1) != 0) 18 | } 19 | #[doc = "Bit 31"] 20 | #[inline(always)] 21 | pub fn ready(&self) -> ReadyR { 22 | ReadyR::new(((self.bits >> 31) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 30"] 27 | #[inline(always)] 28 | pub fn enable(&mut self) -> EnableW<'_, HfxosccfgSpec> { 29 | EnableW::new(self, 30) 30 | } 31 | #[doc = "Bit 31"] 32 | #[inline(always)] 33 | pub fn ready(&mut self) -> ReadyW<'_, HfxosccfgSpec> { 34 | ReadyW::new(self, 31) 35 | } 36 | } 37 | #[doc = "Clock Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`hfxosccfg::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`hfxosccfg::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct HfxosccfgSpec; 39 | impl crate::RegisterSpec for HfxosccfgSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`hfxosccfg::R`](R) reader structure"] 43 | impl crate::Readable for HfxosccfgSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`hfxosccfg::W`](W) writer structure"] 45 | impl crate::Writable for HfxosccfgSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets hfxosccfg to value 0"] 49 | impl crate::Resettable for HfxosccfgSpec {} 50 | -------------------------------------------------------------------------------- /e310x-hal/src/spi.rs: -------------------------------------------------------------------------------- 1 | //! # Serial Peripheral Interface 2 | //! 3 | //! You can use the `Spi` interface with these SPI instances 4 | //! 5 | //! # QSPI0 6 | //! - Interrupt::QSPI0 7 | //! 8 | //! # QSPI1 9 | //! - MOSI: Pin 3 IOF0 10 | //! - MISO: Pin 4 IOF0 11 | //! - SCK: Pin 5 IOF0 12 | //! - CS0: Pin 2 IOF0 13 | //! - CS1: Pin 8 IOF0 (not connected to package in FE310) 14 | //! - CS2: Pin 9 IOF0 15 | //! - CS3: Pin 10 IOF0 16 | //! - Interrupt::QSPI1 17 | //! 18 | //! # QSPI2 19 | //! *Warning:* QSPI2 pins are not connected to package in FE310 20 | //! - MOSI: Pin 27 IOF0 21 | //! - MISO: Pin 28 IOF0 22 | //! - SCK: Pin 29 IOF0 23 | //! - CS: Pin 26 IOF0 24 | //! - Interrupt::QSPI2 25 | //! 26 | //! # Exclusive Bus usage example 27 | //!```ignore 28 | //! let pins = (mosi, miso, sck, cs0); 29 | //! let spi_bus = SpiBus::new(p.QSPI1, pins); 30 | //! 31 | //! let spi_config = SpiConfig::new(MODE_0, 100.khz().into(), &clocks); 32 | //! let mut dev = spi_bus.new_device(&spi_config); 33 | //! 34 | //! dev.write(&[1, 2, 3]).unwrap(); 35 | //!``` 36 | //! 37 | //! # Shared Bus usage example 38 | //!```ignore 39 | //! let pins = (mosi, miso, sck); 40 | //! let spi_bus = SpiBus::shared(p.QSPI1, pins); 41 | //! 42 | //! let spi_config1 = SpiConfig::new(MODE_0, 100.khz().into(), &clocks); 43 | //! let mut dev1 = spi_bus.new_device(cs0, &spi_config1); 44 | //! 45 | //! let spi_config2 = SpiConfig::new(MODE_3, 2.mhz().into(), &clocks); 46 | //! let mut dev2 = spi_bus.new_device(cs1, &spi_config2); 47 | //! 48 | //! dev1.write(&[1, 2, 3]).unwrap(); 49 | //! dev2.write(&[4, 5]).unwrap(); 50 | //!``` 51 | 52 | mod bus; // contains the SPI Bus abstraction 53 | mod config; 54 | mod exclusive_device; // contains the exclusive SPI device abstraction 55 | mod shared_bus; // shared bus newtype 56 | mod shared_device; // contains the shared SPI device abstraction 57 | mod traits; // contains SPI device abstraction 58 | 59 | pub use bus::*; 60 | pub use config::*; 61 | pub use exclusive_device::*; 62 | pub use shared_bus::*; 63 | pub use shared_device::*; 64 | pub use traits::*; 65 | 66 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 67 | -------------------------------------------------------------------------------- /e310x/src/i2c0/ctr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `ctr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `ctr` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `ien` reader - I2C core interrupt enable bit"] 6 | pub type IenR = crate::BitReader; 7 | #[doc = "Field `ien` writer - I2C core interrupt enable bit"] 8 | pub type IenW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `en` reader - I2C core enable bit"] 10 | pub type EnR = crate::BitReader; 11 | #[doc = "Field `en` writer - I2C core enable bit"] 12 | pub type EnW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 6 - I2C core interrupt enable bit"] 15 | #[inline(always)] 16 | pub fn ien(&self) -> IenR { 17 | IenR::new(((self.bits >> 6) & 1) != 0) 18 | } 19 | #[doc = "Bit 7 - I2C core enable bit"] 20 | #[inline(always)] 21 | pub fn en(&self) -> EnR { 22 | EnR::new(((self.bits >> 7) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 6 - I2C core interrupt enable bit"] 27 | #[inline(always)] 28 | pub fn ien(&mut self) -> IenW<'_, CtrSpec> { 29 | IenW::new(self, 6) 30 | } 31 | #[doc = "Bit 7 - I2C core enable bit"] 32 | #[inline(always)] 33 | pub fn en(&mut self) -> EnW<'_, CtrSpec> { 34 | EnW::new(self, 7) 35 | } 36 | } 37 | #[doc = "Control register\n\nYou can [`read`](crate::Reg::read) this register and get [`ctr::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`ctr::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct CtrSpec; 39 | impl crate::RegisterSpec for CtrSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`ctr::R`](R) reader structure"] 43 | impl crate::Readable for CtrSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`ctr::W`](W) writer structure"] 45 | impl crate::Writable for CtrSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets ctr to value 0"] 49 | impl crate::Resettable for CtrSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/prci/plloutdiv.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `plloutdiv` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `plloutdiv` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `div` reader - "] 6 | pub type DivR = crate::FieldReader; 7 | #[doc = "Field `div` writer - "] 8 | pub type DivW<'a, REG> = crate::FieldWriter<'a, REG, 6>; 9 | #[doc = "Field `divby1` reader - "] 10 | pub type Divby1R = crate::BitReader; 11 | #[doc = "Field `divby1` writer - "] 12 | pub type Divby1W<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bits 0:5"] 15 | #[inline(always)] 16 | pub fn div(&self) -> DivR { 17 | DivR::new((self.bits & 0x3f) as u8) 18 | } 19 | #[doc = "Bit 8"] 20 | #[inline(always)] 21 | pub fn divby1(&self) -> Divby1R { 22 | Divby1R::new(((self.bits >> 8) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:5"] 27 | #[inline(always)] 28 | pub fn div(&mut self) -> DivW<'_, PlloutdivSpec> { 29 | DivW::new(self, 0) 30 | } 31 | #[doc = "Bit 8"] 32 | #[inline(always)] 33 | pub fn divby1(&mut self) -> Divby1W<'_, PlloutdivSpec> { 34 | Divby1W::new(self, 8) 35 | } 36 | } 37 | #[doc = "PLL Divider Register\n\nYou can [`read`](crate::Reg::read) this register and get [`plloutdiv::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`plloutdiv::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct PlloutdivSpec; 39 | impl crate::RegisterSpec for PlloutdivSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`plloutdiv::R`](R) reader structure"] 43 | impl crate::Readable for PlloutdivSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`plloutdiv::W`](W) writer structure"] 45 | impl crate::Writable for PlloutdivSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets plloutdiv to value 0x0100"] 49 | impl crate::Resettable for PlloutdivSpec { 50 | const RESET_VALUE: u32 = 0x0100; 51 | } 52 | -------------------------------------------------------------------------------- /e310x/src/qspi0/txdata.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `txdata` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `txdata` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `data` reader - Transmit data"] 6 | pub type DataR = crate::FieldReader; 7 | #[doc = "Field `data` writer - Transmit data"] 8 | pub type DataW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `full` reader - FIFO full flag"] 10 | pub type FullR = crate::BitReader; 11 | #[doc = "Field `full` writer - FIFO full flag"] 12 | pub type FullW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bits 0:7 - Transmit data"] 15 | #[inline(always)] 16 | pub fn data(&self) -> DataR { 17 | DataR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bit 31 - FIFO full flag"] 20 | #[inline(always)] 21 | pub fn full(&self) -> FullR { 22 | FullR::new(((self.bits >> 31) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7 - Transmit data"] 27 | #[inline(always)] 28 | pub fn data(&mut self) -> DataW<'_, TxdataSpec> { 29 | DataW::new(self, 0) 30 | } 31 | #[doc = "Bit 31 - FIFO full flag"] 32 | #[inline(always)] 33 | pub fn full(&mut self) -> FullW<'_, TxdataSpec> { 34 | FullW::new(self, 31) 35 | } 36 | } 37 | #[doc = "Transmit Data Register\n\nYou can [`read`](crate::Reg::read) this register and get [`txdata::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`txdata::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct TxdataSpec; 39 | impl crate::RegisterSpec for TxdataSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`txdata::R`](R) reader structure"] 43 | impl crate::Readable for TxdataSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`txdata::W`](W) writer structure"] 45 | impl crate::Writable for TxdataSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets txdata to value 0"] 49 | impl crate::Resettable for TxdataSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/qspi0/ie.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `ie` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `ie` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `txwm` reader - Transmit watermark enable"] 6 | pub type TxwmR = crate::BitReader; 7 | #[doc = "Field `txwm` writer - Transmit watermark enable"] 8 | pub type TxwmW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `rxwm` reader - Receive watermark enable"] 10 | pub type RxwmR = crate::BitReader; 11 | #[doc = "Field `rxwm` writer - Receive watermark enable"] 12 | pub type RxwmW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 0 - Transmit watermark enable"] 15 | #[inline(always)] 16 | pub fn txwm(&self) -> TxwmR { 17 | TxwmR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1 - Receive watermark enable"] 20 | #[inline(always)] 21 | pub fn rxwm(&self) -> RxwmR { 22 | RxwmR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0 - Transmit watermark enable"] 27 | #[inline(always)] 28 | pub fn txwm(&mut self) -> TxwmW<'_, IeSpec> { 29 | TxwmW::new(self, 0) 30 | } 31 | #[doc = "Bit 1 - Receive watermark enable"] 32 | #[inline(always)] 33 | pub fn rxwm(&mut self) -> RxwmW<'_, IeSpec> { 34 | RxwmW::new(self, 1) 35 | } 36 | } 37 | #[doc = "SPI Interrupt Enable Register\n\nYou can [`read`](crate::Reg::read) this register and get [`ie::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`ie::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct IeSpec; 39 | impl crate::RegisterSpec for IeSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`ie::R`](R) reader structure"] 43 | impl crate::Readable for IeSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`ie::W`](W) writer structure"] 45 | impl crate::Writable for IeSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets ie to value 0"] 49 | impl crate::Resettable for IeSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/qspi0/ip.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `ip` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `ip` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `txwm` reader - Transmit watermark enable"] 6 | pub type TxwmR = crate::BitReader; 7 | #[doc = "Field `txwm` writer - Transmit watermark enable"] 8 | pub type TxwmW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `rxwm` reader - Receive watermark enable"] 10 | pub type RxwmR = crate::BitReader; 11 | #[doc = "Field `rxwm` writer - Receive watermark enable"] 12 | pub type RxwmW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 0 - Transmit watermark enable"] 15 | #[inline(always)] 16 | pub fn txwm(&self) -> TxwmR { 17 | TxwmR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1 - Receive watermark enable"] 20 | #[inline(always)] 21 | pub fn rxwm(&self) -> RxwmR { 22 | RxwmR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0 - Transmit watermark enable"] 27 | #[inline(always)] 28 | pub fn txwm(&mut self) -> TxwmW<'_, IpSpec> { 29 | TxwmW::new(self, 0) 30 | } 31 | #[doc = "Bit 1 - Receive watermark enable"] 32 | #[inline(always)] 33 | pub fn rxwm(&mut self) -> RxwmW<'_, IpSpec> { 34 | RxwmW::new(self, 1) 35 | } 36 | } 37 | #[doc = "SPI Interrupt Pending Register\n\nYou can [`read`](crate::Reg::read) this register and get [`ip::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`ip::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct IpSpec; 39 | impl crate::RegisterSpec for IpSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`ip::R`](R) reader structure"] 43 | impl crate::Readable for IpSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`ip::W`](W) writer structure"] 45 | impl crate::Writable for IpSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets ip to value 0"] 49 | impl crate::Resettable for IpSpec {} 50 | -------------------------------------------------------------------------------- /e310x/src/qspi0/rxdata.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rxdata` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rxdata` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `data` reader - Received data"] 6 | pub type DataR = crate::FieldReader; 7 | #[doc = "Field `data` writer - Received data"] 8 | pub type DataW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `empty` reader - FIFO empty flag"] 10 | pub type EmptyR = crate::BitReader; 11 | #[doc = "Field `empty` writer - FIFO empty flag"] 12 | pub type EmptyW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bits 0:7 - Received data"] 15 | #[inline(always)] 16 | pub fn data(&self) -> DataR { 17 | DataR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bit 31 - FIFO empty flag"] 20 | #[inline(always)] 21 | pub fn empty(&self) -> EmptyR { 22 | EmptyR::new(((self.bits >> 31) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7 - Received data"] 27 | #[inline(always)] 28 | pub fn data(&mut self) -> DataW<'_, RxdataSpec> { 29 | DataW::new(self, 0) 30 | } 31 | #[doc = "Bit 31 - FIFO empty flag"] 32 | #[inline(always)] 33 | pub fn empty(&mut self) -> EmptyW<'_, RxdataSpec> { 34 | EmptyW::new(self, 31) 35 | } 36 | } 37 | #[doc = "Receive Data Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rxdata::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rxdata::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct RxdataSpec; 39 | impl crate::RegisterSpec for RxdataSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`rxdata::R`](R) reader structure"] 43 | impl crate::Readable for RxdataSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`rxdata::W`](W) writer structure"] 45 | impl crate::Writable for RxdataSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets rxdata to value 0"] 49 | impl crate::Resettable for RxdataSpec {} 50 | -------------------------------------------------------------------------------- /.github/workflows/hifive1.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | pull_request: 5 | merge_group: 6 | 7 | name: Build check (hifive1) 8 | 9 | jobs: 10 | # We check that the crate builds and links for all the toolchains and targets. 11 | build-riscv: 12 | strategy: 13 | matrix: 14 | # All generated code should be running on stable now, MRSV is 1.79.0 15 | toolchain: [nightly, stable, 1.79.0] 16 | board: [hifive1, hifive1-revb, redv, lofive, lofive-r1] 17 | include: 18 | # Nightly is only for reference and allowed to fail 19 | - toolchain: nightly 20 | experimental: true 21 | runs-on: ubuntu-latest 22 | continue-on-error: ${{ matrix.experimental || false }} 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Update Rust toolchain 26 | run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} 27 | - name: Install Rust target 28 | run: rustup target install riscv32imc-unknown-none-elf 29 | - name: Build (direct) 30 | run: cargo build --package hifive1 --features board-${{ matrix.board }} 31 | - name: Build (vectored) 32 | run: cargo build --package hifive1 --features board-${{ matrix.board }},v-trap 33 | 34 | # On MacOS and Ubuntu, we at least make sure that the crate builds and links. 35 | # On Windows, linking fails when the rt feature is enabled. 36 | build-others: 37 | strategy: 38 | matrix: 39 | os: [ macos-latest, ubuntu-latest ] 40 | board: [hifive1, hifive1-revb, redv, lofive, lofive-r1] 41 | runs-on: ${{ matrix.os }} 42 | steps: 43 | - uses: actions/checkout@v4 44 | - name: Update Rust toolchain 45 | run: rustup update stable && rustup default stable 46 | - name: Rename .cargo/config to .cargo/config.bak to ignore it 47 | run: mv .cargo/config.toml .cargo/config.bak 48 | - name: Build (direct) 49 | run: cargo test --package hifive1 --features board-${{ matrix.board }} 50 | - name: Build (vectored) 51 | run: cargo test --package hifive1 --features board-${{ matrix.board }},v-trap 52 | 53 | -------------------------------------------------------------------------------- /e310x/src/qspi0/sckmode.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `sckmode` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `sckmode` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `pha` reader - Serial clock phase"] 6 | pub type PhaR = crate::BitReader; 7 | #[doc = "Field `pha` writer - Serial clock phase"] 8 | pub type PhaW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `pol` reader - Serial clock polarity"] 10 | pub type PolR = crate::BitReader; 11 | #[doc = "Field `pol` writer - Serial clock polarity"] 12 | pub type PolW<'a, REG> = crate::BitWriter<'a, REG>; 13 | impl R { 14 | #[doc = "Bit 0 - Serial clock phase"] 15 | #[inline(always)] 16 | pub fn pha(&self) -> PhaR { 17 | PhaR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1 - Serial clock polarity"] 20 | #[inline(always)] 21 | pub fn pol(&self) -> PolR { 22 | PolR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bit 0 - Serial clock phase"] 27 | #[inline(always)] 28 | pub fn pha(&mut self) -> PhaW<'_, SckmodeSpec> { 29 | PhaW::new(self, 0) 30 | } 31 | #[doc = "Bit 1 - Serial clock polarity"] 32 | #[inline(always)] 33 | pub fn pol(&mut self) -> PolW<'_, SckmodeSpec> { 34 | PolW::new(self, 1) 35 | } 36 | } 37 | #[doc = "Serial Clock Mode Register\n\nYou can [`read`](crate::Reg::read) this register and get [`sckmode::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`sckmode::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct SckmodeSpec; 39 | impl crate::RegisterSpec for SckmodeSpec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`sckmode::R`](R) reader structure"] 43 | impl crate::Readable for SckmodeSpec {} 44 | #[doc = "`write(|w| ..)` method takes [`sckmode::W`](W) writer structure"] 45 | impl crate::Writable for SckmodeSpec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets sckmode to value 0"] 49 | impl crate::Resettable for SckmodeSpec {} 50 | -------------------------------------------------------------------------------- /e310x-hal/src/delay.rs: -------------------------------------------------------------------------------- 1 | //! # Delays 2 | 3 | use crate::clock::Clocks; 4 | use e310x::Clint; 5 | use embedded_hal::delay::DelayNs; 6 | use riscv::register::mip; 7 | 8 | /// Machine timer (mtime) as a busyloop delay provider 9 | #[derive(Default)] 10 | pub struct Delay; 11 | 12 | const TICKS_PER_SECOND: u64 = 32768; 13 | 14 | impl Delay { 15 | /// Constructs a delay provider based on the machine timer (mtime) 16 | pub fn new() -> Self { 17 | Delay 18 | } 19 | } 20 | 21 | impl DelayNs for Delay { 22 | fn delay_ns(&mut self, ns: u32) { 23 | let ticks = (ns as u64) * TICKS_PER_SECOND / 1_000_000_000; 24 | 25 | let mtime = unsafe { Clint::steal() }.mtimer().mtime(); 26 | let t = mtime.read() + ticks; 27 | while mtime.read() < t {} 28 | } 29 | } 30 | 31 | /// Machine timer (mtime) as a sleep delay provider using mtimecmp 32 | pub struct Sleep { 33 | clock_freq: u32, 34 | } 35 | 36 | impl Sleep { 37 | /// Constructs a delay provider using mtimecmp register to sleep 38 | pub fn new(clocks: Clocks) -> Self { 39 | Sleep { 40 | clock_freq: clocks.lfclk().0, 41 | } 42 | } 43 | } 44 | 45 | impl DelayNs for Sleep { 46 | fn delay_ns(&mut self, ns: u32) { 47 | let ticks = (ns as u64) * u64::from(self.clock_freq) / 1_000_000_000; 48 | let clint = unsafe { e310x::Clint::steal() }; 49 | let t = clint.mtimer().mtime().read() + ticks; 50 | 51 | clint.mtimecmp0().write(t); 52 | 53 | // Enable timer interrupt 54 | unsafe { clint.mtimer().enable() }; 55 | 56 | // Wait For Interrupt will put CPU to sleep until an interrupt hits 57 | // in our case when internal timer mtime value >= mtimecmp value 58 | // after which empty handler gets called and we go into the 59 | // next iteration of this loop 60 | loop { 61 | riscv::asm::wfi(); 62 | 63 | // check if we got the right interrupt cause, otherwise just loop back to wfi 64 | if mip::read().mtimer() { 65 | break; 66 | } 67 | } 68 | 69 | // Clear timer interrupt 70 | clint.mtimer().disable(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /e310x/src/qspi0/delay0.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `delay0` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `delay0` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `cssck` reader - CS to SCK Delay"] 6 | pub type CssckR = crate::FieldReader; 7 | #[doc = "Field `cssck` writer - CS to SCK Delay"] 8 | pub type CssckW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `sckcs` reader - SCK to CS Delay"] 10 | pub type SckcsR = crate::FieldReader; 11 | #[doc = "Field `sckcs` writer - SCK to CS Delay"] 12 | pub type SckcsW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 13 | impl R { 14 | #[doc = "Bits 0:7 - CS to SCK Delay"] 15 | #[inline(always)] 16 | pub fn cssck(&self) -> CssckR { 17 | CssckR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bits 16:23 - SCK to CS Delay"] 20 | #[inline(always)] 21 | pub fn sckcs(&self) -> SckcsR { 22 | SckcsR::new(((self.bits >> 16) & 0xff) as u8) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7 - CS to SCK Delay"] 27 | #[inline(always)] 28 | pub fn cssck(&mut self) -> CssckW<'_, Delay0Spec> { 29 | CssckW::new(self, 0) 30 | } 31 | #[doc = "Bits 16:23 - SCK to CS Delay"] 32 | #[inline(always)] 33 | pub fn sckcs(&mut self) -> SckcsW<'_, Delay0Spec> { 34 | SckcsW::new(self, 16) 35 | } 36 | } 37 | #[doc = "Delay Control 0 Register\n\nYou can [`read`](crate::Reg::read) this register and get [`delay0::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`delay0::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct Delay0Spec; 39 | impl crate::RegisterSpec for Delay0Spec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`delay0::R`](R) reader structure"] 43 | impl crate::Readable for Delay0Spec {} 44 | #[doc = "`write(|w| ..)` method takes [`delay0::W`](W) writer structure"] 45 | impl crate::Writable for Delay0Spec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets delay0 to value 0x0001_0001"] 49 | impl crate::Resettable for Delay0Spec { 50 | const RESET_VALUE: u32 = 0x0001_0001; 51 | } 52 | -------------------------------------------------------------------------------- /e310x-hal/src/spi/config.rs: -------------------------------------------------------------------------------- 1 | use e310x::qspi0::csmode::Mode as CsMode; 2 | use embedded_hal::spi::Mode; 3 | 4 | use crate::{clock::Clocks, time::Hertz}; 5 | 6 | /// SPI Bus configuration 7 | 8 | #[derive(Clone)] 9 | /// SPI Bus configuration 10 | pub struct SpiConfig { 11 | /// SPI Mode 12 | pub mode: Mode, 13 | /// Clock Divisor calculated from frozen core clock frequency and SPI frequency 14 | pub(crate) clock_divisor: u32, 15 | /// CS Mode 16 | pub cs_mode: CsMode, 17 | /// Watermark level for transmits 18 | pub txmark: u8, 19 | /// Watermark level for received 20 | pub rxmark: u8, 21 | /// Configuration values for CS and SCK related delays 22 | pub delays: SpiDelayConfig, 23 | } 24 | 25 | #[derive(Clone)] 26 | /// Configuration values for CS and SCK related delays 27 | pub struct SpiDelayConfig { 28 | /// delay between assert and clock in clock ticks 29 | pub cssck: u8, 30 | /// delay between clock and de-assert in clock ticks 31 | pub sckcs: u8, 32 | /// delay between CS re-assets in clock ticks 33 | pub intercs: u8, 34 | /// delay between frames when not re-asserting CS in clock ticks 35 | pub interxfr: u8, 36 | } 37 | 38 | impl SpiConfig { 39 | /// Create new default configuration with given [Mode] and frequency using core [Clocks] 40 | pub fn new(mode: Mode, freq: Hertz, clocks: &Clocks) -> Self { 41 | let clock_divisor = clocks.tlclk().0 / (2 * freq.0) - 1; 42 | assert!(clock_divisor <= 0xfff); 43 | 44 | Self { 45 | mode, 46 | clock_divisor, 47 | cs_mode: CsMode::Hold, 48 | txmark: 1, 49 | rxmark: 0, 50 | delays: SpiDelayConfig::default(), 51 | } 52 | } 53 | 54 | /// Calculated clock divisor 55 | pub fn clock_divisor(&self) -> u32 { 56 | self.clock_divisor 57 | } 58 | } 59 | 60 | impl Default for SpiDelayConfig { 61 | fn default() -> Self { 62 | Self { 63 | cssck: 1, // 1 cycle delay between CS assert and first clock 64 | sckcs: 1, // 1 cycle delay between last clock and CS de-assert 65 | intercs: 1, // 1 cycle delay between CS re-asserts 66 | interxfr: 0, // no delay intra-frame when not CS re-asserting 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /e310x-hal/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] 9 | 10 | ### Changed 11 | - Update `e310x` dependency and adapt code 12 | - Add interrupt managing methods to `e310x-hal::gpio` module 13 | - Add embedded-hal-async digital module support to `e310x-hal::gpio` module 14 | 15 | ## [v0.12.0] - 2024-12-10 16 | 17 | ### Changed 18 | - Fix `StatefulOutputPin::is_set_high`. It now reads from `output_val` 19 | - UART traits are implemented now from `embedded-hal-nb` 1.0.0 20 | - Update `embedded-hal` to 1.0.0 21 | - Update `riscv` to 0.12.1 22 | - Remove `virq` feature. Now interrupts are handled by `e310x` 23 | - Apply clippy changes 24 | - Use `portable-atomic` with `zaamo` feature to use native `amo*` operations. 25 | - Official target is now `riscv32imc-unknown-none-elf`, as it does not fully support the A extension. 26 | - Update `e310x` dependency and adapt code 27 | - Bump MSRV to 1.76.0 28 | 29 | ## [v0.10.0] - 2023-03-28 30 | 31 | ### Added 32 | - Added Pulse Width Modulation interface implementing `embedded_hal::Pwm` 33 | - Added `interrupt` module for vectored interrupt handlers. This module is only active if feature `virq` is selected. 34 | 35 | ### Changed 36 | - Refactored `e310x-hal::spi` module, splitting the abstraction into `SpiBus` and `SpiExclusiveDevice/SpiSharedDevice` to allow multiple devices on a single SPI bus to co-exist 37 | - Update `e310x` dependency to version 0.11 38 | - Update `riscv` dependency to version 0.10 39 | 40 | ### Removed 41 | - removed interrupt linking definitions, they are now provided by `e310x` via `svd2rust` 42 | 43 | ## [v0.9.4] - 2022-07-10 44 | 45 | ### Changed 46 | 47 | - Fixed code still using old `riscv::interrupt::Nr` 48 | 49 | ## [v0.9.3] - 2021-08-15 50 | 51 | ### Changed 52 | 53 | - Fixed `e310x-hal::delay::Delay` call typo to `delay_ms` 54 | 55 | ## [v0.9.2] - 2021-07-17 56 | 57 | ### Changed 58 | 59 | - Fixed `e310x-hal::delay::Delay` timing typo with extra 0 60 | 61 | ## [v0.9.1] - 2021-07-15 62 | 63 | ### Added 64 | 65 | - Added implementation of `embedded_hal::blocking::delay::DelayUs` for `e310x-hal::delay::Delay` using `MTIME` 66 | -------------------------------------------------------------------------------- /hifive1/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/d/hifive1.svg)](https://crates.io/crates/hifive1) 2 | [![crates.io](https://img.shields.io/crates/v/hifive1.svg)](https://crates.io/crates/hifive1) 3 | [![Build Status](https://travis-ci.org/riscv-rust/hifive1.svg?branch=master)](https://travis-ci.org/riscv-rust/hifive1) 4 | 5 | # `hifive1` 6 | 7 | > Board support crate for HiFive1 and LoFive boards 8 | 9 | ## Supported Boards 10 | 11 | * [SiFive Hifive1](https://www.sifive.com/boards/hifive1) - use feature `board-hifive1` 12 | * [SiFive Hifive1 RevB](https://www.sifive.com/boards/hifive1-rev-b) - use feature `board-hifive1-revb` 13 | * [SparkFun Red-V RedBoard](https://www.sparkfun.com/products/15594) - use feature `board-redv` 14 | * [lofive1](https://github.com/mwelling/lofive) - use feature `board-lofive` 15 | * [lofive1-r1](https://github.com/mwelling/lofive) - use feature `board-lofive-r1` 16 | 17 | ## [Documentation](https://docs.rs/crate/hifive1) 18 | 19 | ## Minimum Supported Rust Version (MSRV) 20 | 21 | This crate is guaranteed to compile on stable Rust 1.79.0 and up. It *might* 22 | compile with older versions but that may change in any new patch release. 23 | 24 | ## License 25 | 26 | Copyright 2018-2023 [RISC-V team][team] 27 | 28 | Permission to use, copy, modify, and/or distribute this software for any purpose 29 | with or without fee is hereby granted, provided that the above copyright notice 30 | and this permission notice appear in all copies. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 33 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 34 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 35 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 36 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 37 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 38 | THIS SOFTWARE. 39 | 40 | ## Code of Conduct 41 | 42 | Contribution to this crate is organized under the terms of the [Rust Code of 43 | Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises 44 | to intervene to uphold that code of conduct. 45 | 46 | [CoC]: CODE_OF_CONDUCT.md 47 | [team]: https://github.com/rust-embedded/wg#the-risc-v-team 48 | -------------------------------------------------------------------------------- /e310x/src/i2c0/sr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `sr` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Field `if` reader - Interrupt Flag. This bit is set when an interrupt is pending, which will cause a processor interrupt request if the IEN bit is set."] 4 | pub type IfR = crate::BitReader; 5 | #[doc = "Field `tip` reader - Transfer in progress"] 6 | pub type TipR = crate::BitReader; 7 | #[doc = "Field `al` reader - Arbitration lost"] 8 | pub type AlR = crate::BitReader; 9 | #[doc = "Field `busy` reader - I2C bus busy"] 10 | pub type BusyR = crate::BitReader; 11 | #[doc = "Field `rx_ack` reader - Received acknowledge from slave. This flag represents acknowledge from the addressed slave. '1' = No acknowledge received '0' = Acknowledge received"] 12 | pub type RxAckR = crate::BitReader; 13 | impl R { 14 | #[doc = "Bit 0 - Interrupt Flag. This bit is set when an interrupt is pending, which will cause a processor interrupt request if the IEN bit is set."] 15 | #[inline(always)] 16 | pub fn if_(&self) -> IfR { 17 | IfR::new((self.bits & 1) != 0) 18 | } 19 | #[doc = "Bit 1 - Transfer in progress"] 20 | #[inline(always)] 21 | pub fn tip(&self) -> TipR { 22 | TipR::new(((self.bits >> 1) & 1) != 0) 23 | } 24 | #[doc = "Bit 5 - Arbitration lost"] 25 | #[inline(always)] 26 | pub fn al(&self) -> AlR { 27 | AlR::new(((self.bits >> 5) & 1) != 0) 28 | } 29 | #[doc = "Bit 6 - I2C bus busy"] 30 | #[inline(always)] 31 | pub fn busy(&self) -> BusyR { 32 | BusyR::new(((self.bits >> 6) & 1) != 0) 33 | } 34 | #[doc = "Bit 7 - Received acknowledge from slave. This flag represents acknowledge from the addressed slave. '1' = No acknowledge received '0' = Acknowledge received"] 35 | #[inline(always)] 36 | pub fn rx_ack(&self) -> RxAckR { 37 | RxAckR::new(((self.bits >> 7) & 1) != 0) 38 | } 39 | } 40 | #[doc = "Status register\n\nYou can [`read`](crate::Reg::read) this register and get [`sr::R`](R). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 41 | pub struct SrSpec; 42 | impl crate::RegisterSpec for SrSpec { 43 | type Ux = u32; 44 | } 45 | #[doc = "`read()` method returns [`sr::R`](R) reader structure"] 46 | impl crate::Readable for SrSpec {} 47 | #[doc = "`reset()` method sets sr to value 0"] 48 | impl crate::Resettable for SrSpec {} 49 | -------------------------------------------------------------------------------- /e310x/src/qspi0/delay1.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `delay1` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `delay1` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `intercs` reader - Minimum CS inactive time"] 6 | pub type IntercsR = crate::FieldReader; 7 | #[doc = "Field `intercs` writer - Minimum CS inactive time"] 8 | pub type IntercsW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 9 | #[doc = "Field `interxfr` reader - Maximum interframe delay"] 10 | pub type InterxfrR = crate::FieldReader; 11 | #[doc = "Field `interxfr` writer - Maximum interframe delay"] 12 | pub type InterxfrW<'a, REG> = crate::FieldWriter<'a, REG, 8>; 13 | impl R { 14 | #[doc = "Bits 0:7 - Minimum CS inactive time"] 15 | #[inline(always)] 16 | pub fn intercs(&self) -> IntercsR { 17 | IntercsR::new((self.bits & 0xff) as u8) 18 | } 19 | #[doc = "Bits 16:23 - Maximum interframe delay"] 20 | #[inline(always)] 21 | pub fn interxfr(&self) -> InterxfrR { 22 | InterxfrR::new(((self.bits >> 16) & 0xff) as u8) 23 | } 24 | } 25 | impl W { 26 | #[doc = "Bits 0:7 - Minimum CS inactive time"] 27 | #[inline(always)] 28 | pub fn intercs(&mut self) -> IntercsW<'_, Delay1Spec> { 29 | IntercsW::new(self, 0) 30 | } 31 | #[doc = "Bits 16:23 - Maximum interframe delay"] 32 | #[inline(always)] 33 | pub fn interxfr(&mut self) -> InterxfrW<'_, Delay1Spec> { 34 | InterxfrW::new(self, 16) 35 | } 36 | } 37 | #[doc = "Delay Control 1 Register\n\nYou can [`read`](crate::Reg::read) this register and get [`delay1::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`delay1::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 38 | pub struct Delay1Spec; 39 | impl crate::RegisterSpec for Delay1Spec { 40 | type Ux = u32; 41 | } 42 | #[doc = "`read()` method returns [`delay1::R`](R) reader structure"] 43 | impl crate::Readable for Delay1Spec {} 44 | #[doc = "`write(|w| ..)` method takes [`delay1::W`](W) writer structure"] 45 | impl crate::Writable for Delay1Spec { 46 | type Safety = crate::Unsafe; 47 | } 48 | #[doc = "`reset()` method sets delay1 to value 0x01"] 49 | impl crate::Resettable for Delay1Spec { 50 | const RESET_VALUE: u32 = 0x01; 51 | } 52 | -------------------------------------------------------------------------------- /e310x-hal/src/rtc.rs: -------------------------------------------------------------------------------- 1 | //! RTC 2 | #![allow(missing_docs)] 3 | 4 | use e310x::Rtc as RTC; 5 | 6 | pub trait RtcExt { 7 | fn constrain(self) -> Rtc; 8 | } 9 | 10 | impl RtcExt for RTC { 11 | fn constrain(self) -> Rtc { 12 | Rtc { _0: () } 13 | } 14 | } 15 | 16 | pub struct Rtc { 17 | _0: (), 18 | } 19 | 20 | impl Rtc { 21 | #[inline] 22 | pub fn is_pending(&self) -> bool { 23 | unsafe { RTC::steal() }.rtccfg().read().cmpip().bit() 24 | } 25 | 26 | #[inline] 27 | pub fn set_scale(&mut self, scale: u8) { 28 | unsafe { RTC::steal().rtccfg().modify(|_, w| w.scale().bits(scale)) }; 29 | } 30 | 31 | #[inline] 32 | pub fn enable(&mut self) { 33 | unsafe { RTC::steal() } 34 | .rtccfg() 35 | .modify(|_, w| w.enalways().bit(true)); 36 | } 37 | 38 | #[inline] 39 | pub fn disable(&mut self) { 40 | unsafe { RTC::steal() } 41 | .rtccfg() 42 | .modify(|_, w| w.enalways().bit(false)); 43 | } 44 | 45 | #[inline] 46 | pub fn is_enabled(&self) -> bool { 47 | unsafe { RTC::steal() }.rtccfg().read().enalways().bit() 48 | } 49 | 50 | #[inline] 51 | pub fn rtc_lo(&self) -> u32 { 52 | unsafe { RTC::steal() }.rtclo().read().bits() 53 | } 54 | 55 | #[inline] 56 | pub fn rtc_hi(&self) -> u32 { 57 | unsafe { RTC::steal() }.rtchi().read().bits() 58 | } 59 | 60 | pub fn rtc(&self) -> u64 { 61 | loop { 62 | let hi = self.rtc_hi(); 63 | let lo = self.rtc_lo(); 64 | if hi == self.rtc_hi() { 65 | return ((hi as u64) << 32) | lo as u64; 66 | } 67 | } 68 | } 69 | 70 | #[inline] 71 | pub fn set_rtc_lo(&mut self, value: u32) { 72 | unsafe { RTC::steal().rtclo().write(|w| w.bits(value)) }; 73 | } 74 | 75 | #[inline] 76 | pub fn set_rtc_hi(&mut self, value: u16) { 77 | unsafe { RTC::steal().rtchi().write(|w| w.value().bits(value)) }; 78 | } 79 | 80 | pub fn set_rtc(&mut self, value: u64) { 81 | self.set_rtc_hi((value >> 32) as u16); 82 | self.set_rtc_lo(value as u32); 83 | } 84 | 85 | #[inline] 86 | pub fn rtccmp(&self) -> u32 { 87 | unsafe { RTC::steal() }.rtccmp().read().bits() 88 | } 89 | 90 | #[inline] 91 | pub fn set_rtccmp(&mut self, value: u32) { 92 | unsafe { RTC::steal().rtccmp().write(|w| w.bits(value)) }; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /e310x-hal/src/spi/exclusive_device.rs: -------------------------------------------------------------------------------- 1 | use embedded_hal::{ 2 | delay::DelayNs, 3 | spi::{self, ErrorType, Operation, SpiBus, SpiDevice}, 4 | }; 5 | 6 | use crate::spi::SpiConfig; 7 | 8 | use super::{Pins, PinsFull, SpiBus as Bus, SpiX}; 9 | 10 | /// SPI exclusive device abstraction with delay support. 11 | pub struct SpiExclusiveDevice { 12 | bus: Bus, 13 | delay: D, 14 | } 15 | 16 | impl SpiExclusiveDevice 17 | where 18 | SPI: SpiX, 19 | PINS: Pins, 20 | D: DelayNs, 21 | { 22 | /// Create [`SpiDelayedExclusiveDevice`] using existing [`SpiBus`](Bus) with the given [`SpiConfig`] 23 | pub fn new(mut bus: Bus, config: &SpiConfig, delay: D) -> Self { 24 | // Safety: valid CS index 25 | unsafe { bus.configure(config, PINS::CS_INDEX) }; 26 | 27 | Self { bus, delay } 28 | } 29 | 30 | /// Releases the Bus and Delay back deconstructing it 31 | pub fn release(self) -> (SPI, PINS, D) { 32 | let (spi, pins) = self.bus.release(); 33 | (spi, pins, self.delay) 34 | } 35 | } 36 | 37 | impl ErrorType for SpiExclusiveDevice 38 | where 39 | SPI: SpiX, 40 | PINS: Pins, 41 | D: DelayNs, 42 | { 43 | type Error = spi::ErrorKind; 44 | } 45 | 46 | impl SpiDevice for SpiExclusiveDevice 47 | where 48 | SPI: SpiX, 49 | PINS: PinsFull, 50 | D: DelayNs, 51 | { 52 | fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { 53 | self.bus.start_frame(); 54 | 55 | let mut res = Ok(()); 56 | for operation in operations.iter_mut() { 57 | res = match operation { 58 | Operation::Read(read) => self.bus.read(read), 59 | Operation::Write(write) => self.bus.write(write), 60 | Operation::Transfer(read, write) => self.bus.transfer(read, write), 61 | Operation::TransferInPlace(read_write) => self.bus.transfer_in_place(read_write), 62 | Operation::DelayNs(ns) => { 63 | self.delay.delay_ns(*ns); 64 | Ok(()) 65 | } 66 | }; 67 | if res.is_err() { 68 | break; 69 | } 70 | } 71 | 72 | if res.is_ok() { 73 | self.bus.flush()?; 74 | } 75 | self.bus.end_frame(); 76 | res 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /e310x/device.x: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | RAM : ORIGIN = 0x80000000, LENGTH = 16K 4 | } 5 | 6 | /* Core interrupt sources and trap handlers */ 7 | PROVIDE(MachineSoft = DefaultHandler); 8 | PROVIDE(_start_MachineSoft_trap = _start_DefaultHandler_trap); 9 | PROVIDE(MachineTimer = DefaultHandler); 10 | PROVIDE(_start_MachineTimer_trap = _start_DefaultHandler_trap); 11 | PROVIDE(MachineExternal = DefaultHandler); 12 | PROVIDE(_start_MachineExternal_trap = _start_DefaultHandler_trap); 13 | /* External interrupt sources */ 14 | PROVIDE(WATCHDOG = DefaultHandler); 15 | PROVIDE(RTC = DefaultHandler); 16 | PROVIDE(UART0 = DefaultHandler); 17 | PROVIDE(UART1 = DefaultHandler); 18 | PROVIDE(QSPI0 = DefaultHandler); 19 | PROVIDE(QSPI1 = DefaultHandler); 20 | PROVIDE(QSPI2 = DefaultHandler); 21 | PROVIDE(GPIO0 = DefaultHandler); 22 | PROVIDE(GPIO1 = DefaultHandler); 23 | PROVIDE(GPIO2 = DefaultHandler); 24 | PROVIDE(GPIO3 = DefaultHandler); 25 | PROVIDE(GPIO4 = DefaultHandler); 26 | PROVIDE(GPIO5 = DefaultHandler); 27 | PROVIDE(GPIO6 = DefaultHandler); 28 | PROVIDE(GPIO7 = DefaultHandler); 29 | PROVIDE(GPIO8 = DefaultHandler); 30 | PROVIDE(GPIO9 = DefaultHandler); 31 | PROVIDE(GPIO10 = DefaultHandler); 32 | PROVIDE(GPIO11 = DefaultHandler); 33 | PROVIDE(GPIO12 = DefaultHandler); 34 | PROVIDE(GPIO13 = DefaultHandler); 35 | PROVIDE(GPIO14 = DefaultHandler); 36 | PROVIDE(GPIO15 = DefaultHandler); 37 | PROVIDE(GPIO16 = DefaultHandler); 38 | PROVIDE(GPIO17 = DefaultHandler); 39 | PROVIDE(GPIO18 = DefaultHandler); 40 | PROVIDE(GPIO19 = DefaultHandler); 41 | PROVIDE(GPIO20 = DefaultHandler); 42 | PROVIDE(GPIO21 = DefaultHandler); 43 | PROVIDE(GPIO22 = DefaultHandler); 44 | PROVIDE(GPIO23 = DefaultHandler); 45 | PROVIDE(GPIO24 = DefaultHandler); 46 | PROVIDE(GPIO25 = DefaultHandler); 47 | PROVIDE(GPIO26 = DefaultHandler); 48 | PROVIDE(GPIO27 = DefaultHandler); 49 | PROVIDE(GPIO28 = DefaultHandler); 50 | PROVIDE(GPIO29 = DefaultHandler); 51 | PROVIDE(GPIO30 = DefaultHandler); 52 | PROVIDE(GPIO31 = DefaultHandler); 53 | PROVIDE(PWM0CMP0 = DefaultHandler); 54 | PROVIDE(PWM0CMP1 = DefaultHandler); 55 | PROVIDE(PWM0CMP2 = DefaultHandler); 56 | PROVIDE(PWM0CMP3 = DefaultHandler); 57 | PROVIDE(PWM1CMP0 = DefaultHandler); 58 | PROVIDE(PWM1CMP1 = DefaultHandler); 59 | PROVIDE(PWM1CMP2 = DefaultHandler); 60 | PROVIDE(PWM1CMP3 = DefaultHandler); 61 | PROVIDE(PWM2CMP0 = DefaultHandler); 62 | PROVIDE(PWM2CMP1 = DefaultHandler); 63 | PROVIDE(PWM2CMP2 = DefaultHandler); 64 | PROVIDE(PWM2CMP3 = DefaultHandler); 65 | PROVIDE(I2C0 = DefaultHandler); 66 | 67 | -------------------------------------------------------------------------------- /hifive1/src/stdout.rs: -------------------------------------------------------------------------------- 1 | //! Stdout based on the UART hooked up to FTDI or J-Link 2 | 3 | use core::{ 4 | fmt::{self, Result, Write}, 5 | ptr, 6 | }; 7 | use e310x_hal::{ 8 | clock::Clocks, 9 | e310x::Uart0, 10 | gpio::{ 11 | gpio0::{Pin16, Pin17}, 12 | NoInvert, IOF0, 13 | }, 14 | serial::{Rx, Serial, Tx}, 15 | stdout::Stdout, 16 | time::Bps, 17 | }; 18 | 19 | struct SerialWrapper(Tx>>); 20 | 21 | static mut STDOUT: Option = None; 22 | 23 | impl Write for SerialWrapper { 24 | fn write_str(&mut self, s: &str) -> Result { 25 | let mut stdout = Stdout(&mut self.0); 26 | stdout.write_str(s) 27 | } 28 | } 29 | 30 | /// Configures stdout 31 | pub fn configure( 32 | uart: Uart0, 33 | tx: Pin17, 34 | rx: Pin16, 35 | baud_rate: Bps, 36 | clocks: Clocks, 37 | ) -> Rx>> { 38 | let tx = tx.into_iof0(); 39 | let rx = rx.into_iof0(); 40 | let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); 41 | let (tx, rx) = serial.split(); 42 | 43 | critical_section::with(|_| { 44 | unsafe { &mut *ptr::addr_of_mut!(STDOUT) }.replace(SerialWrapper(tx)); 45 | }); 46 | rx 47 | } 48 | 49 | /// Writes string to stdout 50 | pub fn write_str(s: &str) { 51 | critical_section::with(|_| { 52 | if let Some(stdout) = unsafe { &mut *ptr::addr_of_mut!(STDOUT) } { 53 | let _ = stdout.write_str(s); 54 | } 55 | }); 56 | } 57 | 58 | /// Writes formatted string to stdout 59 | pub fn write_fmt(args: fmt::Arguments) { 60 | critical_section::with(|_| { 61 | if let Some(stdout) = unsafe { &mut *ptr::addr_of_mut!(STDOUT) } { 62 | let _ = stdout.write_fmt(args); 63 | } 64 | }); 65 | } 66 | 67 | /// Macro for printing to the serial standard output 68 | #[macro_export] 69 | macro_rules! sprint { 70 | ($s:expr) => { 71 | $crate::stdout::write_str($s) 72 | }; 73 | ($($tt:tt)*) => { 74 | $crate::stdout::write_fmt(format_args!($($tt)*)) 75 | }; 76 | } 77 | 78 | /// Macro for printing to the serial standard output, with a newline. 79 | #[macro_export] 80 | macro_rules! sprintln { 81 | () => { 82 | $crate::stdout::write_str("\n") 83 | }; 84 | ($s:expr) => { 85 | $crate::stdout::write_str(concat!($s, "\n")) 86 | }; 87 | ($s:expr, $($tt:tt)*) => { 88 | $crate::stdout::write_fmt(format_args!(concat!($s, "\n"), $($tt)*)) 89 | }; 90 | } 91 | -------------------------------------------------------------------------------- /e310x-hal/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! HAL for the E310x family of microcontrollers 2 | //! 3 | //! This is an implementation of the [`embedded-hal`] traits for the E310x 4 | //! family of microcontrollers. 5 | //! 6 | //! # Building an application for the E310x chips 7 | //! 8 | //! The E310x chips implement the [Zaamo](https://github.com/riscv/riscv-zaamo-zalrsc/blob/main/zaamo-zalrsc.adoc) 9 | //! extension for atomic instructions. This means that it *partially* supports the `A` 10 | //! extension for atomic. Specifically, it supports the `amo*` instructions, but not the 11 | //! `lr*` and `sc*` instructions. 12 | //! 13 | //! It is discouraged to use the `riscv32imac-unknown-none-elf` target for E310x chips, as it 14 | //! will potentially generate code that uses the `lr*` and `sc*` instructions, which are not 15 | //! supported by the E310x chips. Thus, it is recommended to use `riscv32imc-unknown-none-elf`. 16 | //! 17 | //! # Working with atomic operations 18 | //! 19 | //! If you are using the `riscv32imc-unknown-none-elf` target, you will notice that 20 | //! `core::sync::atomic` is not available. To work around this, you can use the 21 | //! [`portable-atomic`](https://docs.rs/portable-atomic/1.8.0/portable_atomic/) crate. 22 | //! This crate allows us to use native `amo*` instructions on the E310x chips without requiring 23 | //! the `A` extension. Furthermore, you can emulate the `lr*` and `sc*` instructions if needed. 24 | //! 25 | //! Thus, the recommended way to work with E310x chips is: 26 | //! 27 | //! 1. Compile your code against the `riscv32imc-unknown-none-elf` target. 28 | //! 2. Add the following configuration to your `.cargo/config.toml`: 29 | //! 30 | //! ```toml 31 | //! [target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] 32 | //! rustflags = [ 33 | //! "--cfg", "portable_atomic_target_feature=\"zaamo\"", 34 | //! ] 35 | //! 36 | //! [build] 37 | //! target = "riscv32imc-unknown-none-elf" 38 | //! ``` 39 | //! 40 | //! This will ensure that the `portable-atomic` crate is correctly configured to work with the E310x chips. 41 | 42 | #![deny(missing_docs)] 43 | #![no_std] 44 | 45 | pub use e310x; 46 | 47 | pub mod clock; 48 | pub mod core; 49 | pub mod delay; 50 | pub mod device; 51 | pub mod gpio; 52 | pub mod pmu; 53 | pub mod prelude; 54 | pub mod pwm; 55 | pub mod rtc; 56 | pub mod serial; 57 | pub mod spi; 58 | pub mod stdout; 59 | pub mod time; 60 | pub mod wdog; 61 | 62 | #[cfg(feature = "g002")] 63 | pub mod i2c; 64 | 65 | #[cfg(feature = "async")] 66 | pub mod asynch; 67 | 68 | pub use device::DeviceResources; 69 | -------------------------------------------------------------------------------- /e310x/src/pmu/pmuie.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `pmuie` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `pmuie` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `rtc` reader - "] 6 | pub type RtcR = crate::BitReader; 7 | #[doc = "Field `rtc` writer - "] 8 | pub type RtcW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `dwakeup` reader - "] 10 | pub type DwakeupR = crate::BitReader; 11 | #[doc = "Field `dwakeup` writer - "] 12 | pub type DwakeupW<'a, REG> = crate::BitWriter<'a, REG>; 13 | #[doc = "Field `awakeup` reader - "] 14 | pub type AwakeupR = crate::BitReader; 15 | #[doc = "Field `awakeup` writer - "] 16 | pub type AwakeupW<'a, REG> = crate::BitWriter<'a, REG>; 17 | impl R { 18 | #[doc = "Bit 1"] 19 | #[inline(always)] 20 | pub fn rtc(&self) -> RtcR { 21 | RtcR::new(((self.bits >> 1) & 1) != 0) 22 | } 23 | #[doc = "Bit 2"] 24 | #[inline(always)] 25 | pub fn dwakeup(&self) -> DwakeupR { 26 | DwakeupR::new(((self.bits >> 2) & 1) != 0) 27 | } 28 | #[doc = "Bit 3"] 29 | #[inline(always)] 30 | pub fn awakeup(&self) -> AwakeupR { 31 | AwakeupR::new(((self.bits >> 3) & 1) != 0) 32 | } 33 | } 34 | impl W { 35 | #[doc = "Bit 1"] 36 | #[inline(always)] 37 | pub fn rtc(&mut self) -> RtcW<'_, PmuieSpec> { 38 | RtcW::new(self, 1) 39 | } 40 | #[doc = "Bit 2"] 41 | #[inline(always)] 42 | pub fn dwakeup(&mut self) -> DwakeupW<'_, PmuieSpec> { 43 | DwakeupW::new(self, 2) 44 | } 45 | #[doc = "Bit 3"] 46 | #[inline(always)] 47 | pub fn awakeup(&mut self) -> AwakeupW<'_, PmuieSpec> { 48 | AwakeupW::new(self, 3) 49 | } 50 | } 51 | #[doc = "PMU Interrupt Enable Register\n\nYou can [`read`](crate::Reg::read) this register and get [`pmuie::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`pmuie::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 52 | pub struct PmuieSpec; 53 | impl crate::RegisterSpec for PmuieSpec { 54 | type Ux = u32; 55 | } 56 | #[doc = "`read()` method returns [`pmuie::R`](R) reader structure"] 57 | impl crate::Readable for PmuieSpec {} 58 | #[doc = "`write(|w| ..)` method takes [`pmuie::W`](W) writer structure"] 59 | impl crate::Writable for PmuieSpec { 60 | type Safety = crate::Unsafe; 61 | } 62 | #[doc = "`reset()` method sets pmuie to value 0"] 63 | impl crate::Resettable for PmuieSpec {} 64 | -------------------------------------------------------------------------------- /e310x/src/uart0/txctrl.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `txctrl` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `txctrl` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `enable` reader - "] 6 | pub type EnableR = crate::BitReader; 7 | #[doc = "Field `enable` writer - "] 8 | pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; 9 | #[doc = "Field `nstop` reader - "] 10 | pub type NstopR = crate::BitReader; 11 | #[doc = "Field `nstop` writer - "] 12 | pub type NstopW<'a, REG> = crate::BitWriter<'a, REG>; 13 | #[doc = "Field `counter` reader - "] 14 | pub type CounterR = crate::FieldReader; 15 | #[doc = "Field `counter` writer - "] 16 | pub type CounterW<'a, REG> = crate::FieldWriter<'a, REG, 3>; 17 | impl R { 18 | #[doc = "Bit 0"] 19 | #[inline(always)] 20 | pub fn enable(&self) -> EnableR { 21 | EnableR::new((self.bits & 1) != 0) 22 | } 23 | #[doc = "Bit 1"] 24 | #[inline(always)] 25 | pub fn nstop(&self) -> NstopR { 26 | NstopR::new(((self.bits >> 1) & 1) != 0) 27 | } 28 | #[doc = "Bits 16:18"] 29 | #[inline(always)] 30 | pub fn counter(&self) -> CounterR { 31 | CounterR::new(((self.bits >> 16) & 7) as u8) 32 | } 33 | } 34 | impl W { 35 | #[doc = "Bit 0"] 36 | #[inline(always)] 37 | pub fn enable(&mut self) -> EnableW<'_, TxctrlSpec> { 38 | EnableW::new(self, 0) 39 | } 40 | #[doc = "Bit 1"] 41 | #[inline(always)] 42 | pub fn nstop(&mut self) -> NstopW<'_, TxctrlSpec> { 43 | NstopW::new(self, 1) 44 | } 45 | #[doc = "Bits 16:18"] 46 | #[inline(always)] 47 | pub fn counter(&mut self) -> CounterW<'_, TxctrlSpec> { 48 | CounterW::new(self, 16) 49 | } 50 | } 51 | #[doc = "Transmit Control Register\n\nYou can [`read`](crate::Reg::read) this register and get [`txctrl::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`txctrl::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 52 | pub struct TxctrlSpec; 53 | impl crate::RegisterSpec for TxctrlSpec { 54 | type Ux = u32; 55 | } 56 | #[doc = "`read()` method returns [`txctrl::R`](R) reader structure"] 57 | impl crate::Readable for TxctrlSpec {} 58 | #[doc = "`write(|w| ..)` method takes [`txctrl::W`](W) writer structure"] 59 | impl crate::Writable for TxctrlSpec { 60 | type Safety = crate::Unsafe; 61 | } 62 | #[doc = "`reset()` method sets txctrl to value 0"] 63 | impl crate::Resettable for TxctrlSpec {} 64 | -------------------------------------------------------------------------------- /e310x/src/rtc/rtccfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `rtccfg` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `rtccfg` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `scale` reader - "] 6 | pub type ScaleR = crate::FieldReader; 7 | #[doc = "Field `scale` writer - "] 8 | pub type ScaleW<'a, REG> = crate::FieldWriter<'a, REG, 4>; 9 | #[doc = "Field `enalways` reader - "] 10 | pub type EnalwaysR = crate::BitReader; 11 | #[doc = "Field `enalways` writer - "] 12 | pub type EnalwaysW<'a, REG> = crate::BitWriter<'a, REG>; 13 | #[doc = "Field `cmpip` reader - "] 14 | pub type CmpipR = crate::BitReader; 15 | #[doc = "Field `cmpip` writer - "] 16 | pub type CmpipW<'a, REG> = crate::BitWriter<'a, REG>; 17 | impl R { 18 | #[doc = "Bits 0:3"] 19 | #[inline(always)] 20 | pub fn scale(&self) -> ScaleR { 21 | ScaleR::new((self.bits & 0x0f) as u8) 22 | } 23 | #[doc = "Bit 12"] 24 | #[inline(always)] 25 | pub fn enalways(&self) -> EnalwaysR { 26 | EnalwaysR::new(((self.bits >> 12) & 1) != 0) 27 | } 28 | #[doc = "Bit 28"] 29 | #[inline(always)] 30 | pub fn cmpip(&self) -> CmpipR { 31 | CmpipR::new(((self.bits >> 28) & 1) != 0) 32 | } 33 | } 34 | impl W { 35 | #[doc = "Bits 0:3"] 36 | #[inline(always)] 37 | pub fn scale(&mut self) -> ScaleW<'_, RtccfgSpec> { 38 | ScaleW::new(self, 0) 39 | } 40 | #[doc = "Bit 12"] 41 | #[inline(always)] 42 | pub fn enalways(&mut self) -> EnalwaysW<'_, RtccfgSpec> { 43 | EnalwaysW::new(self, 12) 44 | } 45 | #[doc = "Bit 28"] 46 | #[inline(always)] 47 | pub fn cmpip(&mut self) -> CmpipW<'_, RtccfgSpec> { 48 | CmpipW::new(self, 28) 49 | } 50 | } 51 | #[doc = "RTC Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`rtccfg::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`rtccfg::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 52 | pub struct RtccfgSpec; 53 | impl crate::RegisterSpec for RtccfgSpec { 54 | type Ux = u32; 55 | } 56 | #[doc = "`read()` method returns [`rtccfg::R`](R) reader structure"] 57 | impl crate::Readable for RtccfgSpec {} 58 | #[doc = "`write(|w| ..)` method takes [`rtccfg::W`](W) writer structure"] 59 | impl crate::Writable for RtccfgSpec { 60 | type Safety = crate::Unsafe; 61 | } 62 | #[doc = "`reset()` method sets rtccfg to value 0"] 63 | impl crate::Resettable for RtccfgSpec {} 64 | -------------------------------------------------------------------------------- /hifive1-async-examples/examples/button_led.rs: -------------------------------------------------------------------------------- 1 | //! Basic example where the LED changes its state according to a button connected to pin 9. 2 | //! The LED must be connected to pin 10 of the board 3 | //! This example uses synchronous UART and only tests asynchronous GPIO. 4 | 5 | #![no_std] 6 | #![no_main] 7 | 8 | use embassy_executor::Spawner; 9 | use hifive1::{ 10 | clock, 11 | hal::{asynch::prelude::*, gpio::EventType, prelude::*, DeviceResources}, 12 | sprintln, 13 | }; 14 | extern crate panic_halt; 15 | 16 | #[embassy_executor::main] 17 | async fn main(_spawner: Spawner) -> ! { 18 | let dr = DeviceResources::take().unwrap(); 19 | let cp = dr.core_peripherals; 20 | let p = dr.peripherals; 21 | let mut pins = dr.pins; 22 | 23 | // Configure clocks 24 | let clocks = clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); 25 | 26 | // Disable and clear pending GPIO interrupts from previous states 27 | pins.disable_interrupts(EventType::All); 28 | pins.clear_interrupts(EventType::All); 29 | 30 | // Configure UART for stdout 31 | hifive1::stdout::configure(p.UART0, pins.pin17, pins.pin16, 115_200.bps(), clocks); 32 | 33 | sprintln!("Configuring GPIOs..."); 34 | 35 | // Button pin (GPIO9) as pull-up input 36 | let mut button = pins.pin9.into_pull_up_input(); 37 | // Configure blue LED pin (GPIO10) as output 38 | let mut led = pins.pin10.into_output(); 39 | 40 | sprintln!("Configuring external interrupts..."); 41 | 42 | // Make sure interrupts are disabled 43 | riscv::interrupt::disable(); 44 | 45 | // Reset PLIC interrupts and set priority threshold 46 | let plic = cp.plic; 47 | let priorities = plic.priorities(); 48 | let ctx = plic.ctx0(); 49 | priorities.reset::(); 50 | unsafe { 51 | ctx.enables().disable_all::(); 52 | ctx.threshold().set_threshold(Priority::P0); 53 | } 54 | 55 | // Enable GPIO9 interrupt for both edges 56 | button.enable_interrupt(EventType::BothEdges); 57 | unsafe { 58 | button.set_exti_priority(&plic, Priority::P1); 59 | button.enable_exti(&plic); 60 | } 61 | 62 | sprintln!("Enabling external interrupts..."); 63 | 64 | // Enable global interrupts 65 | unsafe { 66 | riscv::interrupt::enable(); 67 | plic.enable(); 68 | } 69 | 70 | // Execute loop 71 | loop { 72 | led.toggle().unwrap(); 73 | let led_state = led.is_set_high().unwrap(); 74 | sprintln!("LED toggled. New state: {}", led_state); 75 | button.wait_for_any_edge().await.unwrap(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /hifive1/src/led.rs: -------------------------------------------------------------------------------- 1 | //! On-board user LEDs 2 | //! 3 | //! Hifive1 (+ revB) 4 | //! - Red = Pin 22 5 | //! - Green = Pin 19 6 | //! - Blue = Pin 21 7 | //! 8 | //! RedV 9 | //! - Blue = Pin 5 10 | 11 | use core::convert::Infallible; 12 | #[cfg(feature = "board-redv")] 13 | use e310x_hal::gpio::gpio0::Pin5; 14 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 15 | use e310x_hal::gpio::gpio0::{Pin19, Pin21, Pin22}; 16 | use e310x_hal::{ 17 | gpio::{Invert, Output, Regular}, 18 | prelude::*, 19 | }; 20 | 21 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 22 | /// Red LED 23 | pub type RED = Pin22>>; 24 | 25 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 26 | /// Green LED 27 | pub type GREEN = Pin19>>; 28 | 29 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 30 | /// Blue LED 31 | pub type BLUE = Pin21>>; 32 | 33 | #[cfg(feature = "board-redv")] 34 | /// Blue LED 35 | pub type BLUE = Pin5>>; 36 | 37 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 38 | /// Returns RED, GREEN and BLUE LEDs. 39 | pub fn rgb(red: Pin22, green: Pin19, blue: Pin21) -> (RED, GREEN, BLUE) { 40 | let red: RED = red.into_inverted_output(); 41 | let green: GREEN = green.into_inverted_output(); 42 | let blue: BLUE = blue.into_inverted_output(); 43 | (red, green, blue) 44 | } 45 | 46 | /// Generic LED 47 | pub trait Led: StatefulOutputPin { 48 | /// Returns true if the LED is on 49 | fn is_on(&mut self) -> bool; 50 | 51 | /// Turns the LED off 52 | fn off(&mut self); 53 | 54 | /// Turns the LED on 55 | fn on(&mut self); 56 | 57 | /// Toggles the LED state 58 | fn toggle(&mut self) { 59 | StatefulOutputPin::toggle(self).unwrap(); 60 | } 61 | } 62 | 63 | /// Macro to implement the Led trait for each of the board LEDs 64 | macro_rules! led_impl { 65 | ($($LEDTYPE:ident),+) => { 66 | $( 67 | impl Led for $LEDTYPE { 68 | fn is_on(&mut self) -> bool { 69 | self.is_set_low().unwrap() 70 | } 71 | 72 | fn off(&mut self) { 73 | self.set_high().unwrap(); 74 | } 75 | 76 | fn on(&mut self) { 77 | self.set_low().unwrap(); 78 | } 79 | } 80 | )+ 81 | } 82 | } 83 | 84 | // Call the macro for each LED 85 | 86 | #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] 87 | led_impl!(RED, GREEN); 88 | 89 | led_impl!(BLUE); 90 | -------------------------------------------------------------------------------- /e310x-hal/src/wdog.rs: -------------------------------------------------------------------------------- 1 | //! Watchdog 2 | #![allow(missing_docs)] 3 | use e310x::Wdog as WDOG; 4 | 5 | pub trait WdogExt { 6 | fn configure(self) -> WdogCfg; 7 | } 8 | 9 | impl WdogExt for WDOG { 10 | fn configure(self) -> WdogCfg { 11 | WdogCfg { 12 | _0: (), 13 | enable: false, 14 | awake: false, 15 | reset: false, 16 | zero_cmp: false, 17 | scale: 0, 18 | } 19 | } 20 | } 21 | 22 | pub struct WdogCfg { 23 | _0: (), 24 | enable: bool, 25 | awake: bool, 26 | reset: bool, 27 | zero_cmp: bool, 28 | scale: u8, 29 | } 30 | 31 | impl WdogCfg { 32 | pub fn enable(mut self) -> Self { 33 | self.enable = true; 34 | self 35 | } 36 | 37 | pub fn enable_awake(mut self) -> Self { 38 | self.awake = true; 39 | self 40 | } 41 | 42 | pub fn enable_reset(mut self) -> Self { 43 | self.reset = true; 44 | self 45 | } 46 | 47 | pub fn enable_zero_cmp(mut self) -> Self { 48 | self.zero_cmp = true; 49 | self 50 | } 51 | 52 | pub fn scale(mut self, scale: u8) -> Self { 53 | self.scale = scale; 54 | self 55 | } 56 | 57 | pub fn freeze(self) -> Wdog { 58 | unsafe { 59 | let wdog = WDOG::steal(); 60 | wdog.wdogkey().write(|w| w.bits(0x51F15E)); 61 | wdog.wdogcfg().write(|w| { 62 | w.scale() 63 | .bits(self.scale) 64 | .rsten() 65 | .bit(self.reset) 66 | .zerocmp() 67 | .bit(self.zero_cmp) 68 | .enalways() 69 | .bit(self.enable) 70 | .encoreawake() 71 | .bit(self.awake) 72 | }); 73 | } 74 | Wdog { _0: () } 75 | } 76 | } 77 | 78 | pub struct Wdog { 79 | _0: (), 80 | } 81 | 82 | impl Wdog { 83 | #[inline] 84 | fn unlock(&mut self) { 85 | unsafe { WDOG::steal().wdogkey().write(|w| w.bits(0x51F15E)) }; 86 | } 87 | 88 | pub fn is_pending(&self) -> bool { 89 | unsafe { WDOG::steal() }.wdogcfg().read().cmpip().bit() 90 | } 91 | 92 | pub fn feed(&mut self) { 93 | self.unlock(); 94 | unsafe { WDOG::steal().wdogfeed().write(|w| w.bits(0xD09F00D)) }; 95 | } 96 | 97 | pub fn cmp(&self) -> u16 { 98 | unsafe { WDOG::steal() }.wdogcmp().read().value().bits() 99 | } 100 | 101 | pub fn set_cmp(&mut self, value: u16) { 102 | unsafe { WDOG::steal().wdogcmp().write(|w| w.value().bits(value)) }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /e310x-hal/src/spi/shared_device.rs: -------------------------------------------------------------------------------- 1 | use embedded_hal::{ 2 | delay::DelayNs, 3 | spi::{ErrorKind, ErrorType, Operation, SpiBus, SpiDevice}, 4 | }; 5 | use riscv::interrupt; 6 | 7 | use super::{PinCS, PinsFull, PinsNoCS, SharedBus, SpiConfig, SpiX}; 8 | 9 | /// SPI shared device abstraction 10 | pub struct SpiSharedDevice<'bus, SPI, PINS, CS, D> { 11 | bus: &'bus SharedBus, 12 | cs: CS, 13 | config: SpiConfig, 14 | delay: D, 15 | } 16 | 17 | impl SpiSharedDevice<'_, SPI, PINS, CS, D> { 18 | /// Releases the CS pin and delay back 19 | pub fn release(self) -> (CS, D) { 20 | (self.cs, self.delay) 21 | } 22 | } 23 | 24 | impl<'bus, SPI, PINS, CS, D> SpiSharedDevice<'bus, SPI, PINS, CS, D> 25 | where 26 | SPI: SpiX, 27 | PINS: PinsNoCS, 28 | CS: PinCS, 29 | D: DelayNs, 30 | { 31 | /// Create shared [SpiSharedDevice] using the existing [SharedBus] 32 | /// and given [SpiConfig]. The config gets cloned. 33 | pub fn new(bus: &'bus SharedBus, cs: CS, config: &SpiConfig, delay: D) -> Self { 34 | Self { 35 | bus, 36 | cs, 37 | config: config.clone(), 38 | delay, 39 | } 40 | } 41 | } 42 | 43 | impl ErrorType for SpiSharedDevice<'_, SPI, PINS, CS, D> 44 | where 45 | SPI: SpiX, 46 | PINS: PinsNoCS, 47 | CS: PinCS, 48 | D: DelayNs, 49 | { 50 | type Error = ErrorKind; 51 | } 52 | 53 | impl SpiDevice for SpiSharedDevice<'_, SPI, PINS, CS, D> 54 | where 55 | SPI: SpiX, 56 | PINS: PinsNoCS + PinsFull, 57 | CS: PinCS, 58 | D: DelayNs, 59 | { 60 | fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { 61 | let mut bus = 62 | interrupt::free(|| self.bus.try_borrow_mut().map_err(|_| ErrorKind::ModeFault))?; 63 | // Safety: valid CS index 64 | unsafe { bus.configure(&self.config, Some(CS::CS_INDEX)) }; 65 | bus.start_frame(); 66 | 67 | let mut res = Ok(()); 68 | for operation in operations.iter_mut() { 69 | res = match operation { 70 | Operation::Read(read) => bus.read(read), 71 | Operation::Write(write) => bus.write(write), 72 | Operation::Transfer(read, write) => bus.transfer(read, write), 73 | Operation::TransferInPlace(read_write) => bus.transfer_in_place(read_write), 74 | Operation::DelayNs(ns) => { 75 | self.delay.delay_ns(*ns); 76 | Ok(()) 77 | } 78 | }; 79 | if res.is_err() { 80 | break; 81 | } 82 | } 83 | 84 | if res.is_ok() { 85 | bus.flush()?; 86 | } 87 | bus.end_frame(); 88 | 89 | Ok(()) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /e310x/src/prci/hfrosccfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `hfrosccfg` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `hfrosccfg` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `div` reader - "] 6 | pub type DivR = crate::FieldReader; 7 | #[doc = "Field `div` writer - "] 8 | pub type DivW<'a, REG> = crate::FieldWriter<'a, REG, 6>; 9 | #[doc = "Field `trim` reader - "] 10 | pub type TrimR = crate::FieldReader; 11 | #[doc = "Field `trim` writer - "] 12 | pub type TrimW<'a, REG> = crate::FieldWriter<'a, REG, 5>; 13 | #[doc = "Field `enable` reader - "] 14 | pub type EnableR = crate::BitReader; 15 | #[doc = "Field `enable` writer - "] 16 | pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; 17 | #[doc = "Field `ready` reader - "] 18 | pub type ReadyR = crate::BitReader; 19 | #[doc = "Field `ready` writer - "] 20 | pub type ReadyW<'a, REG> = crate::BitWriter<'a, REG>; 21 | impl R { 22 | #[doc = "Bits 0:5"] 23 | #[inline(always)] 24 | pub fn div(&self) -> DivR { 25 | DivR::new((self.bits & 0x3f) as u8) 26 | } 27 | #[doc = "Bits 16:20"] 28 | #[inline(always)] 29 | pub fn trim(&self) -> TrimR { 30 | TrimR::new(((self.bits >> 16) & 0x1f) as u8) 31 | } 32 | #[doc = "Bit 30"] 33 | #[inline(always)] 34 | pub fn enable(&self) -> EnableR { 35 | EnableR::new(((self.bits >> 30) & 1) != 0) 36 | } 37 | #[doc = "Bit 31"] 38 | #[inline(always)] 39 | pub fn ready(&self) -> ReadyR { 40 | ReadyR::new(((self.bits >> 31) & 1) != 0) 41 | } 42 | } 43 | impl W { 44 | #[doc = "Bits 0:5"] 45 | #[inline(always)] 46 | pub fn div(&mut self) -> DivW<'_, HfrosccfgSpec> { 47 | DivW::new(self, 0) 48 | } 49 | #[doc = "Bits 16:20"] 50 | #[inline(always)] 51 | pub fn trim(&mut self) -> TrimW<'_, HfrosccfgSpec> { 52 | TrimW::new(self, 16) 53 | } 54 | #[doc = "Bit 30"] 55 | #[inline(always)] 56 | pub fn enable(&mut self) -> EnableW<'_, HfrosccfgSpec> { 57 | EnableW::new(self, 30) 58 | } 59 | #[doc = "Bit 31"] 60 | #[inline(always)] 61 | pub fn ready(&mut self) -> ReadyW<'_, HfrosccfgSpec> { 62 | ReadyW::new(self, 31) 63 | } 64 | } 65 | #[doc = "Clock Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`hfrosccfg::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`hfrosccfg::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 66 | pub struct HfrosccfgSpec; 67 | impl crate::RegisterSpec for HfrosccfgSpec { 68 | type Ux = u32; 69 | } 70 | #[doc = "`read()` method returns [`hfrosccfg::R`](R) reader structure"] 71 | impl crate::Readable for HfrosccfgSpec {} 72 | #[doc = "`write(|w| ..)` method takes [`hfrosccfg::W`](W) writer structure"] 73 | impl crate::Writable for HfrosccfgSpec { 74 | type Safety = crate::Unsafe; 75 | } 76 | #[doc = "`reset()` method sets hfrosccfg to value 0"] 77 | impl crate::Resettable for HfrosccfgSpec {} 78 | -------------------------------------------------------------------------------- /e310x/src/aonclk/lfrosccfg.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `lfrosccfg` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `lfrosccfg` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Field `div` reader - "] 6 | pub type DivR = crate::FieldReader; 7 | #[doc = "Field `div` writer - "] 8 | pub type DivW<'a, REG> = crate::FieldWriter<'a, REG, 6>; 9 | #[doc = "Field `trim` reader - "] 10 | pub type TrimR = crate::FieldReader; 11 | #[doc = "Field `trim` writer - "] 12 | pub type TrimW<'a, REG> = crate::FieldWriter<'a, REG, 5>; 13 | #[doc = "Field `enable` reader - "] 14 | pub type EnableR = crate::BitReader; 15 | #[doc = "Field `enable` writer - "] 16 | pub type EnableW<'a, REG> = crate::BitWriter<'a, REG>; 17 | #[doc = "Field `ready` reader - "] 18 | pub type ReadyR = crate::BitReader; 19 | #[doc = "Field `ready` writer - "] 20 | pub type ReadyW<'a, REG> = crate::BitWriter<'a, REG>; 21 | impl R { 22 | #[doc = "Bits 0:5"] 23 | #[inline(always)] 24 | pub fn div(&self) -> DivR { 25 | DivR::new((self.bits & 0x3f) as u8) 26 | } 27 | #[doc = "Bits 16:20"] 28 | #[inline(always)] 29 | pub fn trim(&self) -> TrimR { 30 | TrimR::new(((self.bits >> 16) & 0x1f) as u8) 31 | } 32 | #[doc = "Bit 30"] 33 | #[inline(always)] 34 | pub fn enable(&self) -> EnableR { 35 | EnableR::new(((self.bits >> 30) & 1) != 0) 36 | } 37 | #[doc = "Bit 31"] 38 | #[inline(always)] 39 | pub fn ready(&self) -> ReadyR { 40 | ReadyR::new(((self.bits >> 31) & 1) != 0) 41 | } 42 | } 43 | impl W { 44 | #[doc = "Bits 0:5"] 45 | #[inline(always)] 46 | pub fn div(&mut self) -> DivW<'_, LfrosccfgSpec> { 47 | DivW::new(self, 0) 48 | } 49 | #[doc = "Bits 16:20"] 50 | #[inline(always)] 51 | pub fn trim(&mut self) -> TrimW<'_, LfrosccfgSpec> { 52 | TrimW::new(self, 16) 53 | } 54 | #[doc = "Bit 30"] 55 | #[inline(always)] 56 | pub fn enable(&mut self) -> EnableW<'_, LfrosccfgSpec> { 57 | EnableW::new(self, 30) 58 | } 59 | #[doc = "Bit 31"] 60 | #[inline(always)] 61 | pub fn ready(&mut self) -> ReadyW<'_, LfrosccfgSpec> { 62 | ReadyW::new(self, 31) 63 | } 64 | } 65 | #[doc = "AON Clock Configuration Register\n\nYou can [`read`](crate::Reg::read) this register and get [`lfrosccfg::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`lfrosccfg::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 66 | pub struct LfrosccfgSpec; 67 | impl crate::RegisterSpec for LfrosccfgSpec { 68 | type Ux = u32; 69 | } 70 | #[doc = "`read()` method returns [`lfrosccfg::R`](R) reader structure"] 71 | impl crate::Readable for LfrosccfgSpec {} 72 | #[doc = "`write(|w| ..)` method takes [`lfrosccfg::W`](W) writer structure"] 73 | impl crate::Writable for LfrosccfgSpec { 74 | type Safety = crate::Unsafe; 75 | } 76 | #[doc = "`reset()` method sets lfrosccfg to value 0"] 77 | impl crate::Resettable for LfrosccfgSpec {} 78 | -------------------------------------------------------------------------------- /e310x/src/i2c0/cr.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `cr` writer"] 2 | pub type W = crate::W; 3 | #[doc = "Field `iack` writer - Interrupt acknowledge. When set, clears a pending interrupt"] 4 | pub type IackW<'a, REG> = crate::BitWriter<'a, REG>; 5 | #[doc = "When a receiver, sent ACK (0) or NACK (1)\n\nValue on reset: 0"] 6 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 7 | pub enum Ack { 8 | #[doc = "0: `0`"] 9 | Ack = 0, 10 | #[doc = "1: `1`"] 11 | Nack = 1, 12 | } 13 | impl From for bool { 14 | #[inline(always)] 15 | fn from(variant: Ack) -> Self { 16 | variant as u8 != 0 17 | } 18 | } 19 | #[doc = "Field `ack` writer - When a receiver, sent ACK (0) or NACK (1)"] 20 | pub type AckW<'a, REG> = crate::BitWriter<'a, REG, Ack>; 21 | impl<'a, REG> AckW<'a, REG> 22 | where 23 | REG: crate::Writable + crate::RegisterSpec, 24 | { 25 | #[doc = "`0`"] 26 | #[inline(always)] 27 | pub fn ack(self) -> &'a mut crate::W { 28 | self.variant(Ack::Ack) 29 | } 30 | #[doc = "`1`"] 31 | #[inline(always)] 32 | pub fn nack(self) -> &'a mut crate::W { 33 | self.variant(Ack::Nack) 34 | } 35 | } 36 | #[doc = "Field `wr` writer - Write to slave"] 37 | pub type WrW<'a, REG> = crate::BitWriter<'a, REG>; 38 | #[doc = "Field `rd` writer - Read from slave"] 39 | pub type RdW<'a, REG> = crate::BitWriter<'a, REG>; 40 | #[doc = "Field `sto` writer - Generate stop condition"] 41 | pub type StoW<'a, REG> = crate::BitWriter<'a, REG>; 42 | #[doc = "Field `sta` writer - Generate (repeated) start condition"] 43 | pub type StaW<'a, REG> = crate::BitWriter<'a, REG>; 44 | impl W { 45 | #[doc = "Bit 0 - Interrupt acknowledge. When set, clears a pending interrupt"] 46 | #[inline(always)] 47 | pub fn iack(&mut self) -> IackW<'_, CrSpec> { 48 | IackW::new(self, 0) 49 | } 50 | #[doc = "Bit 3 - When a receiver, sent ACK (0) or NACK (1)"] 51 | #[inline(always)] 52 | pub fn ack(&mut self) -> AckW<'_, CrSpec> { 53 | AckW::new(self, 3) 54 | } 55 | #[doc = "Bit 4 - Write to slave"] 56 | #[inline(always)] 57 | pub fn wr(&mut self) -> WrW<'_, CrSpec> { 58 | WrW::new(self, 4) 59 | } 60 | #[doc = "Bit 5 - Read from slave"] 61 | #[inline(always)] 62 | pub fn rd(&mut self) -> RdW<'_, CrSpec> { 63 | RdW::new(self, 5) 64 | } 65 | #[doc = "Bit 6 - Generate stop condition"] 66 | #[inline(always)] 67 | pub fn sto(&mut self) -> StoW<'_, CrSpec> { 68 | StoW::new(self, 6) 69 | } 70 | #[doc = "Bit 7 - Generate (repeated) start condition"] 71 | #[inline(always)] 72 | pub fn sta(&mut self) -> StaW<'_, CrSpec> { 73 | StaW::new(self, 7) 74 | } 75 | } 76 | #[doc = "Command register\n\nYou can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`cr::W`](W). See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 77 | pub struct CrSpec; 78 | impl crate::RegisterSpec for CrSpec { 79 | type Ux = u32; 80 | } 81 | #[doc = "`write(|w| ..)` method takes [`cr::W`](W) writer structure"] 82 | impl crate::Writable for CrSpec { 83 | type Safety = crate::Unsafe; 84 | } 85 | #[doc = "`reset()` method sets cr to value 0"] 86 | impl crate::Resettable for CrSpec {} 87 | -------------------------------------------------------------------------------- /e310x/src/qspi0/csmode.rs: -------------------------------------------------------------------------------- 1 | #[doc = "Register `csmode` reader"] 2 | pub type R = crate::R; 3 | #[doc = "Register `csmode` writer"] 4 | pub type W = crate::W; 5 | #[doc = "Chip select mode\n\nValue on reset: 0"] 6 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 7 | #[repr(u8)] 8 | pub enum Mode { 9 | #[doc = "0: Assert/de-assert CS at the beginning/end of each frame."] 10 | Auto = 0, 11 | #[doc = "2: Keep CS continuously asserted after the initial frame."] 12 | Hold = 2, 13 | #[doc = "3: Disable hardware control of the CS pin."] 14 | Off = 3, 15 | } 16 | impl From for u8 { 17 | #[inline(always)] 18 | fn from(variant: Mode) -> Self { 19 | variant as _ 20 | } 21 | } 22 | impl crate::FieldSpec for Mode { 23 | type Ux = u8; 24 | } 25 | impl crate::IsEnum for Mode {} 26 | #[doc = "Field `mode` reader - Chip select mode"] 27 | pub type ModeR = crate::FieldReader; 28 | impl ModeR { 29 | #[doc = "Get enumerated values variant"] 30 | #[inline(always)] 31 | pub const fn variant(&self) -> Option { 32 | match self.bits { 33 | 0 => Some(Mode::Auto), 34 | 2 => Some(Mode::Hold), 35 | 3 => Some(Mode::Off), 36 | _ => None, 37 | } 38 | } 39 | #[doc = "Assert/de-assert CS at the beginning/end of each frame."] 40 | #[inline(always)] 41 | pub fn is_auto(&self) -> bool { 42 | *self == Mode::Auto 43 | } 44 | #[doc = "Keep CS continuously asserted after the initial frame."] 45 | #[inline(always)] 46 | pub fn is_hold(&self) -> bool { 47 | *self == Mode::Hold 48 | } 49 | #[doc = "Disable hardware control of the CS pin."] 50 | #[inline(always)] 51 | pub fn is_off(&self) -> bool { 52 | *self == Mode::Off 53 | } 54 | } 55 | #[doc = "Field `mode` writer - Chip select mode"] 56 | pub type ModeW<'a, REG> = crate::FieldWriter<'a, REG, 2, Mode>; 57 | impl<'a, REG> ModeW<'a, REG> 58 | where 59 | REG: crate::Writable + crate::RegisterSpec, 60 | REG::Ux: From, 61 | { 62 | #[doc = "Assert/de-assert CS at the beginning/end of each frame."] 63 | #[inline(always)] 64 | pub fn auto(self) -> &'a mut crate::W { 65 | self.variant(Mode::Auto) 66 | } 67 | #[doc = "Keep CS continuously asserted after the initial frame."] 68 | #[inline(always)] 69 | pub fn hold(self) -> &'a mut crate::W { 70 | self.variant(Mode::Hold) 71 | } 72 | #[doc = "Disable hardware control of the CS pin."] 73 | #[inline(always)] 74 | pub fn off(self) -> &'a mut crate::W { 75 | self.variant(Mode::Off) 76 | } 77 | } 78 | impl R { 79 | #[doc = "Bits 0:1 - Chip select mode"] 80 | #[inline(always)] 81 | pub fn mode(&self) -> ModeR { 82 | ModeR::new((self.bits & 3) as u8) 83 | } 84 | } 85 | impl W { 86 | #[doc = "Bits 0:1 - Chip select mode"] 87 | #[inline(always)] 88 | pub fn mode(&mut self) -> ModeW<'_, CsmodeSpec> { 89 | ModeW::new(self, 0) 90 | } 91 | } 92 | #[doc = "Chip Select Mode Register\n\nYou can [`read`](crate::Reg::read) this register and get [`csmode::R`](R). You can [`reset`](crate::Reg::reset), [`write`](crate::Reg::write), [`write_with_zero`](crate::Reg::write_with_zero) this register using [`csmode::W`](W). You can also [`modify`](crate::Reg::modify) this register. See [API](https://docs.rs/svd2rust/#read--modify--write-api)."] 93 | pub struct CsmodeSpec; 94 | impl crate::RegisterSpec for CsmodeSpec { 95 | type Ux = u32; 96 | } 97 | #[doc = "`read()` method returns [`csmode::R`](R) reader structure"] 98 | impl crate::Readable for CsmodeSpec {} 99 | #[doc = "`write(|w| ..)` method takes [`csmode::W`](W) writer structure"] 100 | impl crate::Writable for CsmodeSpec { 101 | type Safety = crate::Unsafe; 102 | } 103 | #[doc = "`reset()` method sets csmode to value 0"] 104 | impl crate::Resettable for CsmodeSpec {} 105 | --------------------------------------------------------------------------------