Rework library structure
Changed: - Move most library components to new [`vorago-shared-periphs`](https://egit.irs.uni-stuttgart.de/rust/vorago-shared-periphs) which is mostly re-exported in this crate. - Overhaul and simplification of several HAL APIs. The system configuration and IRQ router peripheral instance generally does not need to be passed to HAL API anymore. - All HAL drivers are now type erased. The constructors will still expect and consume the PAC singleton component for resource management purposes, but are not cached anymore. - Refactoring of GPIO library to be more inline with embassy GPIO API. Added: - I2C clock timeout feature support.
This commit is contained in:
@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1"
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7"
|
||||
embedded-hal = "1"
|
||||
cfg-if = "1"
|
||||
embedded-io = "0.6"
|
||||
embedded-hal-async = "1"
|
||||
embedded-io-async = "0.6"
|
||||
@ -18,7 +16,6 @@ defmt = "1"
|
||||
panic-probe = { version = "1", features = ["defmt"] }
|
||||
static_cell = "2"
|
||||
critical-section = "1"
|
||||
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
||||
ringbuf = { version = "0.4", default-features = false }
|
||||
|
||||
embassy-sync = "0.6"
|
||||
@ -29,11 +26,14 @@ embassy-executor = { version = "0.7", features = [
|
||||
"executor-interrupt"
|
||||
]}
|
||||
|
||||
va416xx-hal = { version = "0.5", features = ["defmt"] }
|
||||
va416xx-embassy = { version = "0.1", default-features = false }
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["defmt"] }
|
||||
va416xx-embassy = { version = "0.1", path = "../../va416xx-embassy", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["ticks-hz-1_000", "va416xx-embassy/irq-tim14-tim15"]
|
||||
custom-irqs = []
|
||||
ticks-hz-1_000 = ["embassy-time/tick-hz-1_000"]
|
||||
ticks-hz-32_768 = ["embassy-time/tick-hz-32_768"]
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["cortex-m-rt"]
|
||||
|
@ -5,6 +5,7 @@
|
||||
//! [CHECK_XXX_TO_XXX] constants to true.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
// Import panic provider.
|
||||
use panic_probe as _;
|
||||
// Import logger.
|
||||
@ -16,23 +17,19 @@ use embassy_sync::channel::{Receiver, Sender};
|
||||
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, channel::Channel};
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use embedded_hal_async::digital::Wait;
|
||||
use va416xx_hal::clock::ClkgenExt;
|
||||
use va416xx_hal::gpio::{
|
||||
on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, PinsC, PinsD,
|
||||
PinsE, PinsF, PinsG, Port,
|
||||
};
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
use va416xx_hal::gpio::asynch::{on_interrupt_for_async_gpio_for_port, InputPinAsync};
|
||||
use va416xx_hal::gpio::{Input, Output, PinState, Port};
|
||||
use va416xx_hal::pac::{self, interrupt};
|
||||
use va416xx_hal::pins::{PinsA, PinsB, PinsC, PinsD, PinsE, PinsF, PinsG};
|
||||
use va416xx_hal::time::Hertz;
|
||||
use va416xx_hal::{
|
||||
gpio::{DynPin, PinsA},
|
||||
pac::{self, interrupt},
|
||||
};
|
||||
|
||||
const CHECK_PA0_TO_PA1: bool = true;
|
||||
const CHECK_PB0_TO_PB1: bool = true;
|
||||
const CHECK_PC14_TO_PC15: bool = true;
|
||||
const CHECK_PD2_TO_PD3: bool = true;
|
||||
const CHECK_PE0_TO_PE1: bool = true;
|
||||
const CHECK_PF0_TO_PF1: bool = true;
|
||||
const CHECK_PB0_TO_PB1: bool = false;
|
||||
const CHECK_PC14_TO_PC15: bool = false;
|
||||
const CHECK_PD2_TO_PD3: bool = false;
|
||||
const CHECK_PE0_TO_PE1: bool = false;
|
||||
const CHECK_PF0_TO_PF1: bool = false;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct GpioCmd {
|
||||
@ -70,41 +67,30 @@ static CHANNEL_PF0_TO_PF1: Channel<ThreadModeRawMutex, GpioCmd, 3> = Channel::ne
|
||||
async fn main(spawner: Spawner) {
|
||||
defmt::println!("-- VA416xx Async GPIO Demo --");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks,
|
||||
)
|
||||
};
|
||||
va416xx_embassy::init(dp.tim15, dp.tim14, &clocks);
|
||||
|
||||
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
|
||||
let portb = PinsB::new(&mut dp.sysconfig, dp.portb);
|
||||
let portc = PinsC::new(&mut dp.sysconfig, dp.portc);
|
||||
let portd = PinsD::new(&mut dp.sysconfig, dp.portd);
|
||||
let porte = PinsE::new(&mut dp.sysconfig, dp.porte);
|
||||
let portf = PinsF::new(&mut dp.sysconfig, dp.portf);
|
||||
let porta = PinsA::new(dp.porta);
|
||||
let portb = PinsB::new(dp.portb);
|
||||
let portc = PinsC::new(dp.portc);
|
||||
let portd = PinsD::new(dp.portd);
|
||||
let porte = PinsE::new(dp.porte);
|
||||
let portf = PinsF::new(dp.portf);
|
||||
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let mut led = portg.pg5.into_readable_push_pull_output();
|
||||
let portg = PinsG::new(dp.portg);
|
||||
let mut led = Output::new(portg.pg5, PinState::Low);
|
||||
|
||||
if CHECK_PA0_TO_PA1 {
|
||||
let out_pin = porta.pa0.into_readable_push_pull_output();
|
||||
let in_pin = porta.pa1.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let out_pin = Output::new(porta.pa0, PinState::Low);
|
||||
let in_pin = Input::new_floating(porta.pa1);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
|
||||
spawner
|
||||
@ -119,10 +105,9 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
if CHECK_PB0_TO_PB1 {
|
||||
let out_pin = portb.pb0.into_readable_push_pull_output();
|
||||
let in_pin = portb.pb1.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let in_pin = InputDynPinAsync::new(in_pin.downgrade()).unwrap();
|
||||
let out_pin = Output::new(portb.pb0, PinState::Low);
|
||||
let in_pin = Input::new_floating(portb.pb1);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
@ -136,10 +121,9 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
if CHECK_PC14_TO_PC15 {
|
||||
let out_pin = portc.pc14.into_readable_push_pull_output();
|
||||
let in_pin = portc.pc15.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let in_pin = InputDynPinAsync::new(in_pin.downgrade()).unwrap();
|
||||
let out_pin = Output::new(portc.pc14, PinState::Low);
|
||||
let in_pin = Input::new_floating(portc.pc15);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
"PC14 to PC15",
|
||||
@ -152,10 +136,9 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
if CHECK_PD2_TO_PD3 {
|
||||
let out_pin = portd.pd2.into_readable_push_pull_output();
|
||||
let in_pin = portd.pd3.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let in_pin = InputDynPinAsync::new(in_pin.downgrade()).unwrap();
|
||||
let out_pin = Output::new(portd.pd2, PinState::Low);
|
||||
let in_pin = Input::new_floating(portd.pd3);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
"PD2 to PD3",
|
||||
@ -168,10 +151,9 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
if CHECK_PE0_TO_PE1 {
|
||||
let out_pin = porte.pe0.into_readable_push_pull_output();
|
||||
let in_pin = porte.pe1.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let in_pin = InputDynPinAsync::new(in_pin.downgrade()).unwrap();
|
||||
let out_pin = Output::new(porte.pe0, PinState::Low);
|
||||
let in_pin = Input::new_floating(porte.pe1);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
"PE0 to PE1",
|
||||
@ -184,10 +166,9 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
if CHECK_PF0_TO_PF1 {
|
||||
let out_pin = portf.pf0.into_readable_push_pull_output();
|
||||
let in_pin = portf.pf1.into_floating_input();
|
||||
let out_pin = out_pin.downgrade();
|
||||
let in_pin = InputDynPinAsync::new(in_pin.downgrade()).unwrap();
|
||||
let out_pin = Output::new(portf.pf0, PinState::Low);
|
||||
let in_pin = Input::new_floating(portf.pf1);
|
||||
let in_pin = InputPinAsync::new(in_pin).unwrap();
|
||||
spawner
|
||||
.spawn(output_task(
|
||||
"PF0 to PF1",
|
||||
@ -298,7 +279,7 @@ async fn check_pin_to_pin_async_ops(
|
||||
#[embassy_executor::task(pool_size = 8)]
|
||||
async fn output_task(
|
||||
ctx: &'static str,
|
||||
mut out: DynPin,
|
||||
mut out: Output,
|
||||
receiver: Receiver<'static, ThreadModeRawMutex, GpioCmd, 3>,
|
||||
) {
|
||||
loop {
|
||||
@ -307,25 +288,25 @@ async fn output_task(
|
||||
match next_cmd.cmd_type {
|
||||
GpioCmdType::SetHigh => {
|
||||
defmt::info!("{}: Set output high", ctx);
|
||||
out.set_high().unwrap();
|
||||
out.set_high();
|
||||
}
|
||||
GpioCmdType::SetLow => {
|
||||
defmt::info!("{}: Set output low", ctx);
|
||||
out.set_low().unwrap();
|
||||
out.set_low();
|
||||
}
|
||||
GpioCmdType::RisingEdge => {
|
||||
defmt::info!("{}: Rising edge", ctx);
|
||||
if !out.is_low().unwrap() {
|
||||
out.set_low().unwrap();
|
||||
if !out.is_set_low() {
|
||||
out.set_low();
|
||||
}
|
||||
out.set_high().unwrap();
|
||||
out.set_high();
|
||||
}
|
||||
GpioCmdType::FallingEdge => {
|
||||
defmt::info!("{}: Falling edge", ctx);
|
||||
if !out.is_high().unwrap() {
|
||||
out.set_high().unwrap();
|
||||
if !out.is_set_high() {
|
||||
out.set_high();
|
||||
}
|
||||
out.set_low().unwrap();
|
||||
out.set_low();
|
||||
}
|
||||
GpioCmdType::CloseTask => {
|
||||
defmt::info!("{}: Closing task", ctx);
|
||||
|
@ -27,8 +27,10 @@ use embedded_io::Write;
|
||||
use embedded_io_async::Read;
|
||||
use heapless::spsc::{Producer, Queue};
|
||||
use va416xx_hal::{
|
||||
gpio::PinsG,
|
||||
clock::ClockConfigurator,
|
||||
gpio::{Output, PinState},
|
||||
pac::{self, interrupt},
|
||||
pins::PinsG,
|
||||
prelude::*,
|
||||
time::Hertz,
|
||||
uart::{
|
||||
@ -46,34 +48,22 @@ static PRODUCER_UART_A: Mutex<RefCell<Option<Producer<u8, 256>>>> = Mutex::new(R
|
||||
async fn main(_spawner: Spawner) {
|
||||
defmt::println!("-- VA108xx Async UART RX Demo --");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks,
|
||||
);
|
||||
}
|
||||
va416xx_embassy::init(dp.tim15, dp.tim14, &clocks);
|
||||
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let mut led = portg.pg5.into_readable_push_pull_output();
|
||||
let portg = PinsG::new(dp.portg);
|
||||
let mut led = Output::new(portg.pg5, PinState::Low);
|
||||
|
||||
let tx = portg.pg0.into_funsel_1();
|
||||
let rx = portg.pg1.into_funsel_1();
|
||||
|
||||
let uarta = uart::Uart::new(&mut dp.sysconfig, dp.uart0, (tx, rx), 115200.Hz(), &clocks);
|
||||
let uarta =
|
||||
uart::Uart::new(dp.uart0, portg.pg0, portg.pg1, &clocks, 115200.Hz().into()).unwrap();
|
||||
|
||||
let (mut tx_uart_a, rx_uart_a) = uarta.split();
|
||||
let (prod_uart_a, cons_uart_a) = QUEUE_UART_A.take().split();
|
||||
|
@ -21,8 +21,10 @@ use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Instant, Ticker};
|
||||
use embedded_io_async::Write;
|
||||
use va416xx_hal::{
|
||||
gpio::PinsG,
|
||||
clock::ClockConfigurator,
|
||||
gpio::{Output, PinState},
|
||||
pac::{self, interrupt},
|
||||
pins::PinsG,
|
||||
prelude::*,
|
||||
time::Hertz,
|
||||
uart::{
|
||||
@ -44,34 +46,22 @@ const STR_LIST: &[&str] = &[
|
||||
async fn main(_spawner: Spawner) {
|
||||
defmt::println!("-- VA108xx Async UART TX Demo --");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks,
|
||||
);
|
||||
}
|
||||
va416xx_embassy::init(dp.tim15, dp.tim14, &clocks);
|
||||
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let mut led = portg.pg5.into_readable_push_pull_output();
|
||||
let pinsg = PinsG::new(dp.portg);
|
||||
let mut led = Output::new(pinsg.pg5, PinState::Low);
|
||||
|
||||
let tx = portg.pg0.into_funsel_1();
|
||||
let rx = portg.pg1.into_funsel_1();
|
||||
|
||||
let uarta = uart::Uart::new(&mut dp.sysconfig, dp.uart0, (tx, rx), 115200.Hz(), &clocks);
|
||||
let uarta =
|
||||
uart::Uart::new(dp.uart0, pinsg.pg0, pinsg.pg1, &clocks, 115200.Hz().into()).unwrap();
|
||||
let (tx, _rx) = uarta.split();
|
||||
let mut async_tx = TxAsync::new(tx);
|
||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||
|
@ -27,15 +27,15 @@ use ringbuf::{
|
||||
StaticRb,
|
||||
};
|
||||
use va416xx_hal::{
|
||||
gpio::{OutputReadablePushPull, Pin, PinsG, PG5},
|
||||
clock::ClockConfigurator,
|
||||
gpio::{Output, PinState},
|
||||
pac::{self, interrupt},
|
||||
prelude::*,
|
||||
pins::PinsG,
|
||||
time::Hertz,
|
||||
uart,
|
||||
};
|
||||
|
||||
pub type SharedUart =
|
||||
Mutex<CriticalSectionRawMutex, RefCell<Option<uart::RxWithInterrupt<pac::Uart0>>>>;
|
||||
pub type SharedUart = Mutex<CriticalSectionRawMutex, RefCell<Option<uart::RxWithInterrupt>>>;
|
||||
static RX: SharedUart = Mutex::new(RefCell::new(None));
|
||||
|
||||
const BAUDRATE: u32 = 115200;
|
||||
@ -54,39 +54,27 @@ static RINGBUF: SharedRingBuf = Mutex::new(RefCell::new(None));
|
||||
async fn main(spawner: Spawner) {
|
||||
defmt::println!("VA416xx UART-Embassy Example");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks,
|
||||
)
|
||||
};
|
||||
va416xx_embassy::init(dp.tim15, dp.tim14, &clocks);
|
||||
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
|
||||
let tx = portg.pg0.into_funsel_1();
|
||||
let rx = portg.pg1.into_funsel_1();
|
||||
let portg = PinsG::new(dp.portg);
|
||||
|
||||
let uart0 = uart::Uart::new(
|
||||
&mut dp.sysconfig,
|
||||
dp.uart0,
|
||||
(tx, rx),
|
||||
Hertz::from_raw(BAUDRATE),
|
||||
portg.pg0,
|
||||
portg.pg1,
|
||||
&clocks,
|
||||
);
|
||||
Hertz::from_raw(BAUDRATE).into(),
|
||||
)
|
||||
.unwrap();
|
||||
let (mut tx, rx) = uart0.split();
|
||||
let mut rx = rx.into_rx_with_irq();
|
||||
rx.start();
|
||||
@ -97,7 +85,7 @@ async fn main(spawner: Spawner) {
|
||||
static_rb.borrow_mut().replace(StaticRb::default());
|
||||
});
|
||||
|
||||
let led = portg.pg5.into_readable_push_pull_output();
|
||||
let led = Output::new(portg.pg5, PinState::Low);
|
||||
let mut ticker = Ticker::every(Duration::from_millis(50));
|
||||
let mut processing_buf: [u8; RING_BUF_SIZE] = [0; RING_BUF_SIZE];
|
||||
let mut read_bytes = 0;
|
||||
@ -117,7 +105,7 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn blinky(mut led: Pin<PG5, OutputReadablePushPull>) {
|
||||
async fn blinky(mut led: Output) {
|
||||
let mut ticker = Ticker::every(Duration::from_millis(500));
|
||||
loop {
|
||||
led.toggle();
|
||||
|
@ -8,7 +8,13 @@ use defmt_rtt as _;
|
||||
use embassy_example::EXTCLK_FREQ;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Instant, Ticker};
|
||||
use va416xx_hal::{gpio::PinsG, pac, prelude::*, time::Hertz};
|
||||
use va416xx_hal::{
|
||||
clock::ClockConfigurator,
|
||||
gpio::{Output, PinState},
|
||||
pac,
|
||||
pins::PinsG,
|
||||
time::Hertz,
|
||||
};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "custom-irqs")] {
|
||||
@ -22,40 +28,32 @@ cfg_if::cfg_if! {
|
||||
async fn main(_spawner: Spawner) {
|
||||
defmt::println!("VA416xx Embassy Demo");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Initialize the systick interrupt & obtain the token to prove that we did
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(Hertz::from_raw(EXTCLK_FREQ))
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "custom-irqs"))] {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks
|
||||
);
|
||||
} else {
|
||||
va416xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irq_router,
|
||||
dp.tim12,
|
||||
dp.tim11,
|
||||
&clocks
|
||||
);
|
||||
}
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "custom-irqs"))] {
|
||||
va416xx_embassy::init(
|
||||
dp.tim15,
|
||||
dp.tim14,
|
||||
&clocks
|
||||
);
|
||||
} else {
|
||||
va416xx_embassy::init(
|
||||
dp.tim12,
|
||||
dp.tim11,
|
||||
&clocks
|
||||
);
|
||||
}
|
||||
}
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let mut led = portg.pg5.into_readable_push_pull_output();
|
||||
let pinsg = PinsG::new(dp.portg);
|
||||
let mut led = Output::new(pinsg.pg5, PinState::Low);
|
||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||
loop {
|
||||
ticker.next().await;
|
||||
|
@ -5,14 +5,11 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
cortex-m-rt = "0.7"
|
||||
embedded-hal = "1"
|
||||
defmt-rtt = "0.4"
|
||||
defmt = "1"
|
||||
panic-probe = { version = "1", features = ["defmt"] }
|
||||
rtic-sync = { version = "1.3", features = ["defmt-03"] }
|
||||
|
||||
va416xx-hal = { version = "0.5", features = ["va41630"] }
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["va41630"] }
|
||||
|
||||
[dependencies.rtic]
|
||||
version = "2"
|
||||
|
@ -17,14 +17,15 @@ mod app {
|
||||
use rtic_monotonics::systick::prelude::*;
|
||||
use rtic_monotonics::Monotonic;
|
||||
use va416xx_hal::{
|
||||
gpio::{OutputReadablePushPull, Pin, PinsG, PG5},
|
||||
clock::ClockConfigurator,
|
||||
gpio::{Output, PinState},
|
||||
pac,
|
||||
prelude::*,
|
||||
pins::PinsG,
|
||||
};
|
||||
|
||||
#[local]
|
||||
struct Local {
|
||||
led: Pin<PG5, OutputReadablePushPull>,
|
||||
led: Output,
|
||||
}
|
||||
|
||||
#[shared]
|
||||
@ -33,19 +34,16 @@ mod app {
|
||||
rtic_monotonics::systick_monotonic!(Mono, 1_000);
|
||||
|
||||
#[init]
|
||||
fn init(mut cx: init::Context) -> (Shared, Local) {
|
||||
fn init(cx: init::Context) -> (Shared, Local) {
|
||||
defmt::println!("-- Vorago RTIC example application --");
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = cx
|
||||
.device
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(cx.device.clkgen)
|
||||
.xtal_n_clk_with_src_freq(EXTCLK_FREQ)
|
||||
.freeze(&mut cx.device.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
Mono::start(cx.core.SYST, clocks.sysclk().raw());
|
||||
let portg = PinsG::new(&mut cx.device.sysconfig, cx.device.portg);
|
||||
let led = portg.pg5.into_readable_push_pull_output();
|
||||
let pinsg = PinsG::new(cx.device.portg);
|
||||
let led = Output::new(pinsg.pg5, PinState::Low);
|
||||
blinky::spawn().ok();
|
||||
(Shared {}, Local { led })
|
||||
}
|
||||
|
@ -17,20 +17,12 @@ embedded-io = "0.6"
|
||||
panic-halt = "1"
|
||||
accelerometer = "0.12"
|
||||
|
||||
va416xx-hal = { version = "0.5", features = ["va41630", "defmt"] }
|
||||
va416xx-hal = { version = "0.5", path = "../../va416xx-hal", features = ["va41630", "defmt"] }
|
||||
|
||||
[dependencies.vorago-peb1]
|
||||
path = "../../vorago-peb1"
|
||||
optional = true
|
||||
|
||||
[dependencies.rtic]
|
||||
version = "2"
|
||||
features = ["thumbv7-backend"]
|
||||
|
||||
[dependencies.rtic-monotonics]
|
||||
version = "2"
|
||||
features = ["cortex-m-systick"]
|
||||
|
||||
[features]
|
||||
default = ["va41630"]
|
||||
va41630 = ["va416xx-hal/va41630", "has-adc-dac"]
|
||||
|
@ -12,8 +12,8 @@ use embedded_hal::delay::DelayNs;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::{
|
||||
adc::{Adc, ChannelSelect, ChannelValue, MultiChannelSelect},
|
||||
clock::ClockConfigurator,
|
||||
pac,
|
||||
prelude::*,
|
||||
timer::CountdownTimer,
|
||||
};
|
||||
|
||||
@ -24,17 +24,15 @@ const ENABLE_BUF_PRINTOUT: bool = false;
|
||||
fn main() -> ! {
|
||||
defmt::println!("VA416xx ADC example");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
|
||||
let adc = Adc::new_with_channel_tag(&mut dp.sysconfig, dp.adc, &clocks);
|
||||
let mut delay_provider = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||
let adc = Adc::new_with_channel_tag(dp.adc, &clocks);
|
||||
let mut delay = CountdownTimer::new(dp.tim0, &clocks);
|
||||
let mut read_buf: [ChannelValue; 8] = [ChannelValue::default(); 8];
|
||||
loop {
|
||||
let single_value = adc
|
||||
@ -70,6 +68,6 @@ fn main() -> ! {
|
||||
assert_eq!(read_buf[0].channel(), ChannelSelect::AnIn0);
|
||||
assert_eq!(read_buf[1].channel(), ChannelSelect::AnIn2);
|
||||
assert_eq!(read_buf[2].channel(), ChannelSelect::TempSensor);
|
||||
delay_provider.delay_ms(500);
|
||||
delay.delay_ms(500);
|
||||
}
|
||||
}
|
||||
|
@ -8,15 +8,19 @@ use panic_probe as _;
|
||||
use defmt_rtt as _;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use va416xx_hal::{gpio::PinsG, pac};
|
||||
use va416xx_hal::{
|
||||
gpio::{Output, PinState},
|
||||
pac,
|
||||
pins::PinsG,
|
||||
};
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("VA416xx HAL blinky example");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let portg = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let mut led = portg.pg5.into_readable_push_pull_output();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
let portg = PinsG::new(dp.portg);
|
||||
let mut led = Output::new(portg.pg5, PinState::Low);
|
||||
loop {
|
||||
cortex_m::asm::delay(2_000_000);
|
||||
led.toggle();
|
||||
|
@ -10,7 +10,7 @@ use defmt_rtt as _;
|
||||
use cortex_m_rt::entry;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::{adc::Adc, dac::Dac, pac, prelude::*, timer::CountdownTimer};
|
||||
use va416xx_hal::{adc::Adc, clock::ClockConfigurator, dac::Dac, pac, timer::CountdownTimer};
|
||||
|
||||
const DAC_INCREMENT: u16 = 256;
|
||||
|
||||
@ -30,18 +30,15 @@ const APP_MODE: AppMode = AppMode::DacAndAdc;
|
||||
fn main() -> ! {
|
||||
defmt::println!("VA416xx DAC/ADC example");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
let mut dac = None;
|
||||
if APP_MODE == AppMode::DacOnly || APP_MODE == AppMode::DacAndAdc {
|
||||
dac = Some(Dac::new(
|
||||
&mut dp.sysconfig,
|
||||
dp.dac0,
|
||||
va416xx_hal::dac::DacSettling::Apb2Times100,
|
||||
&clocks,
|
||||
@ -49,12 +46,12 @@ fn main() -> ! {
|
||||
}
|
||||
let mut adc = None;
|
||||
if APP_MODE == AppMode::AdcOnly || APP_MODE == AppMode::DacAndAdc {
|
||||
adc = Some(Adc::new(&mut dp.sysconfig, dp.adc, &clocks));
|
||||
adc = Some(Adc::new(dp.adc, &clocks));
|
||||
}
|
||||
let mut delay_provider = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||
let mut delay_provider = CountdownTimer::new(dp.tim0, &clocks);
|
||||
let mut current_val = 0;
|
||||
loop {
|
||||
if let Some(dac) = &dac {
|
||||
if let Some(dac) = &mut dac {
|
||||
defmt::info!("loading DAC with value {}", current_val);
|
||||
dac.load_and_trigger_manually(current_val)
|
||||
.expect("loading DAC value failed");
|
||||
|
@ -6,6 +6,7 @@
|
||||
use panic_probe as _;
|
||||
// Import logger.
|
||||
use defmt_rtt as _;
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
|
||||
use core::cell::Cell;
|
||||
|
||||
@ -15,11 +16,8 @@ use embedded_hal::delay::DelayNs;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::dma::{Dma, DmaCfg, DmaChannel, DmaCtrlBlock};
|
||||
use va416xx_hal::irq_router::enable_and_init_irq_router;
|
||||
use va416xx_hal::pac::{self, interrupt};
|
||||
use va416xx_hal::timer::CountdownTimer;
|
||||
use va416xx_hal::{
|
||||
pac::{self, interrupt},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
static DMA_DONE_FLAG: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
|
||||
static DMA_ACTIVE_FLAG: Mutex<Cell<bool>> = Mutex::new(Cell::new(false));
|
||||
@ -40,26 +38,23 @@ static mut DMA_DEST_BUF: [u16; 36] = [0; 36];
|
||||
fn main() -> ! {
|
||||
defmt::println!("VA416xx DMA example");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
enable_and_init_irq_router(&mut dp.sysconfig, &dp.irq_router);
|
||||
enable_and_init_irq_router();
|
||||
// Safety: The DMA control block has an alignment rule of 128 and we constructed it directly
|
||||
// statically.
|
||||
let dma = Dma::new(
|
||||
&mut dp.sysconfig,
|
||||
dp.dma,
|
||||
DmaCfg::default(),
|
||||
core::ptr::addr_of_mut!(DMA_CTRL_BLOCK),
|
||||
)
|
||||
.expect("error creating DMA");
|
||||
let (mut dma0, _, _, _) = dma.split();
|
||||
let mut delay_ms = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||
let mut delay_ms = CountdownTimer::new(dp.tim0, &clocks);
|
||||
let mut src_buf_8_bit: [u8; 65] = [0; 65];
|
||||
let mut dest_buf_8_bit: [u8; 65] = [0; 65];
|
||||
let mut src_buf_32_bit: [u32; 17] = [0; 17];
|
||||
@ -90,7 +85,7 @@ fn transfer_example_8_bit(
|
||||
src_buf: &mut [u8; 65],
|
||||
dest_buf: &mut [u8; 65],
|
||||
dma0: &mut DmaChannel,
|
||||
delay_ms: &mut CountdownTimer<pac::Tim0>,
|
||||
delay: &mut CountdownTimer,
|
||||
) {
|
||||
(0..64).for_each(|i| {
|
||||
src_buf[i] = i as u8;
|
||||
@ -132,7 +127,7 @@ fn transfer_example_8_bit(
|
||||
defmt::info!("8-bit transfer done");
|
||||
break;
|
||||
}
|
||||
delay_ms.delay_ms(1);
|
||||
delay.delay_ms(1);
|
||||
}
|
||||
(0..64).for_each(|i| {
|
||||
assert_eq!(dest_buf[i], i as u8);
|
||||
@ -142,7 +137,7 @@ fn transfer_example_8_bit(
|
||||
dest_buf.fill(0);
|
||||
}
|
||||
|
||||
fn transfer_example_16_bit(dma0: &mut DmaChannel, delay_ms: &mut CountdownTimer<pac::Tim0>) {
|
||||
fn transfer_example_16_bit(dma0: &mut DmaChannel, delay_ms: &mut CountdownTimer) {
|
||||
let dest_buf_ref = unsafe { &mut *core::ptr::addr_of_mut!(DMA_DEST_BUF[0..33]) };
|
||||
unsafe {
|
||||
// Set values scaled from 0 to 65535 to verify this is really a 16-bit transfer.
|
||||
@ -207,7 +202,7 @@ fn transfer_example_32_bit(
|
||||
src_buf: &mut [u32; 17],
|
||||
dest_buf: &mut [u32; 17],
|
||||
dma0: &mut DmaChannel,
|
||||
delay_ms: &mut CountdownTimer<pac::Tim0>,
|
||||
delay_ms: &mut CountdownTimer,
|
||||
) {
|
||||
// Set values scaled from 0 to 65535 to verify this is really a 16-bit transfer.
|
||||
(0..16).for_each(|i| {
|
||||
|
@ -12,10 +12,11 @@ use cortex_m_rt::entry;
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::{
|
||||
clock::ClockConfigurator,
|
||||
i2c,
|
||||
pac::{self},
|
||||
prelude::*,
|
||||
pwm::CountdownTimer,
|
||||
timer::CountdownTimer,
|
||||
};
|
||||
use vorago_peb1::lis2dh12::{self, detect_i2c_addr, FullScale, Odr};
|
||||
|
||||
@ -31,21 +32,18 @@ fn main() -> ! {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
defmt::println!("-- Vorago PEB1 accelerometer example --");
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
let mut i2c_master = i2c::I2cMaster::new(
|
||||
dp.i2c0,
|
||||
&mut dp.sysconfig,
|
||||
i2c::MasterConfig::default(),
|
||||
&clocks,
|
||||
i2c::MasterConfig::default(),
|
||||
i2c::I2cSpeed::Regular100khz,
|
||||
)
|
||||
.expect("creating I2C master failed");
|
||||
let mut delay_provider = CountdownTimer::new(&mut dp.sysconfig, dp.tim1, &clocks);
|
||||
let mut delay_provider = CountdownTimer::new(dp.tim1, &clocks);
|
||||
// Detect the I2C address of the accelerometer by scanning all possible values.
|
||||
let slave_addr = detect_i2c_addr(&mut i2c_master).expect("detecting I2C address failed");
|
||||
// Create the accelerometer driver using the PEB1 BSP.
|
||||
@ -53,7 +51,7 @@ fn main() -> ! {
|
||||
.expect("creating accelerometer driver failed");
|
||||
let device_id = accelerometer.get_device_id().unwrap();
|
||||
accelerometer
|
||||
.set_mode(lis2dh12::reg::Mode::Normal)
|
||||
.set_mode(lis2dh12::Mode::Normal)
|
||||
.expect("setting mode failed");
|
||||
accelerometer
|
||||
.set_odr(Odr::Hz100)
|
||||
@ -65,7 +63,7 @@ fn main() -> ! {
|
||||
accelerometer
|
||||
.enable_temp(true)
|
||||
.expect("enabling temperature sensor failed");
|
||||
rprintln!("Device ID: 0x{:02X}", device_id);
|
||||
defmt::info!("Device ID: 0x{:02X}", device_id);
|
||||
// Start reading the accelerometer periodically.
|
||||
loop {
|
||||
let temperature = accelerometer
|
||||
@ -76,13 +74,25 @@ fn main() -> ! {
|
||||
let value = accelerometer
|
||||
.accel_norm()
|
||||
.expect("reading normalized accelerometer data failed");
|
||||
rprintln!("Accel Norm F32x3: {:.06?} | Temp {} °C", value, temperature);
|
||||
defmt::info!(
|
||||
"Accel Norm F32x3 {{ x: {:05}, y: {:05}, z:{:05}}} | Temp {} °C",
|
||||
value.x,
|
||||
value.y,
|
||||
value.z,
|
||||
temperature
|
||||
);
|
||||
}
|
||||
DisplayMode::Raw => {
|
||||
let value_raw = accelerometer
|
||||
.accel_raw()
|
||||
.expect("reading raw accelerometer data failed");
|
||||
rprintln!("Accel Raw F32x3: {:?} | Temp {} °C", value_raw, temperature);
|
||||
defmt::info!(
|
||||
"Accel Raw I32x3 {{ x: {:05}, y: {:05}, z:{:05}}} | Temp {} °C",
|
||||
value_raw.x,
|
||||
value_raw.y,
|
||||
value_raw.z,
|
||||
temperature
|
||||
);
|
||||
}
|
||||
}
|
||||
delay_provider.delay_ms(100);
|
||||
|
@ -1,4 +1,6 @@
|
||||
//! Simple PWM example
|
||||
//!
|
||||
//! Outputs a PWM waveform on pin PG2.
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
@ -10,41 +12,34 @@ use panic_probe as _;
|
||||
use defmt_rtt as _;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::{
|
||||
gpio::PinsA,
|
||||
clock::ClockConfigurator,
|
||||
pac,
|
||||
pins::PinsG,
|
||||
prelude::*,
|
||||
pwm::{self, get_duty_from_percent, PwmA, PwmB, ReducedPwmPin},
|
||||
pwm::{get_duty_from_percent, PwmA, PwmB, PwmPin},
|
||||
timer::CountdownTimer,
|
||||
};
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("-- VA108xx PWM example application--");
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
|
||||
let pinsa = PinsA::new(&mut dp.sysconfig, dp.porta);
|
||||
let mut pwm = pwm::PwmPin::new(
|
||||
(pinsa.pa3.into_funsel_1(), dp.tim3),
|
||||
&mut dp.sysconfig,
|
||||
&clocks,
|
||||
10.Hz(),
|
||||
);
|
||||
let mut delay_timer = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||
let pinsg = PinsG::new(dp.portg);
|
||||
let mut pwm = PwmPin::new(pinsg.pg2, dp.tim9, &clocks, 10.Hz()).unwrap();
|
||||
let mut delay_timer = CountdownTimer::new(dp.tim0, &clocks);
|
||||
let mut current_duty_cycle = 0.0;
|
||||
pwm.set_duty_cycle(get_duty_from_percent(current_duty_cycle))
|
||||
.unwrap();
|
||||
pwm.enable();
|
||||
|
||||
// Delete type information, increased code readibility for the rest of the code
|
||||
let mut reduced_pin = ReducedPwmPin::from(pwm);
|
||||
loop {
|
||||
let mut counter = 0;
|
||||
// Increase duty cycle continuously
|
||||
@ -56,8 +51,7 @@ fn main() -> ! {
|
||||
defmt::info!("current duty cycle: {}", current_duty_cycle);
|
||||
}
|
||||
|
||||
reduced_pin
|
||||
.set_duty_cycle(get_duty_from_percent(current_duty_cycle))
|
||||
pwm.set_duty_cycle(get_duty_from_percent(current_duty_cycle))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@ -66,7 +60,7 @@ fn main() -> ! {
|
||||
current_duty_cycle = 0.0;
|
||||
let mut upper_limit = 1.0;
|
||||
let mut lower_limit = 0.0;
|
||||
let mut pwmb: ReducedPwmPin<PwmB> = ReducedPwmPin::from(reduced_pin);
|
||||
let mut pwmb: PwmPin<PwmB> = PwmPin::from(pwm);
|
||||
pwmb.set_pwmb_lower_limit(get_duty_from_percent(lower_limit));
|
||||
pwmb.set_pwmb_upper_limit(get_duty_from_percent(upper_limit));
|
||||
while lower_limit < 0.5 {
|
||||
@ -78,6 +72,6 @@ fn main() -> ! {
|
||||
defmt::info!("Lower limit: {}", pwmb.pwmb_lower_limit());
|
||||
defmt::info!("Upper limit: {}", pwmb.pwmb_upper_limit());
|
||||
}
|
||||
reduced_pin = ReducedPwmPin::<PwmA>::from(pwmb);
|
||||
pwm = PwmPin::<PwmA>::from(pwmb);
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Code to test RTT logger functionality.
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
// Import panic provider.
|
||||
use panic_probe as _;
|
||||
// Import logger.
|
||||
use defmt_rtt as _;
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use va416xx_hal::pac;
|
||||
|
||||
// Mask for the LED
|
||||
const LED_PG5: u32 = 1 << 5;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("VA416xx RTT Demo");
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
// Enable all peripheral clocks
|
||||
dp.sysconfig
|
||||
.peripheral_clk_enable()
|
||||
.modify(|_, w| unsafe { w.bits(0xffffffff) });
|
||||
dp.portg.dir().modify(|_, w| unsafe { w.bits(LED_PG5) });
|
||||
dp.portg
|
||||
.datamask()
|
||||
.modify(|_, w| unsafe { w.bits(LED_PG5) });
|
||||
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
defmt::info!("{}: Hello, world!", counter);
|
||||
// Still toggle LED. If there are issues with the RTT log, the LED
|
||||
// blinking ensures that the application is actually running.
|
||||
dp.portg.togout().write(|w| unsafe { w.bits(LED_PG5) });
|
||||
counter += 1;
|
||||
cortex_m::asm::delay(10_000_000);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
//! If you do not use the loopback mode, MOSI and MISO need to be tied together on the board.
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
use embedded_hal::delay::DelayNs;
|
||||
// Import panic provider.
|
||||
use panic_probe as _;
|
||||
// Import logger.
|
||||
@ -11,11 +12,12 @@ use defmt_rtt as _;
|
||||
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::timer::CountdownTimer;
|
||||
use va416xx_hal::{
|
||||
gpio::{PinsB, PinsC},
|
||||
pac,
|
||||
prelude::*,
|
||||
pins::{PinsB, PinsC},
|
||||
spi::SpiConfig,
|
||||
time::Hertz,
|
||||
};
|
||||
@ -37,29 +39,20 @@ const FILL_WORD: u8 = 0x0f;
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("-- VA108xx SPI example application--");
|
||||
let cp = cortex_m::Peripherals::take().unwrap();
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
let mut delay_sysclk = cortex_m::delay::Delay::new(cp.SYST, clocks.apb0().raw());
|
||||
let mut delay = CountdownTimer::new(dp.tim1, &clocks);
|
||||
|
||||
let pins_b = PinsB::new(&mut dp.sysconfig, dp.portb);
|
||||
let pins_c = PinsC::new(&mut dp.sysconfig, dp.portc);
|
||||
// Configure SPI0 pins.
|
||||
let (sck, miso, mosi) = (
|
||||
pins_b.pb15.into_funsel_1(),
|
||||
pins_c.pc0.into_funsel_1(),
|
||||
pins_c.pc1.into_funsel_1(),
|
||||
);
|
||||
let pins_b = PinsB::new(dp.portb);
|
||||
let pins_c = PinsC::new(dp.portc);
|
||||
|
||||
let mut spi_cfg = SpiConfig::default()
|
||||
.clk_cfg(
|
||||
SpiClkConfig::from_clk(Hertz::from_raw(SPI_SPEED_KHZ), &clocks)
|
||||
SpiClkConfig::from_clks(&clocks, Hertz::from_raw(SPI_SPEED_KHZ))
|
||||
.expect("invalid target clock"),
|
||||
)
|
||||
.mode(SPI_MODE)
|
||||
@ -68,13 +61,7 @@ fn main() -> ! {
|
||||
spi_cfg = spi_cfg.loopback(true)
|
||||
}
|
||||
// Create SPI peripheral.
|
||||
let mut spi0 = Spi::new(
|
||||
&mut dp.sysconfig,
|
||||
&clocks,
|
||||
dp.spi0,
|
||||
(sck, miso, mosi),
|
||||
spi_cfg,
|
||||
);
|
||||
let mut spi0 = Spi::new(dp.spi0, (pins_b.pb15, pins_c.pc0, pins_c.pc1), spi_cfg).unwrap();
|
||||
spi0.set_fill_word(FILL_WORD);
|
||||
loop {
|
||||
let tx_buf: [u8; 4] = [1, 2, 3, 0];
|
||||
@ -95,6 +82,6 @@ fn main() -> ! {
|
||||
spi0.transfer(&mut rx_buf, &tx_buf)
|
||||
.expect("SPI transfer failed");
|
||||
assert_eq!(rx_buf, [1, 2, 3, 0]);
|
||||
delay_sysclk.delay_ms(500);
|
||||
delay.delay_ms(500);
|
||||
}
|
||||
}
|
||||
|
@ -6,16 +6,16 @@ use panic_probe as _;
|
||||
// Import logger.
|
||||
use defmt_rtt as _;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use cortex_m::asm;
|
||||
use cortex_m_rt::entry;
|
||||
use critical_section::Mutex;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::{
|
||||
clock::ClockConfigurator,
|
||||
irq_router::enable_and_init_irq_router,
|
||||
pac::{self, interrupt},
|
||||
prelude::*,
|
||||
timer::{default_ms_irq_handler, set_up_ms_tick, CountdownTimer, MS_COUNTER},
|
||||
timer::CountdownTimer,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -24,32 +24,33 @@ enum LibType {
|
||||
Hal,
|
||||
}
|
||||
|
||||
static SEC_COUNTER: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
|
||||
static MS_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
static SEC_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
let mut last_ms = 0;
|
||||
defmt::println!("-- Vorago system ticks using timers --");
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
enable_and_init_irq_router(&mut dp.sysconfig, &dp.irq_router);
|
||||
let _ = set_up_ms_tick(&mut dp.sysconfig, dp.tim0, &clocks);
|
||||
let mut second_timer = CountdownTimer::new(&mut dp.sysconfig, dp.tim1, &clocks);
|
||||
second_timer.listen();
|
||||
enable_and_init_irq_router();
|
||||
let mut ms_timer = CountdownTimer::new(dp.tim0, &clocks);
|
||||
ms_timer.enable_interrupt(true);
|
||||
ms_timer.start(1.Hz());
|
||||
let mut second_timer = CountdownTimer::new(dp.tim1, &clocks);
|
||||
second_timer.enable_interrupt(true);
|
||||
second_timer.start(1.Hz());
|
||||
loop {
|
||||
let current_ms = critical_section::with(|cs| MS_COUNTER.borrow(cs).get());
|
||||
let current_ms = MS_COUNTER.load(Ordering::Relaxed);
|
||||
if current_ms >= last_ms + 1000 {
|
||||
// To prevent drift.
|
||||
last_ms += 1000;
|
||||
defmt::info!("MS counter: {}", current_ms);
|
||||
let second = critical_section::with(|cs| SEC_COUNTER.borrow(cs).get());
|
||||
let second = SEC_COUNTER.load(Ordering::Relaxed);
|
||||
defmt::info!("Second counter: {}", second);
|
||||
}
|
||||
asm::delay(1000);
|
||||
@ -59,15 +60,11 @@ fn main() -> ! {
|
||||
#[interrupt]
|
||||
#[allow(non_snake_case)]
|
||||
fn TIM0() {
|
||||
default_ms_irq_handler()
|
||||
MS_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
#[allow(non_snake_case)]
|
||||
fn TIM1() {
|
||||
critical_section::with(|cs| {
|
||||
let mut sec = SEC_COUNTER.borrow(cs).get();
|
||||
sec += 1;
|
||||
SEC_COUNTER.borrow(cs).set(sec);
|
||||
});
|
||||
SEC_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
|
@ -11,35 +11,33 @@ use cortex_m_rt::entry;
|
||||
use embedded_hal_nb::serial::Read;
|
||||
use embedded_io::Write;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::clock::ClkgenExt;
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
use va416xx_hal::pins::PinsG;
|
||||
use va416xx_hal::time::Hertz;
|
||||
use va416xx_hal::{gpio::PinsG, pac, uart};
|
||||
use va416xx_hal::{pac, uart};
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
defmt::println!("-- VA416xx UART example application--");
|
||||
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
|
||||
let gpiob = PinsG::new(&mut dp.sysconfig, dp.portg);
|
||||
let tx = gpiob.pg0.into_funsel_1();
|
||||
let rx = gpiob.pg1.into_funsel_1();
|
||||
let gpiog = PinsG::new(dp.portg);
|
||||
|
||||
let uart0 = uart::Uart::new(
|
||||
&mut dp.sysconfig,
|
||||
dp.uart0,
|
||||
(tx, rx),
|
||||
Hertz::from_raw(115200),
|
||||
gpiog.pg0,
|
||||
gpiog.pg1,
|
||||
&clocks,
|
||||
);
|
||||
Hertz::from_raw(115200).into(),
|
||||
)
|
||||
.unwrap();
|
||||
let (mut tx, mut rx) = uart0.split();
|
||||
writeln!(tx, "Hello World\n\r").unwrap();
|
||||
loop {
|
||||
|
@ -5,17 +5,16 @@
|
||||
use panic_probe as _;
|
||||
// Import logger.
|
||||
use defmt_rtt as _;
|
||||
use va416xx_hal::clock::ClockConfigurator;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use cortex_m_rt::entry;
|
||||
use critical_section::Mutex;
|
||||
use simple_examples::peb1;
|
||||
use va416xx_hal::irq_router::enable_and_init_irq_router;
|
||||
use va416xx_hal::pac::{self, interrupt};
|
||||
use va416xx_hal::prelude::*;
|
||||
use va416xx_hal::wdt::Wdt;
|
||||
|
||||
static WDT_INTRPT_COUNT: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
|
||||
static WDT_INTRPT_COUNT: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[allow(dead_code)]
|
||||
@ -33,33 +32,37 @@ const WDT_ROLLOVER_MS: u32 = 100;
|
||||
fn main() -> ! {
|
||||
defmt::println!("-- VA416xx WDT example application--");
|
||||
let cp = cortex_m::Peripherals::take().unwrap();
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Use the external clock connected to XTAL_N.
|
||||
let clocks = dp
|
||||
.clkgen
|
||||
.constrain()
|
||||
let clocks = ClockConfigurator::new(dp.clkgen)
|
||||
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
|
||||
.freeze(&mut dp.sysconfig)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
enable_and_init_irq_router(&mut dp.sysconfig, &dp.irq_router);
|
||||
let mut delay_sysclk = cortex_m::delay::Delay::new(cp.SYST, clocks.apb0().raw());
|
||||
enable_and_init_irq_router();
|
||||
let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.apb0().raw());
|
||||
|
||||
let mut last_interrupt_counter = 0;
|
||||
let mut wdt_ctrl = Wdt::start(&mut dp.sysconfig, dp.watch_dog, &clocks, WDT_ROLLOVER_MS);
|
||||
let mut wdt_ctrl = Wdt::start(dp.watch_dog, &clocks, WDT_ROLLOVER_MS);
|
||||
wdt_ctrl.enable_reset();
|
||||
let log_divisor = 25;
|
||||
let mut counter: u32 = 0;
|
||||
loop {
|
||||
counter = counter.wrapping_add(1);
|
||||
if counter % log_divisor == 0 {
|
||||
defmt::info!("wdt example main loop alive");
|
||||
}
|
||||
if TEST_MODE != TestMode::AllowReset {
|
||||
wdt_ctrl.feed();
|
||||
}
|
||||
let interrupt_counter = critical_section::with(|cs| WDT_INTRPT_COUNT.borrow(cs).get());
|
||||
let interrupt_counter = WDT_INTRPT_COUNT.load(Ordering::Relaxed);
|
||||
if interrupt_counter > last_interrupt_counter {
|
||||
defmt::info!("interrupt counter has increased to {}", interrupt_counter);
|
||||
last_interrupt_counter = interrupt_counter;
|
||||
}
|
||||
match TEST_MODE {
|
||||
TestMode::FedByMain => delay_sysclk.delay_ms(WDT_ROLLOVER_MS / 5),
|
||||
TestMode::FedByIrq => delay_sysclk.delay_ms(WDT_ROLLOVER_MS),
|
||||
TestMode::FedByMain => delay.delay_ms(WDT_ROLLOVER_MS / 5),
|
||||
TestMode::FedByIrq => delay.delay_ms(WDT_ROLLOVER_MS),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@ -68,11 +71,7 @@ fn main() -> ! {
|
||||
#[interrupt]
|
||||
#[allow(non_snake_case)]
|
||||
fn WATCHDOG() {
|
||||
critical_section::with(|cs| {
|
||||
WDT_INTRPT_COUNT
|
||||
.borrow(cs)
|
||||
.set(WDT_INTRPT_COUNT.borrow(cs).get() + 1);
|
||||
});
|
||||
WDT_INTRPT_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||
let wdt = unsafe { pac::WatchDog::steal() };
|
||||
// Clear interrupt.
|
||||
if TEST_MODE != TestMode::AllowReset {
|
||||
|
Reference in New Issue
Block a user