21 Commits

Author SHA1 Message Date
652af5cb3c README correction
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
2024-07-04 18:41:33 +02:00
6e231e2553 prepare next vorago-reb1 release
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
2024-07-04 18:40:26 +02:00
79b7d7b4c2 Merge pull request 'Improve UART CLK calculation' (#12) from improve-uart-clk-calc into main
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
Reviewed-on: #12
2024-07-04 18:33:08 +02:00
3196d74a34 doc correction
Some checks are pending
Rust/va108xx-rs/pipeline/head Build queued...
2024-07-04 18:32:30 +02:00
d7c27446e0 Merge remote-tracking branch 'origin/main' into improve-uart-clk-calc
Some checks are pending
Rust/va108xx-rs/pipeline/head Build started...
2024-07-04 18:27:17 +02:00
3d4e8477c1 improve UART clock calculation 2024-07-04 18:26:56 +02:00
e2e3cc7020 Merge pull request 'Improve HAL' (#11) from improve-hal into main
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
Reviewed-on: #11
2024-07-04 18:16:11 +02:00
4f15cd7a31 another small link fix
Some checks are pending
Rust/va108xx-rs/pipeline/pr-main Build queued...
2024-07-04 18:15:55 +02:00
3c8c455c6f Update and improve HAL library and docs
All checks were successful
Rust/va108xx-rs/pipeline/pr-main This commit looks good
2024-07-04 18:07:34 +02:00
abb78c2682 Merge pull request 'update doc build settings' (#10) from update-doc-settings into main
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
Reviewed-on: #10
2024-06-26 23:05:30 +02:00
51f21fee43 update doc build settings
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
2024-06-26 22:58:12 +02:00
6fb3b0544f Merge pull request 'readme fix' (#9) from readme-fix into main
Some checks failed
Rust/va108xx-rs/pipeline/head There was a failure building this commit
Reviewed-on: #9
2024-06-25 20:18:48 +02:00
e3996d9166 Merge branch 'main' into readme-fix 2024-06-25 20:18:39 +02:00
deee5f6f46 readme fix
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
2024-06-25 19:44:12 +02:00
5d6c7ebf5e Merge pull request 'doc fixes and improvements' (#8) from update-docs into main
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
Reviewed-on: #8
2024-06-25 11:02:54 +02:00
6b3cdf74cc Merge branch 'main' into update-docs
Some checks are pending
Rust/va108xx-rs/pipeline/pr-main Build queued...
2024-06-25 11:02:31 +02:00
f4f378ba4f doc fixes and improvements
All checks were successful
Rust/va108xx-rs/pipeline/head This commit looks good
2024-06-25 10:47:33 +02:00
4224b14545 Merge pull request 'update docs' (#7) from update-docs into main
Some checks failed
Rust/va108xx-rs/pipeline/head There was a failure building this commit
Reviewed-on: #7
2024-06-25 10:26:10 +02:00
e3cdb19a35 Merge branch 'main' into update-docs 2024-06-25 10:26:02 +02:00
95e72cfea6 update docs
Some checks are pending
Rust/va108xx-rs/pipeline/head Build queued...
2024-06-25 10:25:39 +02:00
6854703c5d link corrections
Some checks failed
Rust/va108xx-rs/pipeline/head There was a failure building this commit
2024-06-23 22:05:11 +02:00
43 changed files with 1612 additions and 1466 deletions

View File

@ -24,8 +24,7 @@ rustflags = [
# "-C", "link-arg=-Tdefmt.x", # "-C", "link-arg=-Tdefmt.x",
# Can be useful for debugging. # Can be useful for debugging.
"-Clink-args=-Map=app.map" # "-Clink-args=-Map=app.map"
] ]
[build] [build]

View File

@ -39,7 +39,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/rust-toolchain@nightly
- run: cargo +nightly doc --all-features --config 'build.rustdocflags=["--cfg", "docs_rs"]' - run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc --all-features
clippy: clippy:
name: Clippy name: Clippy

View File

@ -106,3 +106,6 @@ configuration variables in your `settings.json`:
- `"cortex-debug.gdbPath.linux"` - `"cortex-debug.gdbPath.linux"`
- `"cortex-debug.gdbPath.windows"` - `"cortex-debug.gdbPath.windows"`
- `"cortex-debug.gdbPath.osx"` - `"cortex-debug.gdbPath.osx"`
The provided VS Code configurations also provide an integrated RTT logger, which you can access
via the terminal at `RTT Ch:0 console`.

View File

@ -25,7 +25,7 @@ pipeline {
stage('Docs') { stage('Docs') {
steps { steps {
sh """ sh """
cargo +nightly doc --all-features --config 'build.rustdocflags=["--cfg", "docs_rs"]' RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc --all-features
""" """
} }
} }

View File

@ -15,7 +15,7 @@ embedded-hal-nb = "1"
embedded-io = "0.6" embedded-io = "0.6"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.6" version = "0.7"
path = "../va108xx-hal" path = "../va108xx-hal"
features = ["rt"] features = ["rt"]

View File

@ -28,6 +28,6 @@ version = "1"
features = ["cortex-m-systick"] features = ["cortex-m-systick"]
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.6" version = "0.7"
path = "../../va108xx-hal" path = "../../va108xx-hal"
features = ["rt", "defmt"] features = ["rt", "defmt"]

View File

@ -21,9 +21,9 @@ fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap();
let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta); let pinsa = PinsA::new(&mut dp.sysconfig, None, dp.porta);
let mut pwm = pwm::PwmPin::new( let mut pwm = pwm::PwmPin::new(
(pinsa.pa3.into_funsel_1(), dp.tim3),
50.MHz(),
&mut dp.sysconfig, &mut dp.sysconfig,
50.MHz(),
(pinsa.pa3.into_funsel_1(), dp.tim3),
10.Hz(), 10.Hz(),
); );
let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0);

View File

@ -3,12 +3,14 @@
#![no_std] #![no_std]
use cortex_m_rt::entry; use cortex_m_rt::entry;
use panic_halt as _; use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print}; use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal as _;
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
rtt_init_print!(); rtt_init_print!();
rprintln!("-- VA108XX RTT example --");
let mut counter = 0; let mut counter = 0;
loop { loop {
rprintln!("{}: Hello, world!", counter); rprintln!("{}: Hello, world!", counter);

View File

@ -73,12 +73,12 @@ fn main() -> ! {
pinsa.pa30.into_funsel_1(), pinsa.pa30.into_funsel_1(),
pinsa.pa29.into_funsel_1(), pinsa.pa29.into_funsel_1(),
); );
let mut spia = Spi::spia( let mut spia = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spia, dp.spia,
(sck, miso, mosi), (sck, miso, mosi),
50.MHz(),
spi_cfg, spi_cfg,
Some(&mut dp.sysconfig),
None, None,
); );
spia.set_fill_word(FILL_WORD); spia.set_fill_word(FILL_WORD);
@ -90,12 +90,12 @@ fn main() -> ! {
pinsb.pb8.into_funsel_2(), pinsb.pb8.into_funsel_2(),
pinsb.pb7.into_funsel_2(), pinsb.pb7.into_funsel_2(),
); );
let mut spia = Spi::spia( let mut spia = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spia, dp.spia,
(sck, miso, mosi), (sck, miso, mosi),
50.MHz(),
spi_cfg, spi_cfg,
Some(&mut dp.sysconfig),
None, None,
); );
spia.set_fill_word(FILL_WORD); spia.set_fill_word(FILL_WORD);
@ -107,12 +107,12 @@ fn main() -> ! {
pinsb.pb4.into_funsel_1(), pinsb.pb4.into_funsel_1(),
pinsb.pb3.into_funsel_1(), pinsb.pb3.into_funsel_1(),
); );
let mut spib = Spi::spib( let mut spib = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spib, dp.spib,
(sck, miso, mosi), (sck, miso, mosi),
50.MHz(),
spi_cfg, spi_cfg,
Some(&mut dp.sysconfig),
None, None,
); );
spib.set_fill_word(FILL_WORD); spib.set_fill_word(FILL_WORD);
@ -195,6 +195,10 @@ fn main() -> ! {
if EXAMPLE_SEL == ExampleSelect::Loopback { if EXAMPLE_SEL == ExampleSelect::Loopback {
// Can't really verify correct reply here. // Can't really verify correct reply here.
spi.write(&[0x42]).expect("write failed"); spi.write(&[0x42]).expect("write failed");
// Need small delay.. otherwise we will read back the sent byte (which we don't want here).
// The write function will return as soon as all bytes were shifted out, ignoring the
// reply bytes.
delay.delay_us(50);
// Because of the loopback mode, we should get back the fill word here. // Because of the loopback mode, we should get back the fill word here.
spi.read(&mut reply_buf[0..1]).unwrap(); spi.read(&mut reply_buf[0..1]).unwrap();
assert_eq!(reply_buf[0], FILL_WORD); assert_eq!(reply_buf[0], FILL_WORD);

View File

@ -65,7 +65,7 @@ mod app {
let irq_cfg = IrqCfg::new(pac::interrupt::OC3, true, true); let irq_cfg = IrqCfg::new(pac::interrupt::OC3, true, true);
let (mut irq_uart, _) = let (mut irq_uart, _) =
uart::Uart::uartb(dp.uartb, (tx, rx), 115200.Hz(), &mut dp.sysconfig, 50.MHz()) uart::Uart::new(&mut dp.sysconfig, 50.MHz(), dp.uartb, (tx, rx), 115200.Hz())
.into_uart_with_irq(irq_cfg, Some(&mut dp.sysconfig), Some(&mut dp.irqsel)) .into_uart_with_irq(irq_cfg, Some(&mut dp.sysconfig), Some(&mut dp.irqsel))
.downgrade(); .downgrade();
irq_uart irq_uart

View File

@ -28,7 +28,7 @@ fn main() -> ! {
let tx = gpioa.pa9.into_funsel_2(); let tx = gpioa.pa9.into_funsel_2();
let rx = gpioa.pa8.into_funsel_2(); let rx = gpioa.pa8.into_funsel_2();
let uarta = uart::Uart::uarta(dp.uarta, (tx, rx), 115200.Hz(), &mut dp.sysconfig, 50.MHz()); let uarta = uart::Uart::new(&mut dp.sysconfig, 50.MHz(), dp.uarta, (tx, rx), 115200.Hz());
let (mut tx, mut rx) = uarta.split(); let (mut tx, mut rx) = uarta.split();
writeln!(tx, "Hello World\r").unwrap(); writeln!(tx, "Hello World\r").unwrap();
loop { loop {

View File

@ -6,6 +6,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [v0.7.0] 2024-07-04
- Replace `uarta` and `uartb` `Uart` constructors by `new` constructor
- Replace SPI `spia`, `spib` and `spic` constructors by `new` constructor
- Replace I2C `i2ca`, `i2cb` constructors by `new` constructor. Update constructor
to fail on invalid fast I2C speed system clock values
- Renamed `gpio::pins` to `gpio::pin` and `gpio::dynpins` to `gpio::dynpin`
- Simplify UART clock divider calculations and remove `libm` dependency consequently
## [v0.6.0] 2024-06-16 ## [v0.6.0] 2024-06-16
- Updated `embedded-hal` to v1 - Updated `embedded-hal` to v1

View File

@ -1,6 +1,6 @@
[package] [package]
name = "va108xx-hal" name = "va108xx-hal"
version = "0.6.0" version = "0.7.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2021" edition = "2021"
description = "HAL for the Vorago VA108xx family of microcontrollers" description = "HAL for the Vorago VA108xx family of microcontrollers"
@ -16,7 +16,6 @@ cortex-m-rt = "0.7"
nb = "1" nb = "1"
paste = "1" paste = "1"
embedded-hal-nb = "1" embedded-hal-nb = "1"
libm = "0.2"
embedded-io = "0.6" embedded-io = "0.6"
fugit = "0.3" fugit = "0.3"
typenum = "1" typenum = "1"
@ -45,4 +44,4 @@ rt = ["va108xx/rt"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docs_rs", "--generate-link-to-definition"] rustdoc-args = ["--generate-link-to-definition"]

View File

@ -4,7 +4,7 @@
# HAL for the Vorago VA108xx MCU family # HAL for the Vorago VA108xx MCU family
This repository contains the **H**ardware **A**bstraction **L**ayer (HAL), which is an additional This repository contains the **H**ardware **A**bstraction **L**ayer (HAL), which is an additional
hardware abstraction on top of the [peripheral access API](https://egit.irs.uni-stuttgart.de/rust/va108xx). hardware abstraction on top of the [peripheral access API](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/va108xx).
It is the result of reading the datasheet for the device and encoding a type-safe layer over the It is the result of reading the datasheet for the device and encoding a type-safe layer over the
raw PAC. This crate also implements traits specified by the raw PAC. This crate also implements traits specified by the
@ -39,7 +39,7 @@ your custom board.
The hello world of embedded development is usually to blinky a LED. This example The hello world of embedded development is usually to blinky a LED. This example
is contained within the is contained within the
[examples folder](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/blinky.rs). [examples folder](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/blinky.rs).
1. Set up your Rust cross-compiler if you have not done so yet. See more in the [build chapter](#Building) 1. Set up your Rust cross-compiler if you have not done so yet. See more in the [build chapter](#Building)
2. Create a new binary crate with `cargo init` 2. Create a new binary crate with `cargo init`

View File

@ -36,8 +36,7 @@
//! Users may try to convert value-level pins back to their type-level //! Users may try to convert value-level pins back to their type-level
//! equivalents. However, this option is fallible, because the compiler cannot //! equivalents. However, this option is fallible, because the compiler cannot
//! guarantee the pin has the correct ID or is in the correct mode at //! guarantee the pin has the correct ID or is in the correct mode at
//! compile-time. Use [`TryFrom`](core::convert::TryFrom)/ //! compile-time. Use [TryFrom]/[TryInto] for this conversion.
//! [`TryInto`](core::convert::TryInto) for this conversion.
//! //!
//! ``` //! ```
//! // Convert to a `DynPin` //! // Convert to a `DynPin`
@ -55,10 +54,10 @@
//! `Error = core::convert::Infallible`, the value-level API can return a real //! `Error = core::convert::Infallible`, the value-level API can return a real
//! error. If the [`DynPin`] is not in the correct [`DynPinMode`] for the //! error. If the [`DynPin`] is not in the correct [`DynPinMode`] for the
//! operation, the trait functions will return //! operation, the trait functions will return
//! [`InvalidPinType`](PinError::InvalidPinType). //! [InvalidPinTypeError].
use super::{ use super::{
pins::{FilterType, InterruptEdge, InterruptLevel, Pin, PinId, PinMode, PinState}, pin::{FilterType, InterruptEdge, InterruptLevel, Pin, PinId, PinMode, PinState},
reg::RegisterInterface, reg::RegisterInterface,
}; };
use crate::{clock::FilterClkSel, pac, FunSel, IrqCfg}; use crate::{clock::FilterClkSel, pac, FunSel, IrqCfg};

View File

@ -3,10 +3,10 @@
//! The implementation of this GPIO module is heavily based on the //! The implementation of this GPIO module is heavily based on the
//! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/index.html). //! [ATSAMD HAL implementation](https://docs.rs/atsamd-hal/latest/atsamd_hal/gpio/index.html).
//! //!
//! This API provides two different submodules, [`mod@pins`] and [`dynpins`], //! This API provides two different submodules, [pin] and [dynpin],
//! representing two different ways to handle GPIO pins. The default, [`mod@pins`], //! representing two different ways to handle GPIO pins. The default, [pin],
//! is a type-level API that tracks the state of each pin at compile-time. The //! is a type-level API that tracks the state of each pin at compile-time. The
//! alternative, [`dynpins`] is a type-erased, value-level API that tracks the //! alternative, [dynpin] is a type-erased, value-level API that tracks the
//! state of each pin at run-time. //! state of each pin at run-time.
//! //!
//! The type-level API is strongly preferred. By representing the state of each //! The type-level API is strongly preferred. By representing the state of each
@ -14,14 +14,13 @@
//! compile-time. Furthermore, the type-level API has absolutely zero run-time //! compile-time. Furthermore, the type-level API has absolutely zero run-time
//! cost. //! cost.
//! //!
//! If needed, [`dynpins`] can be used to erase the type-level differences //! If needed, [dynpin] can be used to erase the type-level differences
//! between pins. However, by doing so, pins must now be tracked at run-time, //! between pins. However, by doing so, pins must now be tracked at run-time,
//! and each pin has a non-zero memory footprint. //! and each pin has a non-zero memory footprint.
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/blinky.rs) //! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/blinky.rs)
//!
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -102,10 +101,10 @@ macro_rules! common_reg_if_functions {
}; };
} }
pub mod dynpins; pub mod dynpin;
pub use dynpins::*; pub use dynpin::*;
pub mod pins; pub mod pin;
pub use pins::*; pub use pin::*;
mod reg; mod reg;

View File

@ -29,73 +29,48 @@
//! } //! }
//! ``` //! ```
//! //!
//! A `PinId` identifies a pin by it's group (A, B, C or D) and pin number. Each //! A [PinId] identifies a pin by it's group (A or B) and pin number. Each
//! `PinId` instance is named according to its datasheet identifier, e.g. //! [PinId] instance is named according to its datasheet identifier, e.g.
//! [`PA02`]. //! [PA2].
//! //!
//! A `PinMode` represents the various pin modes. The available `PinMode` //! A [PinMode] represents the various pin modes. The available [PinMode]
//! variants are [`Disabled`], [`Input`], [`Interrupt`], [`Output`] and //! variants are [`Input`], [`Output`] and [`Alternate`], each with its own
//! [`Alternate`], each with its own corresponding configurations. //! corresponding configurations.
//! //!
//! It is not possible for users to create new instances of a [`Pin`]. Singleton //! It is not possible for users to create new instances of a [`Pin`]. Singleton
//! instances of each pin are made available to users through the [`Pins`] //! instances of each pin are made available to users through the PinsX
//! struct. //! struct.
//! //!
//! To create the [`Pins`] struct, users must supply the PAC //! Example for the pins of PORT A:
//! [`PORT`](crate::pac::PORT) peripheral. The [`Pins`] struct takes //!
//! ownership of the [`PORT`] and provides the corresponding pins. Each [`Pin`] //! To create the [PinsA] struct, users must supply the PAC
//! within the [`Pins`] struct can be moved out and used individually. //! [Port](crate::pac::Porta) peripheral. The [PinsA] struct takes
//! ownership of the [Porta] and provides the corresponding pins. Each [`Pin`]
//! within the [PinsA] struct can be moved out and used individually.
//! //!
//! //!
//! ``` //! ```
//! let mut peripherals = Peripherals::take().unwrap(); //! let mut peripherals = Peripherals::take().unwrap();
//! let pins = Pins::new(peripherals.PORT); //! let pinsa = PinsA::new(peripherals.PORT);
//! ``` //! ```
//! //!
//! Pins can be converted between modes using several different methods. //! Pins can be converted between modes using several different methods.
//! //!
//! ``` //! ```no_run
//! // Use one of the literal function names //! // Use one of the literal function names
//! let pa27 = pins.pa27.into_floating_input(); //! let pa0 = pinsa.pa0.into_floating_input();
//! // Use a generic method and one of the `PinMode` variant types //! // Use a generic method and one of the `PinMode` variant types
//! let pa27 = pins.pa27.into_mode::<FloatingInput>(); //! let pa0 = pinsa.pa0.into_mode::<FloatingInput>();
//! // Specify the target type and use `From`/`Into` //! // Specify the target type and use `From`/`Into`
//! let pa27: Pin<PA27, FloatingInput> = pins.pa27.into(); //! let pa0: Pin<PA0, FloatingInput> = pinsa.pa27.into();
//! ``` //! ```
//! //!
//! # Embedded HAL traits //! # Embedded HAL traits
//! //!
//! This module implements all of the embedded HAL GPIO traits for each [`Pin`] //! This module implements all of the embedded HAL GPIO traits for each [`Pin`]
//! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`], //! in the corresponding [`PinMode`]s, namely: [`InputPin`], [`OutputPin`],
//! [`ToggleableOutputPin`] and [`StatefulOutputPin`]. //! and [`StatefulOutputPin`].
//! use super::dynpin::{DynAlternate, DynGroup, DynInput, DynOutput, DynPinId, DynPinMode};
//! For example, you can control the logic level of an `OutputPin` like so
//!
//! ```
//! use atsamd_hal::pac::Peripherals;
//! use atsamd_hal::gpio::Pins;
//! use crate::ehal_02::digital::v2::OutputPin;
//!
//! let mut peripherals = Peripherals::take().unwrap();
//! let mut pins = Pins::new(peripherals.PORT);
//! pins.pa27.set_high();
//! ```
//!
//! # Type-level features
//!
//! This module also provides additional, type-level tools to work with GPIO
//! pins.
//!
//! The [`OptionalPinId`] and [`OptionalPin`] traits use the [`OptionalKind`]
//! pattern to act as type-level versions of [`Option`] for `PinId` and `Pin`
//! respectively. And the [`AnyPin`] trait defines an [`AnyKind`] type class
//! for all `Pin` types.
//!
//! [type classes]: crate::typelevel#type-classes
//! [type-level enum]: crate::typelevel#type-level-enum
//! [`OptionalKind`]: crate::typelevel#optionalkind-trait-pattern
//! [`AnyKind`]: crate::typelevel#anykind-trait-pattern
use super::dynpins::{DynAlternate, DynGroup, DynInput, DynOutput, DynPinId, DynPinMode};
use super::reg::RegisterInterface; use super::reg::RegisterInterface;
use crate::{ use crate::{
pac::{Irqsel, Porta, Portb, Sysconfig}, pac::{Irqsel, Porta, Portb, Sysconfig},
@ -137,9 +112,9 @@ pub enum PinState {
/// Type-level enum for input configurations /// Type-level enum for input configurations
/// ///
/// The valid options are [`Floating`], [`PullDown`] and [`PullUp`]. /// The valid options are [Floating], [PullDown] and [PullUp].
pub trait InputConfig: Sealed { pub trait InputConfig: Sealed {
/// Corresponding [`DynInput`](super::DynInput) /// Corresponding [DynInput]
const DYN: DynInput; const DYN: DynInput;
} }
@ -297,9 +272,9 @@ pub type Reset = InputFloating;
/// Type-level enum representing pin modes /// Type-level enum representing pin modes
/// ///
/// The valid options are [`Input`], [`Output`] and [`Alternate`]. /// The valid options are [Input], [Output] and [Alternate].
pub trait PinMode: Sealed { pub trait PinMode: Sealed {
/// Corresponding [`DynPinMode`](super::DynPinMode) /// Corresponding [DynPinMode]
const DYN: DynPinMode; const DYN: DynPinMode;
} }
@ -319,7 +294,7 @@ impl<C: AlternateConfig> PinMode for Alternate<C> {
/// Type-level enum for pin IDs /// Type-level enum for pin IDs
pub trait PinId: Sealed { pub trait PinId: Sealed {
/// Corresponding [`DynPinId`](super::DynPinId) /// Corresponding [DynPinId]
const DYN: DynPinId; const DYN: DynPinId;
} }
@ -344,7 +319,7 @@ macro_rules! pin_id {
// Pin // Pin
//================================================================================================== //==================================================================================================
/// A type-level GPIO pin, parameterized by [`PinId`] and [`PinMode`] types /// A type-level GPIO pin, parameterized by [PinId] and [PinMode] types
pub struct Pin<I: PinId, M: PinMode> { pub struct Pin<I: PinId, M: PinMode> {
pub(in crate::gpio) regs: Registers<I>, pub(in crate::gpio) regs: Registers<I>,
@ -352,12 +327,12 @@ pub struct Pin<I: PinId, M: PinMode> {
} }
impl<I: PinId, M: PinMode> Pin<I, M> { impl<I: PinId, M: PinMode> Pin<I, M> {
/// Create a new [`Pin`] /// Create a new [Pin]
/// ///
/// # Safety /// # Safety
/// ///
/// Each [`Pin`] must be a singleton. For a given [`PinId`], there must be /// Each [Pin] must be a singleton. For a given [PinId], there must be
/// at most one corresponding [`Pin`] in existence at any given time. /// at most one corresponding [Pin] in existence at any given time.
/// Violating this requirement is `unsafe`. /// Violating this requirement is `unsafe`.
#[inline] #[inline]
pub(crate) unsafe fn new() -> Pin<I, M> { pub(crate) unsafe fn new() -> Pin<I, M> {

View File

@ -1,5 +1,5 @@
use super::dynpins::{self, DynGroup, DynPinId, DynPinMode}; use super::dynpin::{self, DynGroup, DynPinId, DynPinMode};
use super::pins::{FilterType, InterruptEdge, InterruptLevel, PinState}; use super::pin::{FilterType, InterruptEdge, InterruptLevel, PinState};
use super::IsMaskedError; use super::IsMaskedError;
use crate::clock::FilterClkSel; use crate::clock::FilterClkSel;
use va108xx::{ioconfig, porta}; use va108xx::{ioconfig, porta};
@ -30,7 +30,7 @@ impl From<DynPinMode> for ModeFields {
use DynPinMode::*; use DynPinMode::*;
match mode { match mode {
Input(config) => { Input(config) => {
use dynpins::DynInput::*; use dynpin::DynInput::*;
fields.dir = false; fields.dir = false;
match config { match config {
Floating => (), Floating => (),
@ -44,7 +44,7 @@ impl From<DynPinMode> for ModeFields {
} }
} }
Output(config) => { Output(config) => {
use dynpins::DynOutput::*; use dynpin::DynOutput::*;
fields.dir = true; fields.dir = true;
match config { match config {
PushPull => (), PushPull => (),

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#![no_std] #![no_std]
#![cfg_attr(docs_rs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
pub use va108xx; pub use va108xx;
pub use va108xx as pac; pub use va108xx as pac;

View File

@ -1,3 +1,5 @@
//! Prelude //! Prelude
pub use fugit::ExtU32 as _; pub use fugit::ExtU32 as _;
pub use fugit::RateExtU32 as _; pub use fugit::RateExtU32 as _;
pub use crate::time::*;

View File

@ -4,7 +4,7 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/pwm.rs) //! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/pwm.rs)
use core::convert::Infallible; use core::convert::Infallible;
use core::marker::PhantomData; use core::marker::PhantomData;
@ -158,9 +158,9 @@ where
{ {
/// Create a new stronlgy typed PWM pin /// Create a new stronlgy typed PWM pin
pub fn new( pub fn new(
vtp: (Pin, Tim),
sys_clk: impl Into<Hertz> + Copy,
sys_cfg: &mut pac::Sysconfig, sys_cfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz> + Copy,
tim_and_pin: (Pin, Tim),
initial_period: impl Into<Hertz> + Copy, initial_period: impl Into<Hertz> + Copy,
) -> Self { ) -> Self {
let mut pin = PwmPin { let mut pin = PwmPin {
@ -171,7 +171,7 @@ where
current_rst_val: 0, current_rst_val: 0,
sys_clk: sys_clk.into(), sys_clk: sys_clk.into(),
}, },
reg: unsafe { TimAndPinRegister::new(vtp.0, vtp.1) }, reg: unsafe { TimAndPinRegister::new(tim_and_pin.0, tim_and_pin.1) },
mode: PhantomData, mode: PhantomData,
}; };
enable_peripheral_clock(sys_cfg, crate::clock::PeripheralClocks::Gpio); enable_peripheral_clock(sys_cfg, crate::clock::PeripheralClocks::Gpio);
@ -225,12 +225,13 @@ where
(Pin, Tim): ValidTimAndPin<Pin, Tim>, (Pin, Tim): ValidTimAndPin<Pin, Tim>,
{ {
pub fn pwma( pub fn pwma(
vtp: (Pin, Tim),
sys_clk: impl Into<Hertz> + Copy,
sys_cfg: &mut pac::Sysconfig, sys_cfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz> + Copy,
pin_and_tim: (Pin, Tim),
initial_period: impl Into<Hertz> + Copy, initial_period: impl Into<Hertz> + Copy,
) -> Self { ) -> Self {
let mut pin: PwmPin<Pin, Tim, PwmA> = Self::new(vtp, sys_clk, sys_cfg, initial_period); let mut pin: PwmPin<Pin, Tim, PwmA> =
Self::new(sys_cfg, sys_clk, pin_and_tim, initial_period);
pin.enable_pwm_a(); pin.enable_pwm_a();
pin pin
} }
@ -241,12 +242,13 @@ where
(Pin, Tim): ValidTimAndPin<Pin, Tim>, (Pin, Tim): ValidTimAndPin<Pin, Tim>,
{ {
pub fn pwmb( pub fn pwmb(
vtp: (Pin, Tim),
sys_clk: impl Into<Hertz> + Copy,
sys_cfg: &mut pac::Sysconfig, sys_cfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz> + Copy,
pin_and_tim: (Pin, Tim),
initial_period: impl Into<Hertz> + Copy, initial_period: impl Into<Hertz> + Copy,
) -> Self { ) -> Self {
let mut pin: PwmPin<Pin, Tim, PwmB> = Self::new(vtp, sys_clk, sys_cfg, initial_period); let mut pin: PwmPin<Pin, Tim, PwmB> =
Self::new(sys_cfg, sys_clk, pin_and_tim, initial_period);
pin.enable_pwm_b(); pin.enable_pwm_b();
pin pin
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
use crate::{pac, PeripheralSelect}; use crate::{pac, PeripheralSelect};
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
pub struct InvalidounterResetVal(pub(crate) ()); #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InvalidCounterResetVal(pub(crate) ());
/// Enable scrubbing for the ROM /// Enable scrubbing for the ROM
/// ///
/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0 /// Returns [InvalidCounterResetVal] if the scrub rate is 0
/// (equivalent to disabling) or larger than 24 bits /// (equivalent to disabling) or larger than 24 bits
pub fn enable_rom_scrubbing( pub fn enable_rom_scrubbing(
syscfg: &mut pac::Sysconfig, syscfg: &mut pac::Sysconfig,
scrub_rate: u32, scrub_rate: u32,
) -> Result<(), InvalidounterResetVal> { ) -> Result<(), InvalidCounterResetVal> {
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) { if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
return Err(InvalidounterResetVal(())); return Err(InvalidCounterResetVal(()));
} }
syscfg.rom_scrub().write(|w| unsafe { w.bits(scrub_rate) }); syscfg.rom_scrub().write(|w| unsafe { w.bits(scrub_rate) });
Ok(()) Ok(())
@ -24,14 +25,14 @@ pub fn disable_rom_scrubbing(syscfg: &mut pac::Sysconfig) {
/// Enable scrubbing for the RAM /// Enable scrubbing for the RAM
/// ///
/// Returns [`UtilityError::InvalidCounterResetVal`] if the scrub rate is 0 /// Returns [InvalidCounterResetVal] if the scrub rate is 0
/// (equivalent to disabling) or larger than 24 bits /// (equivalent to disabling) or larger than 24 bits
pub fn enable_ram_scrubbing( pub fn enable_ram_scrubbing(
syscfg: &mut pac::Sysconfig, syscfg: &mut pac::Sysconfig,
scrub_rate: u32, scrub_rate: u32,
) -> Result<(), InvalidounterResetVal> { ) -> Result<(), InvalidCounterResetVal> {
if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) { if scrub_rate == 0 || scrub_rate > u32::pow(2, 24) {
return Err(InvalidounterResetVal(())); return Err(InvalidCounterResetVal(()));
} }
syscfg.ram_scrub().write(|w| unsafe { w.bits(scrub_rate) }); syscfg.ram_scrub().write(|w| unsafe { w.bits(scrub_rate) });
Ok(()) Ok(())

View File

@ -2,7 +2,7 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [MS and second tick implementation](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/timer-ticks.rs) //! - [MS and second tick implementation](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/timer-ticks.rs)
//! - [Cascade feature example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/cascade.rs) //! - [Cascade feature example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/cascade.rs)
pub use crate::IrqCfg; pub use crate::IrqCfg;
use crate::{ use crate::{

View File

@ -2,23 +2,23 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart.rs) //! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/uart.rs)
//! - [UART with IRQ and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart-irq-rtic.rs) //! - [UART with IRQ and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/uart-irq-rtic.rs)
use core::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData, ops::Deref};
use embedded_hal_nb::serial::Read; use embedded_hal_nb::serial::Read;
use fugit::RateExtU32; use fugit::RateExtU32;
use libm::floorf;
pub use crate::IrqCfg; pub use crate::IrqCfg;
use crate::{ use crate::{
clock::{self, enable_peripheral_clock, PeripheralClocks}, clock::{enable_peripheral_clock, PeripheralClocks},
gpio::pins::{ gpio::pin::{
AltFunc1, AltFunc2, AltFunc3, Pin, PA16, PA17, PA18, PA19, PA2, PA26, PA27, PA3, PA30, AltFunc1, AltFunc2, AltFunc3, Pin, PA16, PA17, PA18, PA19, PA2, PA26, PA27, PA3, PA30,
PA31, PA8, PA9, PB18, PB19, PB20, PB21, PB22, PB23, PB6, PB7, PB8, PB9, PA31, PA8, PA9, PB18, PB19, PB20, PB21, PB22, PB23, PB6, PB7, PB8, PB9,
}, },
pac::{self, uarta as uart_base}, pac::{self, uarta as uart_base},
time::Hertz, time::Hertz,
utility::unmask_irq, utility::unmask_irq,
PeripheralSelect,
}; };
//================================================================================================== //==================================================================================================
@ -306,7 +306,7 @@ pub struct UartBase<Uart> {
} }
/// Serial abstraction. Entry point to create a new UART /// Serial abstraction. Entry point to create a new UART
pub struct Uart<Uart, Pins> { pub struct Uart<Uart, Pins> {
uart_base: UartBase<Uart>, inner: UartBase<Uart>,
pins: Pins, pins: Pins,
} }
@ -353,6 +353,7 @@ impl<UART> Tx<UART> {
pub trait Instance: Deref<Target = uart_base::RegisterBlock> { pub trait Instance: Deref<Target = uart_base::RegisterBlock> {
fn ptr() -> *const uart_base::RegisterBlock; fn ptr() -> *const uart_base::RegisterBlock;
const IDX: u8; const IDX: u8;
const PERIPH_SEL: PeripheralSelect;
} }
impl<UART: Instance> UartBase<UART> { impl<UART: Instance> UartBase<UART> {
@ -363,12 +364,19 @@ impl<UART: Instance> UartBase<UART> {
false => 16, false => 16,
true => 8, true => 8,
}; };
// This is the calculation: (64.0 * (x - integer_part as f32) + 0.5) as u32 without floating
// point calculations.
let frac = ((sys_clk.raw() % (config.baudrate.raw() * 16)) * 64
+ (config.baudrate.raw() * 8))
/ (config.baudrate.raw() * 16);
// Calculations here are derived from chapter 4.8.5 (p.79) of the datasheet.
let x = sys_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32; let x = sys_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32;
let integer_part = floorf(x) as u32; let integer_part = x as u32;
let frac = floorf(64.0 * (x - integer_part as f32) + 0.5) as u32; self.uart.clkscale().write(|w| unsafe {
self.uart w.frac().bits(frac as u8);
.clkscale() w.int().bits(integer_part)
.write(|w| unsafe { w.bits(integer_part * 64 + frac) }); });
let (paren, pareven) = match config.parity { let (paren, pareven) = match config.parity {
Parity::None => (false, false), Parity::None => (false, false),
@ -483,14 +491,34 @@ impl<UART: Instance> UartBase<UART> {
} }
} }
impl<UART, PINS> Uart<UART, PINS> impl<UartInstance, PinsInstance> Uart<UartInstance, PinsInstance>
where where
UART: Instance, UartInstance: Instance,
PinsInstance: Pins<UartInstance>,
{ {
pub fn new(
syscfg: &mut va108xx::Sysconfig,
sys_clk: impl Into<Hertz>,
uart: UartInstance,
pins: PinsInstance,
config: impl Into<Config>,
) -> Self {
crate::clock::enable_peripheral_clock(syscfg, UartInstance::PERIPH_SEL);
Uart {
inner: UartBase {
uart,
tx: Tx::new(),
rx: Rx::new(),
},
pins,
}
.init(config.into(), sys_clk.into())
}
/// This function assumes that the peripheral clock was alredy enabled /// This function assumes that the peripheral clock was alredy enabled
/// in the SYSCONFIG register /// in the SYSCONFIG register
fn init(mut self, config: Config, sys_clk: Hertz) -> Self { fn init(mut self, config: Config, sys_clk: Hertz) -> Self {
self.uart_base = self.uart_base.init(config, sys_clk); self.inner = self.inner.init(config, sys_clk);
self self
} }
@ -501,7 +529,7 @@ where
irq_cfg: IrqCfg, irq_cfg: IrqCfg,
sys_cfg: Option<&mut pac::Sysconfig>, sys_cfg: Option<&mut pac::Sysconfig>,
irq_sel: Option<&mut pac::Irqsel>, irq_sel: Option<&mut pac::Irqsel>,
) -> UartWithIrq<UART, PINS> { ) -> UartWithIrq<UartInstance, PinsInstance> {
let (uart, pins) = self.downgrade_internal(); let (uart, pins) = self.downgrade_internal();
UartWithIrq { UartWithIrq {
pins, pins,
@ -520,75 +548,75 @@ where
#[inline] #[inline]
pub fn enable_rx(&mut self) { pub fn enable_rx(&mut self) {
self.uart_base.enable_rx(); self.inner.enable_rx();
} }
#[inline] #[inline]
pub fn disable_rx(&mut self) { pub fn disable_rx(&mut self) {
self.uart_base.enable_rx(); self.inner.enable_rx();
} }
#[inline] #[inline]
pub fn enable_tx(&mut self) { pub fn enable_tx(&mut self) {
self.uart_base.enable_tx(); self.inner.enable_tx();
} }
#[inline] #[inline]
pub fn disable_tx(&mut self) { pub fn disable_tx(&mut self) {
self.uart_base.disable_tx(); self.inner.disable_tx();
} }
#[inline] #[inline]
pub fn clear_rx_fifo(&mut self) { pub fn clear_rx_fifo(&mut self) {
self.uart_base.clear_rx_fifo(); self.inner.clear_rx_fifo();
} }
#[inline] #[inline]
pub fn clear_tx_fifo(&mut self) { pub fn clear_tx_fifo(&mut self) {
self.uart_base.clear_tx_fifo(); self.inner.clear_tx_fifo();
} }
#[inline] #[inline]
pub fn clear_rx_status(&mut self) { pub fn clear_rx_status(&mut self) {
self.uart_base.clear_rx_status(); self.inner.clear_rx_status();
} }
#[inline] #[inline]
pub fn clear_tx_status(&mut self) { pub fn clear_tx_status(&mut self) {
self.uart_base.clear_tx_status(); self.inner.clear_tx_status();
} }
pub fn listen(&self, event: Event) { pub fn listen(&self, event: Event) {
self.uart_base.listen(event); self.inner.listen(event);
} }
pub fn unlisten(&self, event: Event) { pub fn unlisten(&self, event: Event) {
self.uart_base.unlisten(event); self.inner.unlisten(event);
} }
pub fn release(self) -> (UART, PINS) { pub fn release(self) -> (UartInstance, PinsInstance) {
(self.uart_base.release(), self.pins) (self.inner.release(), self.pins)
} }
fn downgrade_internal(self) -> (UartBase<UART>, PINS) { fn downgrade_internal(self) -> (UartBase<UartInstance>, PinsInstance) {
let base = UartBase { let base = UartBase {
uart: self.uart_base.uart, uart: self.inner.uart,
tx: self.uart_base.tx, tx: self.inner.tx,
rx: self.uart_base.rx, rx: self.inner.rx,
}; };
(base, self.pins) (base, self.pins)
} }
pub fn downgrade(self) -> UartBase<UART> { pub fn downgrade(self) -> UartBase<UartInstance> {
UartBase { UartBase {
uart: self.uart_base.uart, uart: self.inner.uart,
tx: self.uart_base.tx, tx: self.inner.tx,
rx: self.uart_base.rx, rx: self.inner.rx,
} }
} }
pub fn split(self) -> (Tx<UART>, Rx<UART>) { pub fn split(self) -> (Tx<UartInstance>, Rx<UartInstance>) {
self.uart_base.split() self.inner.split()
} }
} }
@ -597,6 +625,8 @@ impl Instance for pac::Uarta {
pac::Uarta::ptr() as *const _ pac::Uarta::ptr() as *const _
} }
const IDX: u8 = 0; const IDX: u8 = 0;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart0;
} }
impl Instance for pac::Uartb { impl Instance for pac::Uartb {
@ -604,36 +634,8 @@ impl Instance for pac::Uartb {
pac::Uartb::ptr() as *const _ pac::Uartb::ptr() as *const _
} }
const IDX: u8 = 1; const IDX: u8 = 1;
}
macro_rules! uart_impl { const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart1;
($($UARTX:path: ($uartx:ident, $clk_enb_enum:path),)+) => {
$(
impl<PINS: Pins<$UARTX>> Uart<$UARTX, PINS> {
pub fn $uartx(
uart: $UARTX,
pins: PINS,
config: impl Into<Config>,
syscfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz>
) -> Self
{
enable_peripheral_clock(syscfg, $clk_enb_enum);
Uart {
uart_base: UartBase {
uart,
tx: Tx::new(),
rx: Rx::new(),
},
pins,
}
.init(config.into(), sys_clk.into())
}
}
)+
}
} }
impl<UART: Instance> UartWithIrqBase<UART> { impl<UART: Instance> UartWithIrqBase<UART> {
@ -871,10 +873,12 @@ impl<UART: Instance, PINS> UartWithIrq<UART, PINS> {
} }
} }
/*
uart_impl! { uart_impl! {
pac::Uarta: (uarta, clock::PeripheralClocks::Uart0), pac::Uarta: (uarta, clock::PeripheralClocks::Uart0),
pac::Uartb: (uartb, clock::PeripheralClocks::Uart1), pac::Uartb: (uartb, clock::PeripheralClocks::Uart1),
} }
*/
impl<Uart> Tx<Uart> where Uart: Instance {} impl<Uart> Tx<Uart> where Uart: Instance {}

View File

@ -24,4 +24,4 @@ rt = ["cortex-m-rt/device"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docs_rs", "--generate-link-to-definition"] rustdoc-args = ["--generate-link-to-definition"]

View File

@ -4,7 +4,7 @@ svd2rust release can be generated by cloning the svd2rust [repository], checking
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![no_std] #![no_std]
// Manually inserted. // Manually inserted.
#![cfg_attr(docs_rs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Deref; use core::ops::Deref;
#[doc = r"Number available in the NVIC for configuring priority"] #[doc = r"Number available in the NVIC for configuring priority"]

View File

@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased] ## [unreleased]
## [v0.5.1] 2024-07-04
- Update `va108xx-hal` dependency to v0.7.0
## [v0.5.0] 2024-06-16 ## [v0.5.0] 2024-06-16
- Updated `va108xx` to v0.3.0 and `va108xx-hal` dependency to v0.6.0 - Updated `va108xx` to v0.3.0 and `va108xx-hal` dependency to v0.6.0

View File

@ -1,6 +1,6 @@
[package] [package]
name = "vorago-reb1" name = "vorago-reb1"
version = "0.5.0" version = "0.5.1"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2021" edition = "2021"
description = "Board Support Crate for the Vorago REB1 development board" description = "Board Support Crate for the Vorago REB1 development board"
@ -19,14 +19,13 @@ embedded-hal = "1"
version = "0.3" version = "0.3"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.6" version = "0.7"
features = ["rt"] features = ["rt"]
[features] [features]
rt = ["va108xx-hal/rt"] rt = ["va108xx-hal/rt"]
[dev-dependencies] [dev-dependencies]
cortex-m-rtic = "1.1"
panic-halt = "0.2" panic-halt = "0.2"
nb = "1" nb = "1"
@ -36,6 +35,14 @@ version = "0.5"
[dev-dependencies.panic-rtt-target] [dev-dependencies.panic-rtt-target]
version = "0.1" version = "0.1"
[dev-dependencies.rtic]
version = "2"
features = ["thumbv6-backend"]
[dev-dependencies.rtic-monotonics]
version = "1"
features = ["cortex-m-systick"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docs_rs", "--generate-link-to-definition"] rustdoc-args = ["--generate-link-to-definition"]

View File

@ -6,5 +6,5 @@
This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board. This is the Rust **B**oard **S**upport **P**ackage crate for the Vorago REB1 development board.
Its aim is to provide drivers for the board features of the REB1 board Its aim is to provide drivers for the board features of the REB1 board
The BSP builds on top of the [HAL crate for VA108xx devices](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal). The BSP builds on top of the [HAL crate for VA108xx devices](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/va108xx-hal).
The example folder contains some example applications using the on-board peripherals. The example folder contains some example applications using the on-board peripherals.

View File

@ -13,7 +13,7 @@ fn main() -> ! {
rprintln!("-- Vorago Temperature Sensor and I2C Example --"); rprintln!("-- Vorago Temperature Sensor and I2C Example --");
let mut dp = pac::Peripherals::take().unwrap(); let mut dp = pac::Peripherals::take().unwrap();
let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0); let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0);
let mut temp_sensor = Adt75TempSensor::new(dp.i2ca, 50.MHz(), Some(&mut dp.sysconfig)) let mut temp_sensor = Adt75TempSensor::new(&mut dp.sysconfig, 50.MHz(), dp.i2ca)
.expect("Creating temperature sensor struct failed"); .expect("Creating temperature sensor struct failed");
loop { loop {
let temp = temp_sensor let temp = temp_sensor

View File

@ -52,12 +52,12 @@ fn main() -> ! {
false, false,
true, true,
); );
let mut spi = Spi::spib( let mut spi = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spib, dp.spib,
(sck, miso, mosi), (sck, miso, mosi),
50.MHz(),
spi_cfg, spi_cfg,
Some(&mut dp.sysconfig),
Some(&transfer_cfg.downgrade()), Some(&transfer_cfg.downgrade()),
); );

View File

@ -5,6 +5,7 @@
#[rtic::app(device = pac)] #[rtic::app(device = pac)]
mod app { mod app {
use panic_rtt_target as _; use panic_rtt_target as _;
use rtic_monotonics::systick::Systick;
use rtt_target::{rprintln, rtt_init_default, set_print_channel}; use rtt_target::{rprintln, rtt_init_default, set_print_channel};
use va108xx_hal::{ use va108xx_hal::{
clock::{set_clk_div_register, FilterClkSel}, clock::{set_clk_div_register, FilterClkSel},
@ -43,10 +44,18 @@ mod app {
struct Shared {} struct Shared {}
#[init] #[init]
fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) { fn init(ctx: init::Context) -> (Shared, Local) {
let channels = rtt_init_default!(); let channels = rtt_init_default!();
set_print_channel(channels.up.0); set_print_channel(channels.up.0);
rprintln!("-- Vorago Button IRQ Example --"); rprintln!("-- Vorago Button IRQ Example --");
// Initialize the systick interrupt & obtain the token to prove that we did
let systick_mono_token = rtic_monotonics::create_systick_token!();
Systick::start(
ctx.core.SYST,
Hertz::from(50.MHz()).raw(),
systick_mono_token,
);
let mode = match CFG_MODE { let mode = match CFG_MODE {
// Ask mode from user via RTT // Ask mode from user via RTT
CfgMode::Prompt => prompt_mode(channels.down.0), CfgMode::Prompt => prompt_mode(channels.down.0),
@ -90,7 +99,7 @@ mod app {
50.MHz(), 50.MHz(),
dp.tim0, dp.tim0,
); );
(Shared {}, Local { leds, button, mode }, init::Monotonics()) (Shared {}, Local { leds, button, mode })
} }
// `shared` cannot be accessed from this context // `shared` cannot be accessed from this context

View File

@ -10,7 +10,7 @@ use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs; use embedded_hal::delay::DelayNs;
use embedded_hal::digital::{OutputPin, StatefulOutputPin}; use embedded_hal::digital::{OutputPin, StatefulOutputPin};
use panic_halt as _; use panic_halt as _;
use va108xx_hal::{gpio::pins::PinsA, pac, prelude::*, timer::set_up_ms_delay_provider}; use va108xx_hal::{gpio::PinsA, pac, prelude::*, timer::set_up_ms_delay_provider};
use vorago_reb1::leds::Leds; use vorago_reb1::leds::Leds;
// REB LED pin definitions. All on port A // REB LED pin definitions. All on port A

View File

@ -1,4 +1,7 @@
//! MAX11619 ADC example applikcation //! MAX11619 ADC example application.
//!
//! You can turn the potentiometer knob of the REB1 board to measure
//! different ADC values.
#![no_main] #![no_main]
#![no_std] #![no_std]
@ -139,12 +142,12 @@ fn main() -> ! {
.expect("Setting accelerometer chip select high failed"); .expect("Setting accelerometer chip select high failed");
let transfer_cfg = TransferConfig::<NoneT>::new(3.MHz(), spi::MODE_0, None, true, false); let transfer_cfg = TransferConfig::<NoneT>::new(3.MHz(), spi::MODE_0, None, true, false);
let spi = Spi::spib( let spi = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spib, dp.spib,
(sck, miso, mosi), (sck, miso, mosi),
50.MHz(),
spi_cfg, spi_cfg,
Some(&mut dp.sysconfig),
Some(&transfer_cfg.downgrade()), Some(&transfer_cfg.downgrade()),
) )
.downgrade(); .downgrade();

View File

@ -2,8 +2,8 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [Button Blinky with IRQs](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-irq.rs) //! - [Button Blinky with IRQs](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/blinky-button-irq.rs)
//! - [Button Blinky with IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-rtic.rs) //! - [Button Blinky with IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/blinky-button-rtic.rs)
use embedded_hal::digital::InputPin; use embedded_hal::digital::InputPin;
use va108xx_hal::{ use va108xx_hal::{
gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11}, gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11},

View File

@ -2,13 +2,13 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [LED example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-leds.rs) //! - [LED example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/blinky-leds.rs)
//! - [Button Blinky using IRQs](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-irq.rs) //! - [Button Blinky using IRQs](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/blinky-button-irq.rs)
//! - [Button Blinky using IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/blinky-button-rtic.rs) //! - [Button Blinky using IRQs and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/blinky-button-rtic.rs)
use embedded_hal::digital::OutputPin; use embedded_hal::digital::OutputPin;
use va108xx_hal::{ use va108xx_hal::{
gpio::dynpins::DynPin, gpio::dynpin::DynPin,
gpio::pins::{Pin, PushPullOutput, PA10, PA6, PA7}, gpio::pin::{Pin, PushPullOutput, PA10, PA6, PA7},
}; };
pub type LD2 = Pin<PA10, PushPullOutput>; pub type LD2 = Pin<PA10, PushPullOutput>;

View File

@ -1,5 +1,5 @@
#![no_std] #![no_std]
#![cfg_attr(docs_rs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
pub mod button; pub mod button;
pub mod leds; pub mod leds;

View File

@ -2,7 +2,7 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [ADC example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/max11619-adc.rs) //! - [ADC example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/max11619-adc.rs)
use core::convert::Infallible; use core::convert::Infallible;
use embedded_hal::spi::SpiDevice; use embedded_hal::spi::SpiDevice;
use max116xx_10bit::{ use max116xx_10bit::{

View File

@ -4,10 +4,10 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [Temperature Sensor example](https://egit.irs.uni-stuttgart.de/rust/vorago-reb1/src/branch/main/examples/adt75-temp-sensor.rs) //! - [Temperature Sensor example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/adt75-temp-sensor.rs
use embedded_hal::i2c::{I2c, SevenBitAddress}; use embedded_hal::i2c::{I2c, SevenBitAddress};
use va108xx_hal::{ use va108xx_hal::{
i2c::{Error, I2cMaster, I2cSpeed, MasterConfig}, i2c::{Error, I2cMaster, I2cSpeed, InitError, MasterConfig},
pac, pac,
time::Hertz, time::Hertz,
}; };
@ -29,20 +29,40 @@ pub enum RegAddresses {
OneShot = 0x04, OneShot = 0x04,
} }
#[derive(Debug)]
pub enum AdtInitError {
Init(InitError),
I2c(Error),
}
impl From<InitError> for AdtInitError {
fn from(value: InitError) -> Self {
Self::Init(value)
}
}
impl From<Error> for AdtInitError {
fn from(value: Error) -> Self {
Self::I2c(value)
}
}
impl Adt75TempSensor { impl Adt75TempSensor {
pub fn new( pub fn new(
i2ca: pac::I2ca, sys_cfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz> + Copy, sys_clk: impl Into<Hertz> + Copy,
sys_cfg: Option<&mut pac::Sysconfig>, i2ca: pac::I2ca,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let mut sensor = Adt75TempSensor { let mut sensor = Adt75TempSensor {
sensor_if: I2cMaster::i2ca( // The master construction can not fail for regular I2C speed.
sensor_if: I2cMaster::new(
sys_cfg,
sys_clk,
i2ca, i2ca,
MasterConfig::default(), MasterConfig::default(),
sys_clk,
I2cSpeed::Regular100khz, I2cSpeed::Regular100khz,
sys_cfg, )
), .unwrap(),
cmd_buf: [RegAddresses::Temperature as u8], cmd_buf: [RegAddresses::Temperature as u8],
current_reg: RegAddresses::Temperature, current_reg: RegAddresses::Temperature,
}; };

View File

@ -18,6 +18,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-leds", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-leds",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -28,9 +39,20 @@
"device": "Cortex-M0", "device": "Cortex-M0",
"svdFile": "./va108xx/svd/va108xx.svd.patched", "svdFile": "./va108xx/svd/va108xx.svd.patched",
"preLaunchTask": "rust: cargo build hal tests", "preLaunchTask": "rust: cargo build hal tests",
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/tests", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/board-tests",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -44,6 +66,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/rtt-log", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/rtt-log",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -57,6 +90,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-irq", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-irq",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -70,6 +114,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/timer-ticks", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/timer-ticks",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -83,6 +138,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -96,6 +162,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/spi", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/spi",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -109,11 +186,22 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adt75-temp-sensor", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adt75-temp-sensor",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug Button Blinky RTIC", "name": "Button Blinky RTIC Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -122,11 +210,22 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-rtic", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/blinky-button-rtic",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug PWM", "name": "PWM Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -135,11 +234,22 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/pwm", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/pwm",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug Cascade", "name": "Cascade Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -148,11 +258,22 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/cascade", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/cascade",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug Accelerometer", "name": "Accelerometer Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -161,6 +282,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adxl343-accelerometer", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/adxl343-accelerometer",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
@ -178,7 +310,7 @@
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug ADC", "name": "ADC Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -187,11 +319,22 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/max11619-adc", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/max11619-adc",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
{ {
"type": "cortex-debug", "type": "cortex-debug",
"request": "launch", "request": "launch",
"name": "Debug UART IRQ", "name": "UART IRQ Example",
"servertype": "jlink", "servertype": "jlink",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"device": "Cortex-M0", "device": "Cortex-M0",
@ -200,6 +343,17 @@
"executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart-irq-rtic", "executable": "${workspaceFolder}/target/thumbv6m-none-eabi/debug/examples/uart-irq-rtic",
"interface": "jtag", "interface": "jtag",
"runToEntryPoint": "main", "runToEntryPoint": "main",
"rttConfig": {
"enabled": true,
"address": "0x10000000",
"decoders": [
{
"port": 0,
"timestamp": true,
"type": "console"
}
]
}
}, },
] ]
} }

View File

@ -21,10 +21,8 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--bin", "--bin",
"tests", "board-tests",
"--features", "--features",
"rt" "rt"
], ],
@ -39,8 +37,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"rtt-log", "rtt-log",
], ],
@ -55,8 +51,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"timer-ticks", "timer-ticks",
"--features", "--features",
@ -89,8 +83,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"spi", "spi",
], ],
@ -105,8 +97,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"pwm", "pwm",
"--features", "--features",
@ -123,8 +113,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"cascade", "cascade",
"--features", "--features",
@ -141,8 +129,6 @@
"command": "~/.cargo/bin/cargo", // note: full path to the cargo "command": "~/.cargo/bin/cargo", // note: full path to the cargo
"args": [ "args": [
"build", "build",
"-p",
"va108xx-hal",
"--example", "--example",
"uart-irq-rtic", "uart-irq-rtic",
"--features", "--features",