8 Commits

17 changed files with 82 additions and 44 deletions

View File

@@ -27,7 +27,7 @@ embassy-executor = { version = "0.7", features = [
"executor-interrupt"
]}
va108xx-hal = { path = "../../va108xx-hal" }
va108xx-hal = "0.9"
va108xx-embassy = { path = "../../va108xx-embassy", default-features = false }
[features]

View File

@@ -22,5 +22,5 @@ rtic-sync = { version = "1.3", features = ["defmt-03"] }
once_cell = {version = "1", default-features = false, features = ["critical-section"]}
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
va108xx-hal = { version = "0.9", path = "../../va108xx-hal" }
va108xx-hal = "0.9"
vorago-reb1 = { path = "../../vorago-reb1" }

View File

@@ -16,7 +16,6 @@ embedded-io = "0.6"
cortex-m-semihosting = "0.5.0"
[dependencies.va108xx-hal]
path = "../../va108xx-hal"
version = "0.9"
features = ["rt", "defmt"]

View File

@@ -25,12 +25,6 @@ rustup target add thumbv6m-none-eabi
After that, you can use `cargo build` to build the development version of the crate.
If you have not done this yet, it is recommended to read some of the excellent resources
available to learn Rust:
- [Rust Embedded Book](https://docs.rust-embedded.org/book/)
- [Rust Discovery Book](https://docs.rust-embedded.org/discovery/)
## Setting up your own binary crate
If you have a custom board, you might be interested in setting up a new binary crate for your
@@ -65,3 +59,11 @@ is contained within the
7. Flashing the board might work differently for different boards and there is usually
more than one way. You can find example instructions in primary README.
## Embedded Rust
If you have not done this yet, it is recommended to read some of the excellent resources available
to learn Rust:
- [Rust Embedded Book](https://docs.rust-embedded.org/book/)
- [Rust Discovery Book](https://docs.rust-embedded.org/discovery/)

View File

@@ -11,6 +11,7 @@ static SYS_CLOCK: Mutex<OnceCell<Hertz>> = Mutex::new(OnceCell::new());
pub type PeripheralClocks = PeripheralSelect;
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FilterClkSel {
SysClk = 0,
Clk1 = 1,

View File

@@ -69,6 +69,7 @@ use crate::{clock::FilterClkSel, enable_nvic_interrupt, pac, FunSel, InterruptCo
/// Value-level `enum` for disabled configurations
#[derive(PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DynDisabled {
Floating,
PullDown,
@@ -156,14 +157,16 @@ pub const DYN_ALT_FUNC_3: DynPinMode = DynPinMode::Alternate(DynAlternate::Sel3)
//==================================================================================================
/// Value-level `enum` for pin groups
#[derive(PartialEq, Eq, Clone, Copy)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DynGroup {
A,
B,
}
/// Value-level `struct` representing pin IDs
#[derive(PartialEq, Eq, Clone, Copy)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DynPinId {
pub group: DynGroup,
pub num: u8,
@@ -177,6 +180,7 @@ pub struct DynPinId {
///
/// This `struct` takes ownership of a [`DynPinId`] and provides an API to
/// access the corresponding regsiters.
#[derive(Debug)]
pub(crate) struct DynRegisters(DynPinId);
// [`DynRegisters`] takes ownership of the [`DynPinId`], and [`DynPin`]
@@ -209,6 +213,7 @@ impl DynRegisters {
///
/// This type acts as a type-erased version of [`Pin`]. Every pin is represented
/// by the same type, and pins are tracked and distinguished at run-time.
#[derive(Debug)]
pub struct DynPin {
pub(crate) regs: DynRegisters,
mode: DynPinMode,

View File

@@ -119,8 +119,11 @@ pub trait InputConfig: Sealed {
const DYN: DynInput;
}
#[derive(Debug)]
pub enum Floating {}
#[derive(Debug)]
pub enum PullDown {}
#[derive(Debug)]
pub enum PullUp {}
impl InputConfig for Floating {
@@ -148,6 +151,7 @@ pub type InputPullUp = Input<PullUp>;
///
/// Type `C` is one of three input configurations: [`Floating`], [`PullDown`] or
/// [`PullUp`]
#[derive(Debug)]
pub struct Input<C: InputConfig> {
cfg: PhantomData<C>,
}
@@ -177,13 +181,17 @@ pub trait OutputConfig: Sealed {
pub trait ReadableOutput: Sealed {}
/// Type-level variant of [`OutputConfig`] for a push-pull configuration
#[derive(Debug)]
pub enum PushPull {}
/// Type-level variant of [`OutputConfig`] for an open drain configuration
#[derive(Debug)]
pub enum OpenDrain {}
/// Type-level variant of [`OutputConfig`] for a readable push-pull configuration
#[derive(Debug)]
pub enum ReadablePushPull {}
/// Type-level variant of [`OutputConfig`] for a readable open-drain configuration
#[derive(Debug)]
pub enum ReadableOpenDrain {}
impl Sealed for PushPull {}
@@ -210,6 +218,7 @@ impl OutputConfig for ReadableOpenDrain {
///
/// Type `C` is one of four output configurations: [`PushPull`], [`OpenDrain`] or
/// their respective readable versions
#[derive(Debug)]
pub struct Output<C: OutputConfig> {
cfg: PhantomData<C>,
}
@@ -304,6 +313,7 @@ macro_rules! pin_id {
// Need paste macro to use ident in doc attribute
paste! {
#[doc = "Pin ID representing pin " $Id]
#[derive(Debug)]
pub enum $Id {}
impl Sealed for $Id {}
impl PinId for $Id {
@@ -321,6 +331,7 @@ macro_rules! pin_id {
//==================================================================================================
/// A type-level GPIO pin, parameterized by [PinId] and [PinMode] types
#[derive(Debug)]
pub struct Pin<I: PinId, M: PinMode> {
inner: DynPin,
phantom: PhantomData<(I, M)>,
@@ -741,6 +752,7 @@ macro_rules! pins {
) => {
paste!(
/// Collection of all the individual [`Pin`]s for a given port (PORTA or PORTB)
#[derive(Debug)]
pub struct $PinsName {
port: $Port,
$(

View File

@@ -18,6 +18,7 @@ const CLK_400K: Hertz = Hertz::from_raw(400_000);
const MIN_CLK_400K: Hertz = Hertz::from_raw(8_000_000);
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FifoEmptyMode {
Stall = 0,
EndTransaction = 1,
@@ -89,18 +90,21 @@ enum I2cCmd {
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum I2cSpeed {
Regular100khz = 0,
Fast400khz = 1,
}
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum I2cDirection {
Send = 0,
Read = 1,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum I2cAddress {
Regular(u8),
TenBit(u16),
@@ -141,9 +145,12 @@ impl Instance for pac::I2cb {
// Config
//==================================================================================================
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct TrTfThighTlow(u8, u8, u8, u8);
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct TsuStoTsuStaThdStaTBuf(u8, u8, u8, u8);
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct TimingCfg {
// 4 bit max width
tr: u8,
@@ -218,6 +225,7 @@ impl Default for TimingCfg {
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct MasterConfig {
pub tx_fe_mode: FifoEmptyMode,
pub rx_fe_mode: FifoEmptyMode,

View File

@@ -77,6 +77,7 @@ impl InterruptConfig {
pub type IrqCfg = InterruptConfig;
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InvalidPin(pub(crate) ());
/// Can be used to manually manipulate the function select of port pins

View File

@@ -15,7 +15,9 @@ use crate::{clock::enable_peripheral_clock, gpio::DynPinId};
const DUTY_MAX: u16 = u16::MAX;
pub struct PwmCommon {
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub(crate) struct PwmCommon {
sys_clk: Hertz,
/// For PWMB, this is the upper limit
current_duty: u16,

View File

@@ -37,6 +37,7 @@ pub const BMSTART_BMSTOP_MASK: u32 = 1 << 31;
pub const DEFAULT_CLK_DIV: u16 = 2;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum HwChipSelectId {
Id0 = 0,
Id1 = 1,
@@ -50,6 +51,7 @@ pub enum HwChipSelectId {
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SpiPort {
Porta = 0,
Portb = 1,
@@ -58,6 +60,7 @@ pub enum SpiPort {
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum WordSize {
OneBit = 0x00,
FourBits = 0x03,

View File

@@ -79,6 +79,7 @@ pub enum Event {
}
#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CascadeCtrl {
/// Enable Cascade 0 signal active as a requirement for counting
pub enb_start_src_csd0: bool,
@@ -108,6 +109,7 @@ pub struct CascadeCtrl {
}
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CascadeSel {
Csd0 = 0,
Csd1 = 1,

View File

@@ -23,6 +23,7 @@ use crate::{
use embedded_hal_nb::serial::Read;
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Bank {
A = 0,
B = 1,
@@ -237,6 +238,7 @@ impl From<Hertz> for Config {
//==================================================================================================
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct IrqContextTimeoutOrMaxSize {
rx_idx: usize,
mode: IrqReceptionMode,
@@ -262,6 +264,7 @@ impl IrqContextTimeoutOrMaxSize {
/// This struct is used to return the default IRQ handler result to the user
#[derive(Debug, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct IrqResult {
pub bytes_read: usize,
pub errors: Option<UartErrors>,
@@ -269,6 +272,7 @@ pub struct IrqResult {
/// This struct is used to return the default IRQ handler result to the user
#[derive(Debug, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct IrqResultMaxSizeOrTimeout {
complete: bool,
timeout: bool,
@@ -319,6 +323,7 @@ impl IrqResultMaxSizeOrTimeout {
}
#[derive(Debug, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum IrqReceptionMode {
Idle,
Pending,
@@ -407,7 +412,7 @@ impl Instance for pac::Uarta {
}
#[inline(always)]
fn ptr() -> *const uart_base::RegisterBlock {
pac::Uarta::ptr() as *const _
Self::ptr() as *const _
}
}
@@ -422,7 +427,7 @@ impl Instance for pac::Uartb {
}
#[inline(always)]
fn ptr() -> *const uart_base::RegisterBlock {
pac::Uartb::ptr() as *const _
Self::ptr() as *const _
}
}

View File

@@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v0.7.0] 2025-02-13
- Bumped `va108xx-hal` dependency to 0.9
- Minor adjustments to `Button` API.
- `Button`, `Led` and `Leds` now simply wrap a type using a tuple struct.
## [v0.6.0] 2024-09-30
- Added M95M01 EEPROM module/API

View File

@@ -1,6 +1,6 @@
[package]
name = "vorago-reb1"
version = "0.6.0"
version = "0.7.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2021"
description = "Board Support Crate for the Vorago REB1 development board"
@@ -19,7 +19,6 @@ bitfield = ">=0.17, <=0.18"
max116xx-10bit = "0.3"
[dependencies.va108xx-hal]
path = "../va108xx-hal"
version = "0.9"
features = ["rt"]

View File

@@ -10,23 +10,22 @@ use va108xx_hal::{
pac, InterruptConfig,
};
pub struct Button {
button: Pin<PA11, InputFloating>,
}
#[derive(Debug)]
pub struct Button(pub Pin<PA11, InputFloating>);
impl Button {
pub fn new(pin: Pin<PA11, InputFloating>) -> Button {
Button { button: pin }
Button(pin)
}
#[inline]
pub fn pressed(&mut self) -> bool {
self.button.is_low().ok().unwrap()
self.0.is_low().ok().unwrap()
}
#[inline]
pub fn released(&mut self) -> bool {
self.button.is_high().ok().unwrap()
self.0.is_high().ok().unwrap()
}
/// Configures an IRQ on edge.
@@ -37,7 +36,7 @@ impl Button {
syscfg: Option<&mut pac::Sysconfig>,
irqsel: Option<&mut pac::Irqsel>,
) {
self.button
self.0
.configure_edge_interrupt(edge_type, irq_cfg, syscfg, irqsel);
}
@@ -49,7 +48,7 @@ impl Button {
syscfg: Option<&mut pac::Sysconfig>,
irqsel: Option<&mut pac::Irqsel>,
) {
self.button
self.0
.configure_level_interrupt(level, irq_cfg, syscfg, irqsel);
}
@@ -58,6 +57,6 @@ impl Button {
/// Please note that you still have to set a clock divisor yourself using the
/// [`va108xx_hal::clock::set_clk_div_register`] function in order for this to work.
pub fn configure_filter_type(&mut self, filter: FilterType, clksel: FilterClkSel) {
self.button.configure_filter_type(filter, clksel);
self.0.configure_filter_type(filter, clksel);
}
}

View File

@@ -15,15 +15,12 @@ pub type LD2 = Pin<PA10, PushPullOutput>;
pub type LD3 = Pin<PA7, PushPullOutput>;
pub type LD4 = Pin<PA6, PushPullOutput>;
pub struct Leds {
leds: [Led; 3],
}
#[derive(Debug)]
pub struct Leds(pub [Led; 3]);
impl Leds {
pub fn new(led_pin1: LD2, led_pin2: LD3, led_pin3: LD4) -> Leds {
Leds {
leds: [led_pin1.into(), led_pin2.into(), led_pin3.into()],
}
Leds([led_pin1.into(), led_pin2.into(), led_pin3.into()])
}
}
@@ -31,13 +28,13 @@ impl core::ops::Deref for Leds {
type Target = [Led];
fn deref(&self) -> &[Led] {
&self.leds
&self.0
}
}
impl core::ops::DerefMut for Leds {
fn deref_mut(&mut self) -> &mut [Led] {
&mut self.leds
&mut self.0
}
}
@@ -45,28 +42,25 @@ impl core::ops::Index<usize> for Leds {
type Output = Led;
fn index(&self, i: usize) -> &Led {
&self.leds[i]
&self.0[i]
}
}
impl core::ops::IndexMut<usize> for Leds {
fn index_mut(&mut self, i: usize) -> &mut Led {
&mut self.leds[i]
&mut self.0[i]
}
}
pub struct Led {
pin: DynPin,
}
#[derive(Debug)]
pub struct Led(pub DynPin);
macro_rules! ctor {
($($ldx:ident),+) => {
$(
impl From<$ldx> for Led {
fn from(led: $ldx) -> Self {
Led {
pin: led.into()
}
Led(led.into())
}
}
)+
@@ -79,18 +73,18 @@ impl Led {
/// Turns the LED off. Setting the pin high actually turns the LED off
#[inline]
pub fn off(&mut self) {
self.pin.set_high().ok();
self.0.set_high().ok();
}
/// Turns the LED on. Setting the pin low actually turns the LED on
#[inline]
pub fn on(&mut self) {
self.pin.set_low().ok();
self.0.set_low().ok();
}
/// Toggles the LED
#[inline]
pub fn toggle(&mut self) {
self.pin.toggle_with_toggle_reg().ok();
self.0.toggle_with_toggle_reg().ok();
}
}