Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c439bfff29 | |||
| 1b98de324e | |||
| dc31996c34 | |||
|
afe11f9589
|
|||
|
1e6779fa66
|
|||
| 1251f33865 | |||
| 62e95972e0 |
@@ -13,7 +13,7 @@ jobs:
|
||||
- run: cargo check --target thumbv7em-none-eabihf
|
||||
- run: cargo check --target thumbv7em-none-eabihf --examples
|
||||
- run: cargo check -p va416xx --target thumbv7em-none-eabihf --all-features
|
||||
- run: cargo check -p va416xx-hal --target thumbv7em-none-eabihf --examples --features "defmt va41630"
|
||||
- run: cargo check -p va416xx-hal --target thumbv7em-none-eabihf --features "defmt va41630"
|
||||
|
||||
test:
|
||||
name: Run Tests
|
||||
|
||||
@@ -56,10 +56,27 @@ cp -rT vscode .vscode
|
||||
|
||||
You can then adapt the files in `.vscode` to your needs.
|
||||
|
||||
## Building projects
|
||||
|
||||
Building an application requires the `thumbv7em-none-eabihf` cross-compiler toolchain.
|
||||
If you have not installed it yet, you can do so with
|
||||
|
||||
```sh
|
||||
rustup target add thumbv7em-none-eabihf
|
||||
```
|
||||
|
||||
After that, you can use `cargo build` to build the development version of the crate.
|
||||
For example, you can use
|
||||
|
||||
```sh
|
||||
cargo build --example blinky
|
||||
```
|
||||
|
||||
to build a simple blinky app.
|
||||
|
||||
## Flashing, running and debugging the software
|
||||
|
||||
You can use CLI or VS Code for flashing, running and debugging. In any case, take
|
||||
care of installing the pre-requisites first.
|
||||
You can use CLI or VS Code for flashing, running and debugging.
|
||||
|
||||
### Using CLI with probe-rs
|
||||
|
||||
@@ -80,17 +97,14 @@ available for persistent flashing.
|
||||
Runner configuration is available in the `.cargo/def-config.toml` file to use `probe-rs` for
|
||||
convenience. `probe-rs` is also able to process and display `defmt` strings directly.
|
||||
|
||||
### Pre-Requisites
|
||||
### Using VS Code
|
||||
|
||||
Following tools are required:
|
||||
|
||||
1. [SEGGER J-Link tools](https://www.segger.com/downloads/jlink/) installed
|
||||
2. [gdb-multiarch](https://packages.debian.org/sid/gdb-multiarch) or similar
|
||||
cross-architecture debugger installed. All commands here assume `gdb-multiarch`.
|
||||
|
||||
### Using CLI
|
||||
|
||||
|
||||
### Using VS Code
|
||||
|
||||
Assuming a working debug connection to your VA416xx board, you can debug using VS Code with
|
||||
the [`Cortex-Debug` plugin](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug).
|
||||
Please make sure that [`objdump-multiarch` and `nm-multiarch`](https://forums.raspberrypi.com/viewtopic.php?t=333146)
|
||||
@@ -114,7 +128,7 @@ work properly, `objdump-multiarch` and `nm-multiarch` need to be installed.
|
||||
|
||||
### Using CLI with GDB and Segger J-Link Tools
|
||||
|
||||
Install the following two tools first:
|
||||
Following tools are required:
|
||||
|
||||
1. [SEGGER J-Link tools](https://www.segger.com/downloads/jlink/) installed
|
||||
2. [gdb-multiarch](https://packages.debian.org/sid/gdb-multiarch) or similar
|
||||
|
||||
@@ -13,6 +13,6 @@ crc = "3"
|
||||
static_assertions = "1"
|
||||
|
||||
[dependencies.va416xx-hal]
|
||||
version = "0.5"
|
||||
version = "0.6"
|
||||
features = ["va41630", "defmt"]
|
||||
path = "../va416xx-hal"
|
||||
|
||||
@@ -10,7 +10,7 @@ use crc::{Crc, CRC_32_ISO_HDLC};
|
||||
use defmt_rtt as _;
|
||||
use panic_probe as _;
|
||||
use va416xx_hal::{
|
||||
clock::{pll_setup_delay, ClkDivSel, ClkselSys, ClockConfigurator},
|
||||
clock::{pll_setup_delay, ClockConfigurator, ClockDivisorSelect, ClockSelect},
|
||||
edac,
|
||||
nvm::Nvm,
|
||||
pac::{self, interrupt},
|
||||
@@ -266,11 +266,11 @@ fn boot_app(app_sel: AppSel, cp: &cortex_m::Peripherals) -> ! {
|
||||
let clkgen = unsafe { pac::Clkgen::steal() };
|
||||
clkgen
|
||||
.ctrl0()
|
||||
.modify(|_, w| unsafe { w.clksel_sys().bits(ClkselSys::Hbo as u8) });
|
||||
.modify(|_, w| unsafe { w.clksel_sys().bits(ClockSelect::Hbo as u8) });
|
||||
pll_setup_delay();
|
||||
clkgen
|
||||
.ctrl0()
|
||||
.modify(|_, w| unsafe { w.clk_div_sel().bits(ClkDivSel::Div1 as u8) });
|
||||
.modify(|_, w| unsafe { w.clk_div_sel().bits(ClockDivisorSelect::Div1 as u8) });
|
||||
// Clear all interrupts set.
|
||||
unsafe {
|
||||
cp.NVIC.icer[0].write(0xFFFFFFFF);
|
||||
|
||||
@@ -11,7 +11,7 @@ embedded-io = "0.6"
|
||||
embedded-hal-async = "1"
|
||||
embedded-io-async = "0.6"
|
||||
|
||||
heapless = "0.8"
|
||||
heapless = "0.9"
|
||||
defmt-rtt = "1"
|
||||
defmt = "1"
|
||||
panic-probe = { version = "1", features = ["print-defmt"] }
|
||||
@@ -21,14 +21,14 @@ ringbuf = { version = "0.4", default-features = false }
|
||||
|
||||
nb = "1"
|
||||
embassy-sync = "0.7"
|
||||
embassy-time = "0.4"
|
||||
embassy-executor = { version = "0.7", features = [
|
||||
embassy-time = "0.5"
|
||||
embassy-executor = { version = "0.9", features = [
|
||||
"arch-cortex-m",
|
||||
"executor-thread",
|
||||
"executor-interrupt"
|
||||
]}
|
||||
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["defmt"] }
|
||||
va416xx-hal = { version = "0.6", path = "../../va416xx-hal", features = ["defmt"] }
|
||||
va416xx-embassy = { version = "0.1", path = "../../va416xx-embassy", default-features = false }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -42,7 +42,7 @@ use va416xx_hal::{
|
||||
|
||||
static QUEUE_UART_A: static_cell::ConstStaticCell<Queue<u8, 256>> =
|
||||
static_cell::ConstStaticCell::new(Queue::new());
|
||||
static PRODUCER_UART_A: Mutex<RefCell<Option<Producer<u8, 256>>>> = Mutex::new(RefCell::new(None));
|
||||
static PRODUCER_UART_A: Mutex<RefCell<Option<Producer<u8>>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
|
||||
@@ -9,7 +9,7 @@ defmt-rtt = "1"
|
||||
defmt = "1"
|
||||
panic-probe = { version = "1", features = ["defmt"] }
|
||||
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["va41630"] }
|
||||
va416xx-hal = { version = "0.6", path = "../../va416xx-hal", features = ["va41630"] }
|
||||
|
||||
[dependencies.rtic]
|
||||
version = "2"
|
||||
|
||||
@@ -17,7 +17,7 @@ embedded-io = "0.6"
|
||||
panic-halt = "1"
|
||||
accelerometer = "0.12"
|
||||
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["va41630", "defmt"] }
|
||||
va416xx-hal = { version = "0.6", path = "../../va416xx-hal", features = ["va41630", "defmt"] }
|
||||
|
||||
[dependencies.vorago-peb1]
|
||||
path = "../../vorago-peb1"
|
||||
|
||||
@@ -14,7 +14,7 @@ use cortex_m_rt::entry;
|
||||
use critical_section::Mutex;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::dma::{Dma, DmaCfg, DmaChannel, DmaCtrlBlock};
|
||||
use va416xx_hal::dma::{Dma, DmaChannel, DmaConfig, DmaCtrlBlock};
|
||||
use va416xx_hal::irq_router::enable_and_init_irq_router;
|
||||
use va416xx_hal::pac::{self, interrupt};
|
||||
use va416xx_hal::timer::CountdownTimer;
|
||||
@@ -49,7 +49,7 @@ fn main() -> ! {
|
||||
// statically.
|
||||
let dma = Dma::new(
|
||||
dp.dma,
|
||||
DmaCfg::default(),
|
||||
DmaConfig::default(),
|
||||
core::ptr::addr_of_mut!(DMA_CTRL_BLOCK),
|
||||
)
|
||||
.expect("error creating DMA");
|
||||
|
||||
@@ -13,7 +13,7 @@ use cortex_m_rt::entry;
|
||||
use embedded_hal::spi::{Mode, SpiBus, MODE_0};
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
use va416xx_hal::spi::{Spi, SpiClkConfig};
|
||||
use va416xx_hal::spi::{Spi, SpiClockConfig};
|
||||
use va416xx_hal::timer::CountdownTimer;
|
||||
use va416xx_hal::{
|
||||
pac,
|
||||
@@ -52,7 +52,7 @@ fn main() -> ! {
|
||||
|
||||
let mut spi_cfg = SpiConfig::default()
|
||||
.clk_cfg(
|
||||
SpiClkConfig::from_clks(&clocks, Hertz::from_raw(SPI_SPEED_KHZ))
|
||||
SpiClockConfig::from_clks(&clocks, Hertz::from_raw(SPI_SPEED_KHZ))
|
||||
.expect("invalid target clock"),
|
||||
)
|
||||
.mode(SPI_MODE)
|
||||
|
||||
@@ -16,7 +16,7 @@ once_cell = { version = "1", default-features = false, features = ["critical-sec
|
||||
spacepackets = { version = "0.15", default-features = false, features = ["defmt"] }
|
||||
cobs = { version = "0.4", default-features = false }
|
||||
|
||||
va416xx-hal = { version = "0.5", features = ["va41630", "defmt"], path = "../va416xx-hal" }
|
||||
va416xx-hal = { version = "0.6", features = ["va41630", "defmt"], path = "../va416xx-hal" }
|
||||
|
||||
rtic = { version = "2", features = ["thumbv7-backend"] }
|
||||
rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
|
||||
|
||||
@@ -7,8 +7,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cortex-m-rt = "0.7"
|
||||
panic-rtt-target = { version = "0.1.3" }
|
||||
rtt-target = { version = "0.5" }
|
||||
panic-rtt-target = { version = "0.2" }
|
||||
rtt-target = { version = "0.6" }
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
embedded-hal = "1"
|
||||
va416xx-hal = { path = "0.4", features = ["va41630"] }
|
||||
|
||||
@@ -7,8 +7,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cortex-m-rt = "0.7"
|
||||
panic-rtt-target = { version = "0.1.3" }
|
||||
rtt-target = { version = "0.5" }
|
||||
panic-rtt-target = { version = "0.2" }
|
||||
rtt-target = { version = "0.6" }
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
embedded-hal = "1"
|
||||
va416xx-hal = { path = "0.4", features = ["va41630"] }
|
||||
|
||||
@@ -108,7 +108,7 @@ mod app {
|
||||
};
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
use va416xx_hal::irq_router::enable_and_init_irq_router;
|
||||
use va416xx_hal::uart::IrqContextTimeoutOrMaxSize;
|
||||
use va416xx_hal::uart::InterruptContextTimeoutOrMaxSize;
|
||||
use va416xx_hal::{
|
||||
edac,
|
||||
nvm::Nvm,
|
||||
@@ -131,7 +131,7 @@ mod app {
|
||||
struct Local {
|
||||
uart_rx: uart::RxWithInterrupt,
|
||||
uart_tx: uart::Tx,
|
||||
rx_context: IrqContextTimeoutOrMaxSize,
|
||||
rx_context: InterruptContextTimeoutOrMaxSize,
|
||||
rom_spi: Option<pac::Spi3>,
|
||||
// We handle all TM in one task.
|
||||
tm_cons: DataConsumer<BUF_RB_SIZE_TM, SIZES_RB_SIZE_TM>,
|
||||
@@ -195,7 +195,7 @@ mod app {
|
||||
CLOCKS.set(clocks).unwrap();
|
||||
|
||||
let mut rx = rx.into_rx_with_irq();
|
||||
let mut rx_context = IrqContextTimeoutOrMaxSize::new(MAX_TC_FRAME_SIZE);
|
||||
let mut rx_context = InterruptContextTimeoutOrMaxSize::new(MAX_TC_FRAME_SIZE);
|
||||
rx.read_fixed_len_or_timeout_based_using_irq(&mut rx_context)
|
||||
.expect("initiating UART RX failed");
|
||||
pus_tc_handler::spawn().unwrap();
|
||||
|
||||
@@ -11,7 +11,7 @@ keywords = ["no-std", "hal", "cortex-m", "vorago", "va416xx"]
|
||||
categories = ["aerospace", "embedded", "no-std", "hardware-support"]
|
||||
|
||||
[dependencies]
|
||||
vorago-shared-periphs = { git = "https://egit.irs.uni-stuttgart.de/rust/vorago-shared-periphs.git", rev = "c8e475cbba820a4b235b46f3d284e23d72396855", features = ["vor4x"] }
|
||||
vorago-shared-hal = { version = "0.2", features = ["vor4x"] }
|
||||
va416xx-hal = { path = "../va416xx-hal" }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -42,9 +42,9 @@ use va416xx_hal::{
|
||||
clock::Clocks,
|
||||
irq_router::enable_and_init_irq_router,
|
||||
pac::{self, interrupt},
|
||||
timer::{TimMarker, TIM_IRQ_OFFSET},
|
||||
timer::{TimInstance, TIM_IRQ_OFFSET},
|
||||
};
|
||||
use vorago_shared_periphs::embassy::time_driver;
|
||||
use vorago_shared_hal::embassy::time_driver;
|
||||
|
||||
/// Macro to define the IRQ handlers for the time driver.
|
||||
///
|
||||
@@ -95,7 +95,7 @@ embassy_time_driver_irqs!(timekeeper_irq = TIM23, alarm_irq = TIM22);
|
||||
/// used TIM peripherals has to match the ID of the passed timer peripherals. Currently, this
|
||||
/// can only be checked at run-time, and a run-time assertion will panic on the embassy
|
||||
/// initialization in case of a missmatch.
|
||||
pub fn init<TimekeeperTim: TimMarker, AlarmTim: TimMarker>(
|
||||
pub fn init<TimekeeperTim: TimInstance, AlarmTim: TimInstance>(
|
||||
timekeeper: TimekeeperTim,
|
||||
alarm: AlarmTim,
|
||||
clocks: &Clocks,
|
||||
|
||||
@@ -8,6 +8,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v0.6.0] 2025-09-03
|
||||
|
||||
- Use `vorago-shared-hal` dependency to provide shared peripherals.
|
||||
- Bump `va416xx` to v0.5
|
||||
|
||||
## Changed
|
||||
|
||||
- Replaced `*Cfg`, `*Clk`, `*Sel` abbreviations in names by written out variant.
|
||||
|
||||
# [v0.5.1] 2025-03-10
|
||||
|
||||
## Fixed
|
||||
@@ -118,7 +127,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- Initial release with basic HAL drivers
|
||||
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.5.0...HEAD
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.6.0...HEAD
|
||||
[v0.6.0]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.5.1...va416xx-hal-v0.6.0
|
||||
[v0.5.1]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.5.0...va416xx-hal-v0.5.1
|
||||
[v0.5.0]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.4.1...va416xx-hal-v0.5.0
|
||||
[v0.4.1]: https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/compare/va416xx-hal-v0.4.0...va416xx-hal-v0.4.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "va416xx-hal"
|
||||
version = "0.5.1"
|
||||
version = "0.6.0"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
edition = "2021"
|
||||
description = "HAL for the Vorago VA416xx family of MCUs"
|
||||
@@ -12,10 +12,10 @@ categories = ["embedded", "no-std", "hardware-support"]
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
va416xx = { version = "0.4", features = ["critical-section"], default-features = false }
|
||||
derive-mmio = { git = "https://github.com/knurling-rs/derive-mmio.git", version = "0.6" }
|
||||
va416xx = { version = "0.5", features = ["critical-section"], default-features = false }
|
||||
derive-mmio = "0.6.1"
|
||||
static_assertions = "1.1"
|
||||
vorago-shared-periphs = { git = "https://egit.irs.uni-stuttgart.de/rust/vorago-shared-periphs.git", rev = "c8e475cbba820a4b235b46f3d284e23d72396855", features = ["vor4x"] }
|
||||
vorago-shared-hal = { version = "0.2", features = ["vor4x"] }
|
||||
|
||||
libm = "0.2"
|
||||
nb = "1"
|
||||
@@ -23,7 +23,7 @@ embedded-hal = "1"
|
||||
num_enum = { version = "0.7", default-features = false }
|
||||
bitflags = "2"
|
||||
bitbybit = "1.3"
|
||||
arbitrary-int = "1.3"
|
||||
arbitrary-int = "2"
|
||||
fugit = "0.3"
|
||||
embedded-can = "0.4"
|
||||
embassy-sync = "0.7"
|
||||
@@ -35,13 +35,13 @@ defmt = { version = "1", optional = true }
|
||||
default = ["rt", "revb"]
|
||||
rt = ["va416xx/rt"]
|
||||
alloc = []
|
||||
defmt = ["dep:defmt", "fugit/defmt", "vorago-shared-periphs/defmt"]
|
||||
defmt = ["dep:defmt", "fugit/defmt", "vorago-shared-hal/defmt"]
|
||||
|
||||
va41630 = ["device-selected"]
|
||||
va41620 = ["device-selected"]
|
||||
|
||||
va41629 = ["device-selected"]
|
||||
va41628 = ["device-selected", "vorago-shared-periphs/va41628"]
|
||||
va41628 = ["device-selected", "vorago-shared-hal/va41628"]
|
||||
|
||||
device-selected = []
|
||||
revb = []
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::clock::Clocks;
|
||||
use crate::pac;
|
||||
use crate::time::Hertz;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use vorago_shared_periphs::{enable_peripheral_clock, PeripheralSelect};
|
||||
use vorago_shared_hal::{enable_peripheral_clock, PeripheralSelect};
|
||||
|
||||
pub const ADC_MIN_CLK: Hertz = Hertz::from_raw(2_000_000);
|
||||
pub const ADC_MAX_CLK: Hertz = Hertz::from_raw(12_500_000);
|
||||
@@ -54,6 +54,7 @@ pub enum ChannelSelect {
|
||||
bitflags::bitflags! {
|
||||
/// This structure is used by the ADC multi-select API to
|
||||
/// allow selecting multiple channels in a convenient manner.
|
||||
#[derive(Debug)]
|
||||
pub struct MultiChannelSelect: u16 {
|
||||
const AnIn0 = 1;
|
||||
const AnIn1 = 1 << 1;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use arbitrary_int::{u11, u15, u3, u4, Number};
|
||||
use arbitrary_int::{prelude::*, u11, u15, u3, u4};
|
||||
use embedded_can::Frame;
|
||||
|
||||
use super::{
|
||||
regs::{
|
||||
self, BaseId, BufStatusAndControl, BufferState, ExtendedId, MmioCanMsgBuf, TwoBytesData,
|
||||
self, BaseId, BufStatusAndControl, BufferState, ExtendedId, MmioCanMessageBuffer,
|
||||
TwoBytesData,
|
||||
},
|
||||
CanFrame, CanFrameNormal, CanFrameRtr, CanId, InvalidBufferIndexError,
|
||||
};
|
||||
@@ -12,7 +13,7 @@ pub struct CanChannelLowLevel {
|
||||
id: CanId,
|
||||
/// Message buffer index.
|
||||
idx: usize,
|
||||
msg_buf: MmioCanMsgBuf<'static>,
|
||||
msg_buf: MmioCanMessageBuffer<'static>,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for CanChannelLowLevel {
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
//! - [CAN example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/embassy/src/bin/can.rs)
|
||||
use core::sync::atomic::AtomicBool;
|
||||
|
||||
use arbitrary_int::{u11, u15, u2, u3, u4, u7, Number};
|
||||
use arbitrary_int::{prelude::*, u11, u15, u2, u3, u4, u7};
|
||||
use embedded_can::Frame;
|
||||
use ll::CanChannelLowLevel;
|
||||
use regs::{BaseId, BufferState, Control, MmioCan, TimingConfig};
|
||||
use vorago_shared_periphs::enable_nvic_interrupt;
|
||||
use vorago_shared_hal::enable_nvic_interrupt;
|
||||
|
||||
use crate::{clock::Clocks, enable_peripheral_clock, time::Hertz, PeripheralSelect};
|
||||
use libm::roundf;
|
||||
@@ -50,6 +50,7 @@ pub const MAX_BITRATE_DEVIATION: f32 = 0.005;
|
||||
static CHANNELS_TAKEN: [AtomicBool; 2] = [AtomicBool::new(false), AtomicBool::new(false)];
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum CanId {
|
||||
Can0 = 0,
|
||||
Can1 = 1,
|
||||
@@ -85,6 +86,7 @@ pub const fn calculate_sample_point(tseg1: u8, tseg2: u8) -> f32 {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct ClockConfig {
|
||||
prescaler: u8,
|
||||
tseg1: u8,
|
||||
@@ -280,19 +282,19 @@ pub const fn calculate_bitrate_deviation(actual_bitrate: f32, target_bitrate: He
|
||||
(actual_bitrate - target_bitrate.raw() as f32).abs() / target_bitrate.raw() as f32
|
||||
}
|
||||
|
||||
pub trait CanMarker {
|
||||
pub trait CanInstance {
|
||||
const ID: CanId;
|
||||
const IRQ: va416xx::Interrupt;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
impl CanMarker for va416xx::Can0 {
|
||||
impl CanInstance for va416xx::Can0 {
|
||||
const ID: CanId = CanId::Can0;
|
||||
const IRQ: va416xx::Interrupt = va416xx::Interrupt::CAN0;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Can0;
|
||||
}
|
||||
|
||||
impl CanMarker for va416xx::Can1 {
|
||||
impl CanInstance for va416xx::Can1 {
|
||||
const ID: CanId = CanId::Can1;
|
||||
const IRQ: va416xx::Interrupt = va416xx::Interrupt::CAN1;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Can1;
|
||||
@@ -310,12 +312,14 @@ pub struct InvalidSjwError(u8);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("invalid sample point {sample_point}")]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct InvalidSamplePointError {
|
||||
/// Sample point, should be larger than 0.5 (50 %) but was not.
|
||||
sample_point: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum ClockConfigError {
|
||||
#[error("invalid sjw: {0}")]
|
||||
InvalidSjw(#[from] InvalidSjwError),
|
||||
@@ -342,7 +346,7 @@ pub struct Can {
|
||||
}
|
||||
|
||||
impl Can {
|
||||
pub fn new<CanI: CanMarker>(_can: CanI, clk_config: ClockConfig) -> Self {
|
||||
pub fn new<CanI: CanInstance>(_can: CanI, clk_config: ClockConfig) -> Self {
|
||||
enable_peripheral_clock(CanI::PERIPH_SEL);
|
||||
let id = CanI::ID;
|
||||
let mut regs = if id == CanId::Can0 {
|
||||
|
||||
+18
-54
@@ -1,7 +1,7 @@
|
||||
//! Custom register definitions for the CAN register block to circumvent PAC API / SVD
|
||||
//! shortcomings.
|
||||
|
||||
use arbitrary_int::{u11, u15, u2, u3, u4, u6, u7, Number};
|
||||
use arbitrary_int::{prelude::*, u11, u15, u2, u3, u4, u6, u7};
|
||||
|
||||
pub const CAN_0_BASE: usize = 0x4001_4000;
|
||||
pub const CAN_1_BASE: usize = 0x4001_4400;
|
||||
@@ -37,8 +37,7 @@ pub enum BufferState {
|
||||
}
|
||||
|
||||
/// Status control register for individual message buffers.
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_fields(feature = "defmt"))]
|
||||
pub struct BufStatusAndControl {
|
||||
/// Data length code.
|
||||
#[bits(12..=15, rw)]
|
||||
@@ -65,8 +64,7 @@ impl Timestamp {
|
||||
}
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct TwoBytesData {
|
||||
#[bits(0..=7, rw)]
|
||||
data_lower_byte: u8,
|
||||
@@ -76,7 +74,7 @@ pub struct TwoBytesData {
|
||||
|
||||
#[derive(derive_mmio::Mmio)]
|
||||
#[repr(C)]
|
||||
pub struct CanMsgBuf {
|
||||
pub struct CanMessageBuffer {
|
||||
stat_ctrl: BufStatusAndControl,
|
||||
timestamp: Timestamp,
|
||||
data3: TwoBytesData,
|
||||
@@ -87,9 +85,9 @@ pub struct CanMsgBuf {
|
||||
id1: BaseId,
|
||||
}
|
||||
|
||||
static_assertions::const_assert_eq!(core::mem::size_of::<CanMsgBuf>(), 0x20);
|
||||
static_assertions::const_assert_eq!(core::mem::size_of::<CanMessageBuffer>(), 0x20);
|
||||
|
||||
impl MmioCanMsgBuf<'_> {
|
||||
impl MmioCanMessageBuffer<'_> {
|
||||
pub fn reset(&mut self) {
|
||||
self.write_stat_ctrl(BufStatusAndControl::new_with_raw_value(0));
|
||||
self.write_timestamp(Timestamp::new(0));
|
||||
@@ -104,6 +102,7 @@ impl MmioCanMsgBuf<'_> {
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum PinLogicLevel {
|
||||
DominantIsZero = 0b0,
|
||||
DominantIsOne = 0b1,
|
||||
@@ -111,6 +110,7 @@ pub enum PinLogicLevel {
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum ErrorInterruptType {
|
||||
/// EIPND bit is set on every error.
|
||||
EveryError = 0b0,
|
||||
@@ -121,12 +121,13 @@ pub enum ErrorInterruptType {
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum DataDirection {
|
||||
FirstByteAtHighestAddr = 0b0,
|
||||
LastByteAtHighestAddr = 0b1,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
|
||||
pub struct Control {
|
||||
#[bit(11, rw)]
|
||||
error_interrupt_type: ErrorInterruptType,
|
||||
@@ -160,8 +161,7 @@ pub struct Control {
|
||||
enable: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct TimingConfig {
|
||||
#[bits(0..=2, rw)]
|
||||
tseg2: u3,
|
||||
@@ -209,9 +209,7 @@ pub enum CanInterruptId {
|
||||
Buffer(usize),
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct StatusPending {
|
||||
#[bits(5..=7, r)]
|
||||
ns: u3,
|
||||
@@ -237,8 +235,7 @@ impl StatusPending {
|
||||
}
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct ErrorCounter {
|
||||
#[bits(0..=7, r)]
|
||||
transmit: u8,
|
||||
@@ -247,8 +244,7 @@ pub struct ErrorCounter {
|
||||
}
|
||||
|
||||
/// This register is unused for standard frames.
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct ExtendedId {
|
||||
/// Mask for ID bits \[14:0\] of extended frames.
|
||||
#[bits(1..=15, rw)]
|
||||
@@ -258,8 +254,7 @@ pub struct ExtendedId {
|
||||
xrtr: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct BaseId {
|
||||
/// This will contain ID\[10:0\] for standard frames and bits \[28:18\] for extended frames.
|
||||
#[bits(5..=15, rw)]
|
||||
@@ -297,7 +292,7 @@ pub enum ErrorFieldId {
|
||||
Crc = 0b1111,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
|
||||
pub struct DiagnosticRegister {
|
||||
/// Shows the output value on the CAN TX pin at the time of the error.
|
||||
#[bit(14, r)]
|
||||
@@ -322,46 +317,15 @@ pub struct DiagnosticRegister {
|
||||
efid: ErrorFieldId,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for DiagnosticRegister {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("DiagnosticRegister")
|
||||
.field("efid", &self.efid())
|
||||
.field("ebid", &self.ebid())
|
||||
.field("txe", &self.txe())
|
||||
.field("stuff", &self.stuff())
|
||||
.field("crc", &self.crc())
|
||||
.field("mon", &self.mon())
|
||||
.field("drive", &self.drive())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
impl defmt::Format for DiagnosticRegister {
|
||||
fn format(&self, fmt: defmt::Formatter) {
|
||||
defmt::write!(
|
||||
fmt,
|
||||
"DiagnosticRegister {{ efid: {}, ebid: {}, txe: {}, stuff: {}, crc: {}, mon: {}, drive: {} }}",
|
||||
self.efid(),
|
||||
self.ebid(),
|
||||
self.txe(),
|
||||
self.stuff(),
|
||||
self.crc(),
|
||||
self.mon(),
|
||||
self.drive()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(derive_mmio::Mmio)]
|
||||
#[mmio(const_inner)]
|
||||
#[repr(C)]
|
||||
pub struct Can {
|
||||
#[mmio(Inner)]
|
||||
cmbs: [CanMsgBuf; 15],
|
||||
cmbs: [CanMessageBuffer; 15],
|
||||
/// Hidden CAN message buffer. Only allowed to be used internally by the peripheral.
|
||||
#[mmio(Inner)]
|
||||
_hcmb: CanMsgBuf,
|
||||
_hcmb: CanMessageBuffer,
|
||||
control: Control,
|
||||
timing: TimingConfig,
|
||||
/// Global mask extension used for buffers 0 to 13.
|
||||
|
||||
+56
-52
@@ -15,14 +15,14 @@ use crate::adc::ADC_MAX_CLK;
|
||||
use crate::pac;
|
||||
|
||||
use crate::time::Hertz;
|
||||
pub use vorago_shared_periphs::clock::{Clocks, HBO_FREQ};
|
||||
use vorago_shared_periphs::{enable_peripheral_clock, PeripheralSelect};
|
||||
pub use vorago_shared_hal::clock::{Clocks, HBO_FREQ};
|
||||
use vorago_shared_hal::{enable_peripheral_clock, PeripheralSelect};
|
||||
|
||||
pub const XTAL_OSC_TSTART_MS: u32 = 15;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum FilterClkSel {
|
||||
pub enum FilterClockSelect {
|
||||
SysClk = 0,
|
||||
Clk1 = 1,
|
||||
Clk2 = 2,
|
||||
@@ -36,7 +36,7 @@ pub enum FilterClkSel {
|
||||
/// Refer to chapter 8 (p.57) of the programmers guide for detailed information.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum ClkselSys {
|
||||
pub enum ClockSelect {
|
||||
// Internal Heart-Beat Osciallator. Not tightly controlled (+/-20 %). Not recommended as the regular clock!
|
||||
Hbo = 0b00,
|
||||
// External clock signal on XTAL_N line, 1-100 MHz
|
||||
@@ -55,7 +55,7 @@ pub enum ClkselSys {
|
||||
/// Refer to chapter 8 (p.57) of the programmers guide for detailed information.
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum RefClkSel {
|
||||
pub enum ReferenceClockSelect {
|
||||
#[default]
|
||||
None = 0b00,
|
||||
XtalOsc = 0b01,
|
||||
@@ -64,7 +64,7 @@ pub enum RefClkSel {
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum ClkDivSel {
|
||||
pub enum ClockDivisorSelect {
|
||||
#[default]
|
||||
Div1 = 0b00,
|
||||
Div2 = 0b01,
|
||||
@@ -74,7 +74,7 @@ pub enum ClkDivSel {
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum AdcClkDivSel {
|
||||
pub enum AdcClockDivisorSelect {
|
||||
Div8 = 0b00,
|
||||
Div4 = 0b01,
|
||||
Div2 = 0b10,
|
||||
@@ -83,7 +83,7 @@ pub enum AdcClkDivSel {
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct PllCfg {
|
||||
pub struct PllConfig {
|
||||
/// Reference clock divider.
|
||||
pub clkr: u8,
|
||||
/// Clock divider on feedback path
|
||||
@@ -94,12 +94,13 @@ pub struct PllCfg {
|
||||
pub bwadj: u8,
|
||||
}
|
||||
|
||||
pub fn clk_after_div(clk: Hertz, div_sel: ClkDivSel) -> Hertz {
|
||||
#[inline]
|
||||
pub const fn clock_after_division(clk: Hertz, div_sel: ClockDivisorSelect) -> Hertz {
|
||||
match div_sel {
|
||||
ClkDivSel::Div1 => clk,
|
||||
ClkDivSel::Div2 => clk / 2,
|
||||
ClkDivSel::Div4 => clk / 4,
|
||||
ClkDivSel::Div8 => clk / 8,
|
||||
ClockDivisorSelect::Div1 => clk,
|
||||
ClockDivisorSelect::Div2 => Hertz::from_raw(clk.raw() / 2),
|
||||
ClockDivisorSelect::Div4 => Hertz::from_raw(clk.raw() / 4),
|
||||
ClockDivisorSelect::Div8 => Hertz::from_raw(clk.raw() / 8),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,9 +119,9 @@ impl ClkgenExt for pac::Clkgen {
|
||||
fn constrain(self) -> ClockConfigurator {
|
||||
ClockConfigurator {
|
||||
source_clk: None,
|
||||
ref_clk_sel: RefClkSel::None,
|
||||
clksel_sys: ClkselSys::Hbo,
|
||||
clk_div_sel: ClkDivSel::Div1,
|
||||
ref_clk_sel: ReferenceClockSelect::None,
|
||||
clksel_sys: ClockSelect::Hbo,
|
||||
clk_div_sel: ClockDivisorSelect::Div1,
|
||||
clk_lost_detection: false,
|
||||
pll_lock_lost_detection: false,
|
||||
pll_cfg: None,
|
||||
@@ -131,11 +132,11 @@ impl ClkgenExt for pac::Clkgen {
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct ClkSourceFreqNotSet;
|
||||
pub struct ClockSourceFrequencyNotSet;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum ClkCfgError {
|
||||
pub enum ClockConfigError {
|
||||
ClkSourceFreqNotSet,
|
||||
PllConfigNotSet,
|
||||
PllInitError,
|
||||
@@ -143,13 +144,13 @@ pub enum ClkCfgError {
|
||||
}
|
||||
|
||||
pub struct ClockConfigurator {
|
||||
ref_clk_sel: RefClkSel,
|
||||
clksel_sys: ClkselSys,
|
||||
clk_div_sel: ClkDivSel,
|
||||
ref_clk_sel: ReferenceClockSelect,
|
||||
clksel_sys: ClockSelect,
|
||||
clk_div_sel: ClockDivisorSelect,
|
||||
/// The source clock frequency which is either an external clock connected to XTAL_N, or a
|
||||
/// crystal connected to the XTAL_OSC input.
|
||||
source_clk: Option<Hertz>,
|
||||
pll_cfg: Option<PllCfg>,
|
||||
pll_cfg: Option<PllConfig>,
|
||||
clk_lost_detection: bool,
|
||||
/// Feature only works on revision B of the board.
|
||||
#[cfg(feature = "revb")]
|
||||
@@ -176,9 +177,9 @@ impl ClockConfigurator {
|
||||
pub fn new(clkgen: pac::Clkgen) -> Self {
|
||||
ClockConfigurator {
|
||||
source_clk: None,
|
||||
ref_clk_sel: RefClkSel::None,
|
||||
clksel_sys: ClkselSys::Hbo,
|
||||
clk_div_sel: ClkDivSel::Div1,
|
||||
ref_clk_sel: ReferenceClockSelect::None,
|
||||
clksel_sys: ClockSelect::Hbo,
|
||||
clk_div_sel: ClockDivisorSelect::Div1,
|
||||
clk_lost_detection: false,
|
||||
pll_lock_lost_detection: false,
|
||||
pll_cfg: None,
|
||||
@@ -207,8 +208,8 @@ impl ClockConfigurator {
|
||||
/// It sets the internal configuration to [ClkselSys::XtalN] and [RefClkSel::XtalN].
|
||||
#[inline]
|
||||
pub fn xtal_n_clk(mut self) -> Self {
|
||||
self.clksel_sys = ClkselSys::XtalN;
|
||||
self.ref_clk_sel = RefClkSel::XtalN;
|
||||
self.clksel_sys = ClockSelect::XtalN;
|
||||
self.ref_clk_sel = ReferenceClockSelect::XtalN;
|
||||
self
|
||||
}
|
||||
|
||||
@@ -219,19 +220,19 @@ impl ClockConfigurator {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clksel_sys(mut self, clksel_sys: ClkselSys) -> Self {
|
||||
pub fn clksel_sys(mut self, clksel_sys: ClockSelect) -> Self {
|
||||
self.clksel_sys = clksel_sys;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pll_cfg(mut self, pll_cfg: PllCfg) -> Self {
|
||||
pub fn pll_cfg(mut self, pll_cfg: PllConfig) -> Self {
|
||||
self.pll_cfg = Some(pll_cfg);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ref_clk_sel(mut self, ref_clk_sel: RefClkSel) -> Self {
|
||||
pub fn ref_clk_sel(mut self, ref_clk_sel: ReferenceClockSelect) -> Self {
|
||||
self.ref_clk_sel = ref_clk_sel;
|
||||
self
|
||||
}
|
||||
@@ -245,19 +246,22 @@ impl ClockConfigurator {
|
||||
/// might have had a reason for those, so I am going to keep them. Chances are, this
|
||||
/// process only has to be performed once, and it does not matter if it takes a few
|
||||
/// microseconds or milliseconds longer.
|
||||
pub fn freeze(self) -> Result<Clocks, ClkCfgError> {
|
||||
pub fn freeze(self) -> Result<Clocks, ClockConfigError> {
|
||||
// Sanitize configuration.
|
||||
if self.source_clk.is_none() {
|
||||
return Err(ClkCfgError::ClkSourceFreqNotSet);
|
||||
return Err(ClockConfigError::ClkSourceFreqNotSet);
|
||||
}
|
||||
if self.clksel_sys == ClkselSys::XtalOsc && self.ref_clk_sel != RefClkSel::XtalOsc {
|
||||
return Err(ClkCfgError::InconsistentCfg);
|
||||
if self.clksel_sys == ClockSelect::XtalOsc
|
||||
&& self.ref_clk_sel != ReferenceClockSelect::XtalOsc
|
||||
{
|
||||
return Err(ClockConfigError::InconsistentCfg);
|
||||
}
|
||||
if self.clksel_sys == ClkselSys::XtalN && self.ref_clk_sel != RefClkSel::XtalN {
|
||||
return Err(ClkCfgError::InconsistentCfg);
|
||||
if self.clksel_sys == ClockSelect::XtalN && self.ref_clk_sel != ReferenceClockSelect::XtalN
|
||||
{
|
||||
return Err(ClockConfigError::InconsistentCfg);
|
||||
}
|
||||
if self.clksel_sys == ClkselSys::Pll && self.pll_cfg.is_none() {
|
||||
return Err(ClkCfgError::PllConfigNotSet);
|
||||
if self.clksel_sys == ClockSelect::Pll && self.pll_cfg.is_none() {
|
||||
return Err(ClockConfigError::PllConfigNotSet);
|
||||
}
|
||||
|
||||
enable_peripheral_clock(PeripheralSelect::Clkgen);
|
||||
@@ -268,11 +272,11 @@ impl ClockConfigurator {
|
||||
// Therefore, we do it here as well.
|
||||
self.clkgen
|
||||
.ctrl0()
|
||||
.modify(|_, w| unsafe { w.clksel_sys().bits(ClkselSys::Hbo as u8) });
|
||||
.modify(|_, w| unsafe { w.clksel_sys().bits(ClockSelect::Hbo as u8) });
|
||||
pll_setup_delay();
|
||||
self.clkgen
|
||||
.ctrl0()
|
||||
.modify(|_, w| unsafe { w.clk_div_sel().bits(ClkDivSel::Div1 as u8) });
|
||||
.modify(|_, w| unsafe { w.clk_div_sel().bits(ClockDivisorSelect::Div1 as u8) });
|
||||
|
||||
// Set up oscillator and PLL input clock.
|
||||
self.clkgen
|
||||
@@ -284,12 +288,12 @@ impl ClockConfigurator {
|
||||
w
|
||||
});
|
||||
match self.ref_clk_sel {
|
||||
RefClkSel::None => pll_setup_delay(),
|
||||
RefClkSel::XtalOsc => {
|
||||
ReferenceClockSelect::None => pll_setup_delay(),
|
||||
ReferenceClockSelect::XtalOsc => {
|
||||
self.clkgen.ctrl1().modify(|_, w| w.xtal_en().set_bit());
|
||||
hbo_clock_delay_ms(XTAL_OSC_TSTART_MS);
|
||||
}
|
||||
RefClkSel::XtalN => {
|
||||
ReferenceClockSelect::XtalN => {
|
||||
self.clkgen.ctrl1().modify(|_, w| w.xtal_n_en().set_bit());
|
||||
pll_setup_delay()
|
||||
}
|
||||
@@ -340,7 +344,7 @@ impl ClockConfigurator {
|
||||
// This is what the HAL does. We could continue, but then we would at least
|
||||
// have to somehow report a partial error.. Chances are, the user does not
|
||||
// want to continue with a broken PLL clock.
|
||||
return Err(ClkCfgError::PllInitError);
|
||||
return Err(ClockConfigError::PllInitError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,7 +364,7 @@ impl ClockConfigurator {
|
||||
self.clkgen
|
||||
.ctrl0()
|
||||
.modify(|_, w| unsafe { w.clk_div_sel().bits(self.clk_div_sel as u8) });
|
||||
final_sysclk = clk_after_div(final_sysclk, self.clk_div_sel);
|
||||
final_sysclk = clock_after_division(final_sysclk, self.clk_div_sel);
|
||||
|
||||
// The HAL does this. I don't know why..
|
||||
pll_setup_delay();
|
||||
@@ -383,14 +387,14 @@ impl ClockConfigurator {
|
||||
// NOTE: Not using divide by 1 or /2 ratio in REVA silicon because of triggering issue
|
||||
// For this reason, keep SYSCLK above 8MHz to have the ADC /4 ratio in range)
|
||||
if final_sysclk.raw() <= ADC_MAX_CLK.raw() * 4 {
|
||||
self.clkgen
|
||||
.ctrl1()
|
||||
.modify(|_, w| unsafe { w.adc_clk_div_sel().bits(AdcClkDivSel::Div4 as u8) });
|
||||
self.clkgen.ctrl1().modify(|_, w| unsafe {
|
||||
w.adc_clk_div_sel().bits(AdcClockDivisorSelect::Div4 as u8)
|
||||
});
|
||||
final_sysclk / 4
|
||||
} else {
|
||||
self.clkgen
|
||||
.ctrl1()
|
||||
.modify(|_, w| unsafe { w.adc_clk_div_sel().bits(AdcClkDivSel::Div8 as u8) });
|
||||
self.clkgen.ctrl1().modify(|_, w| unsafe {
|
||||
w.adc_clk_div_sel().bits(AdcClockDivisorSelect::Div8 as u8)
|
||||
});
|
||||
final_sysclk / 8
|
||||
}
|
||||
}
|
||||
@@ -433,7 +437,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_basic_div() {
|
||||
assert_eq!(
|
||||
clk_after_div(Hertz::from_raw(10_000_000), super::ClkDivSel::Div2),
|
||||
clock_after_division(Hertz::from_raw(10_000_000), super::ClockDivisorSelect::Div2),
|
||||
Hertz::from_raw(5_000_000)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! - [ADC and DAC example](https://github.com/us-irs/va416xx-rs/blob/main/examples/simple/examples/dac-adc.rs)
|
||||
use core::ops::Deref;
|
||||
|
||||
use vorago_shared_periphs::{
|
||||
use vorago_shared_hal::{
|
||||
disable_peripheral_clock, enable_peripheral_clock, reset_peripheral_for_cycles,
|
||||
PeripheralSelect,
|
||||
};
|
||||
@@ -16,13 +16,13 @@ pub type DacRegisterBlock = pac::dac0::RegisterBlock;
|
||||
|
||||
/// Common trait implemented by all PAC peripheral access structures. The register block
|
||||
/// format is the same for all DAC blocks.
|
||||
pub trait DacMarker: Deref<Target = DacRegisterBlock> {
|
||||
pub trait DacInstance: Deref<Target = DacRegisterBlock> {
|
||||
const IDX: u8;
|
||||
|
||||
fn ptr() -> *const DacRegisterBlock;
|
||||
}
|
||||
|
||||
impl DacMarker for pac::Dac0 {
|
||||
impl DacInstance for pac::Dac0 {
|
||||
const IDX: u8 = 0;
|
||||
|
||||
#[inline(always)]
|
||||
@@ -31,7 +31,7 @@ impl DacMarker for pac::Dac0 {
|
||||
}
|
||||
}
|
||||
|
||||
impl DacMarker for pac::Dac1 {
|
||||
impl DacInstance for pac::Dac1 {
|
||||
const IDX: u8 = 1;
|
||||
|
||||
#[inline(always)]
|
||||
@@ -62,7 +62,7 @@ impl Dac {
|
||||
/// Create a new [Dac] driver instance.
|
||||
///
|
||||
/// The [Clocks] structure is expected here as well to ensure the clock was set up properly.
|
||||
pub fn new<Dac: DacMarker>(dac: Dac, dac_settling: DacSettling, _clocks: &Clocks) -> Self {
|
||||
pub fn new<Dac: DacInstance>(dac: Dac, dac_settling: DacSettling, _clocks: &Clocks) -> Self {
|
||||
enable_peripheral_clock(PeripheralSelect::Dac);
|
||||
|
||||
dac.ctrl1().write(|w| {
|
||||
|
||||
+5
-41
@@ -4,9 +4,7 @@
|
||||
//!
|
||||
//! - [Simple DMA example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/dma.rs)
|
||||
use arbitrary_int::{u10, u3};
|
||||
use vorago_shared_periphs::{
|
||||
enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect,
|
||||
};
|
||||
use vorago_shared_hal::{enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect};
|
||||
|
||||
use crate::{enable_nvic_interrupt, pac};
|
||||
|
||||
@@ -91,41 +89,7 @@ pub enum RPower {
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct InvalidCtrlBlockAddrError;
|
||||
|
||||
/*
|
||||
bitfield::bitfield! {
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct ChannelConfig(u32);
|
||||
impl Debug;
|
||||
u32;
|
||||
pub raw, set_raw: 31,0;
|
||||
u8;
|
||||
pub dst_inc, set_dst_inc: 31, 30;
|
||||
u8;
|
||||
pub dst_size, set_dst_size: 29, 28;
|
||||
u8;
|
||||
pub src_inc, set_src_inc: 27, 26;
|
||||
u8;
|
||||
pub src_size, set_src_size: 25, 24;
|
||||
u8;
|
||||
pub dest_prot_ctrl, set_dest_prot_ctrl: 23, 21;
|
||||
u8;
|
||||
pub src_prot_ctrl, set_src_prot_ctrl: 20, 18;
|
||||
u8;
|
||||
pub r_power, set_r_power: 17, 14;
|
||||
u16;
|
||||
pub n_minus_1, set_n_minus_1: 13, 4;
|
||||
bool;
|
||||
pub next_useburst, set_next_useburst: 3;
|
||||
u8;
|
||||
pub cycle_ctrl, set_cycle_ctr: 2, 0;
|
||||
}
|
||||
*/
|
||||
|
||||
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_fields(feature = "defmt"))]
|
||||
pub struct ChannelConfig {
|
||||
#[bits(30..=31, rw)]
|
||||
dst_inc: AddrIncrement,
|
||||
@@ -231,7 +195,7 @@ pub enum DmaTransferInitError {
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub struct DmaCfg {
|
||||
pub struct DmaConfig {
|
||||
pub bufferable: bool,
|
||||
pub cacheable: bool,
|
||||
pub privileged: bool,
|
||||
@@ -533,7 +497,7 @@ impl Dma {
|
||||
/// control block at a specific address.
|
||||
pub fn new(
|
||||
dma: pac::Dma,
|
||||
cfg: DmaCfg,
|
||||
cfg: DmaConfig,
|
||||
ctrl_block: *mut DmaCtrlBlock,
|
||||
) -> Result<Self, InvalidCtrlBlockAddrError> {
|
||||
// The conversion to u32 is safe here because we are on a 32-bit system.
|
||||
@@ -563,7 +527,7 @@ impl Dma {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_protection_bits(&self, cfg: &DmaCfg) {
|
||||
pub fn set_protection_bits(&self, cfg: &DmaConfig) {
|
||||
self.dma.cfg().write(|w| unsafe {
|
||||
w.chnl_prot_ctrl().bits(
|
||||
cfg.privileged as u8 | ((cfg.bufferable as u8) << 1) | ((cfg.cacheable as u8) << 2),
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
//!
|
||||
//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/blinky.rs)
|
||||
//! - [Async GPIO example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/embassy/src/bin/async-gpio.rs)
|
||||
pub use vorago_shared_periphs::gpio::*;
|
||||
pub use vorago_shared_hal::gpio::*;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! - [PEB1 accelerometer example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/peb1-accelerometer.rs)
|
||||
pub use vorago_shared_periphs::i2c::*;
|
||||
pub use vorago_shared_hal::i2c::*;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
//! IRQ Router peripheral support.
|
||||
use vorago_shared_periphs::{
|
||||
enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect,
|
||||
};
|
||||
use vorago_shared_hal::{enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect};
|
||||
|
||||
use crate::pac;
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@ pub mod adc;
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
pub mod dac;
|
||||
|
||||
pub use vorago_shared_periphs::{
|
||||
pub use vorago_shared_hal::{
|
||||
assert_peripheral_reset, deassert_peripheral_reset, disable_nvic_interrupt,
|
||||
disable_peripheral_clock, enable_nvic_interrupt, enable_peripheral_clock,
|
||||
reset_peripheral_for_cycles, FunSel, PeripheralSelect,
|
||||
reset_peripheral_for_cycles, FunctionSelect, PeripheralSelect,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
@@ -80,19 +80,19 @@ pub fn port_function_select(
|
||||
ioconfig: &mut pac::Ioconfig,
|
||||
port: Port,
|
||||
pin: u8,
|
||||
funsel: FunSel,
|
||||
funsel: FunctionSelect,
|
||||
) -> Result<(), InvalidPinError> {
|
||||
if (port == Port::G && pin >= 8) || pin >= 16 {
|
||||
return Err(InvalidPinError(pin));
|
||||
}
|
||||
let reg_block = match port {
|
||||
Port::A => ioconfig.porta(pin as usize),
|
||||
Port::B => ioconfig.portb0(pin as usize),
|
||||
Port::C => ioconfig.portc0(pin as usize),
|
||||
Port::D => ioconfig.portd0(pin as usize),
|
||||
Port::E => ioconfig.porte0(pin as usize),
|
||||
Port::F => ioconfig.portf0(pin as usize),
|
||||
Port::G => ioconfig.portg0(pin as usize),
|
||||
Port::B => ioconfig.portb(pin as usize),
|
||||
Port::C => ioconfig.portc(pin as usize),
|
||||
Port::D => ioconfig.portd(pin as usize),
|
||||
Port::E => ioconfig.porte(pin as usize),
|
||||
Port::F => ioconfig.portf(pin as usize),
|
||||
Port::G => ioconfig.portg(pin as usize),
|
||||
};
|
||||
|
||||
reg_block.modify(|_, w| unsafe { w.funsel().bits(funsel as u8) });
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
//!
|
||||
//! - [Flashloader application](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/flashloader)
|
||||
use embedded_hal::spi::MODE_0;
|
||||
use vorago_shared_periphs::{
|
||||
use vorago_shared_hal::{
|
||||
disable_peripheral_clock, enable_peripheral_clock, reset_peripheral_for_cycles,
|
||||
};
|
||||
|
||||
use crate::clock::Clocks;
|
||||
use crate::pac;
|
||||
use crate::spi::{
|
||||
mode_to_cpo_cph_bit, spi_clk_config_from_div, SpiMarker, WordProvider, BMSTART_BMSTOP_MASK,
|
||||
mode_to_cpo_cph_bit, spi_clk_config_from_div, SpiInstance, SpiWord, BMSTART_BMSTOP_MASK,
|
||||
};
|
||||
|
||||
const NVM_CLOCK_DIV: u16 = 2;
|
||||
@@ -31,7 +31,8 @@ pub const FRAM_WRITE: u8 = 0x02;
|
||||
pub const FRAM_RDID: u8 = 0x9F;
|
||||
pub const FRAM_SLEEP: u8 = 0xB9;
|
||||
|
||||
/* Address Masks */
|
||||
// Address Masks
|
||||
|
||||
const ADDR_MSB_MASK: u32 = 0xFF0000;
|
||||
const ADDR_MID_MASK: u32 = 0x00FF00;
|
||||
const ADDR_LSB_MASK: u32 = 0x0000FF;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
//! This module contains the pin singletons. It allows creating those singletons
|
||||
//! to access the [Pin] structures of individual ports in a safe way with checked ownership
|
||||
//! rules.
|
||||
pub use vorago_shared_periphs::pins::*;
|
||||
pub use vorago_shared_hal::pins::*;
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/pwm.rs)
|
||||
pub use vorago_shared_periphs::pwm::*;
|
||||
pub use vorago_shared_hal::pwm::*;
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
//!
|
||||
//! - [Blocking SPI example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/spi.rs)
|
||||
//! - [NVM library][crate::nvm]
|
||||
pub use vorago_shared_periphs::spi::*;
|
||||
pub use vorago_shared_hal::spi::*;
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
//!
|
||||
//! - [MS and second tick implementation](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/timer-ticks.rs)
|
||||
//! - [Cascade feature example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/cascade.rs)
|
||||
pub use vorago_shared_periphs::timer::*;
|
||||
pub use vorago_shared_hal::timer::*;
|
||||
|
||||
pub const TIM_IRQ_OFFSET: usize = 48;
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
//! - [Flashloader exposing a CCSDS interface via UART](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/flashloader)
|
||||
//! - [Async UART RX example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/embassy/src/bin/async-uart-rx.rs)
|
||||
//! - [Async UART TX example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/embassy/src/bin/async-uart-tx.rs)
|
||||
pub use vorago_shared_periphs::uart::*;
|
||||
pub use vorago_shared_hal::uart::*;
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! - [Watchdog simple example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/wdt.rs)
|
||||
use vorago_shared_periphs::{
|
||||
enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect,
|
||||
};
|
||||
use vorago_shared_hal::{enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect};
|
||||
|
||||
use crate::time::Hertz;
|
||||
use crate::{clock::Clocks, pac};
|
||||
|
||||
@@ -11,7 +11,7 @@ keywords = ["no-std", "peb1", "cortex-m", "vorago", "va416xx"]
|
||||
categories = ["embedded", "no-std", "hardware-support"]
|
||||
|
||||
[dependencies]
|
||||
va416xx-hal = { version = ">=0.3, <=0.5", path = "../va416xx-hal", features = ["va41630"] }
|
||||
va416xx-hal = { version = "0.6", path = "../va416xx-hal", features = ["va41630"] }
|
||||
lis2dh12 = { version = "0.7", features = ["out_f32"] }
|
||||
|
||||
[features]
|
||||
|
||||
Reference in New Issue
Block a user