move to updated API

This commit is contained in:
2025-04-16 14:35:57 +02:00
parent dfe34e965f
commit 121b467fb9
49 changed files with 751 additions and 986 deletions

View File

@ -29,7 +29,7 @@ embassy-executor = { version = "0.7", features = [
"executor-interrupt"
]}
va108xx-hal = { version = "0.11", features = ["defmt"] }
va108xx-hal = { version = "0.11", path = "../../va108xx-hal", features = ["defmt"] }
va108xx-embassy = { version = "0.2" }
[features]

View File

@ -12,11 +12,10 @@ 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 va108xx_hal::gpio::{
on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, Port,
};
use va108xx_hal::gpio::asynch::{on_interrupt_for_async_gpio_for_port, InputPinAsync};
use va108xx_hal::gpio::{Input, Output, PinState, Port};
use va108xx_hal::pins::{PinsA, PinsB};
use va108xx_hal::{
gpio::{DynPin, PinsA},
pac::{self, interrupt},
prelude::*,
};
@ -71,30 +70,28 @@ async fn main(spawner: Spawner) {
dp.tim22,
);
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
let portb = PinsB::new(&mut dp.sysconfig, dp.portb);
let mut led0 = porta.pa10.into_readable_push_pull_output();
let out_pa0 = porta.pa0.into_readable_push_pull_output();
let in_pa1 = porta.pa1.into_floating_input();
let out_pb22 = portb.pb22.into_readable_push_pull_output();
let in_pb23 = portb.pb23.into_floating_input();
let porta = PinsA::new(dp.porta);
let portb = PinsB::new(dp.portb);
let mut led0 = Output::new(porta.pa10, PinState::Low);
let out_pa0 = Output::new(porta.pa0, PinState::Low);
let in_pa1 = Input::new_floating(porta.pa1);
let out_pb22 = Output::new(portb.pb22, PinState::Low);
let in_pb23 = Input::new_floating(portb.pb23);
let in_pa1_async = InputPinAsync::new(in_pa1, pac::Interrupt::OC10);
let out_pa0_dyn = out_pa0.downgrade();
let in_pb23_async = InputDynPinAsync::new(in_pb23.downgrade(), PB22_TO_PB23_IRQ).unwrap();
let out_pb22_dyn = out_pb22.downgrade();
let in_pb23_async = InputPinAsync::new(in_pb23, PB22_TO_PB23_IRQ);
spawner
.spawn(output_task(
"PA0 to PA1",
out_pa0_dyn,
out_pa0,
CHANNEL_PA0_PA1.receiver(),
))
.unwrap();
spawner
.spawn(output_task(
"PB22 to PB23",
out_pb22_dyn,
out_pb22,
CHANNEL_PB22_TO_PB23.receiver(),
))
.unwrap();
@ -207,7 +204,7 @@ async fn check_pin_to_pin_async_ops(
#[embassy_executor::task(pool_size = 2)]
async fn output_task(
ctx: &'static str,
mut out: DynPin,
mut out: Output,
receiver: Receiver<'static, ThreadModeRawMutex, GpioCmd, 3>,
) {
loop {
@ -216,25 +213,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_high() {
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();
}
}
}

View File

@ -24,13 +24,14 @@ use embedded_io::Write;
use embedded_io_async::Read;
use heapless::spsc::{Consumer, Producer, Queue};
use va108xx_hal::{
gpio::PinsA,
gpio::{Output, PinState},
pac::{self, interrupt},
pins::PinsA,
prelude::*,
uart::{
self, on_interrupt_rx_overwriting,
rx_asynch::{on_interrupt_rx, RxAsync},
Bank, RxAsyncOverwriting, Tx,
RxAsyncOverwriting, Tx, UartId,
},
InterruptConfig,
};
@ -62,34 +63,34 @@ async fn main(spawner: Spawner) {
dp.tim22,
);
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
let mut led0 = porta.pa10.into_readable_push_pull_output();
let mut led1 = porta.pa7.into_readable_push_pull_output();
let mut led2 = porta.pa6.into_readable_push_pull_output();
let porta = PinsA::new(dp.porta);
let mut led0 = Output::new(porta.pa10, PinState::Low);
let mut led1 = Output::new(porta.pa7, PinState::Low);
let mut led2 = Output::new(porta.pa6, PinState::Low);
let tx_uart_a = porta.pa9.into_funsel_2();
let rx_uart_a = porta.pa8.into_funsel_2();
let tx_uart_a = porta.pa9;
let rx_uart_a = porta.pa8;
let uarta = uart::Uart::new_with_interrupt(
&mut dp.sysconfig,
50.MHz(),
dp.uarta,
(tx_uart_a, rx_uart_a),
115200.Hz(),
115200.Hz().into(),
InterruptConfig::new(pac::Interrupt::OC2, true, true),
);
)
.unwrap();
let tx_uart_b = porta.pa3.into_funsel_2();
let rx_uart_b = porta.pa2.into_funsel_2();
let tx_uart_b = porta.pa3;
let rx_uart_b = porta.pa2;
let uartb = uart::Uart::new_with_interrupt(
&mut dp.sysconfig,
50.MHz(),
dp.uartb,
(tx_uart_b, rx_uart_b),
115200.Hz(),
115200.Hz().into(),
InterruptConfig::new(pac::Interrupt::OC3, true, true),
);
)
.unwrap();
let (mut tx_uart_a, rx_uart_a) = uarta.split();
let (tx_uart_b, rx_uart_b) = uartb.split();
let (prod_uart_a, cons_uart_a) = QUEUE_UART_A.take().split();
@ -123,7 +124,7 @@ async fn main(spawner: Spawner) {
}
#[embassy_executor::task]
async fn uart_b_task(mut async_rx: RxAsyncOverwriting<pac::Uartb, 256>, mut tx: Tx<pac::Uartb>) {
async fn uart_b_task(mut async_rx: RxAsyncOverwriting<256>, mut tx: Tx) {
let mut buf = [0u8; 256];
loop {
defmt::info!("Current time UART B: {}", Instant::now().as_secs());
@ -144,7 +145,7 @@ async fn uart_b_task(mut async_rx: RxAsyncOverwriting<pac::Uartb, 256>, mut tx:
fn OC2() {
let mut prod =
critical_section::with(|cs| PRODUCER_UART_A.borrow(cs).borrow_mut().take().unwrap());
let errors = on_interrupt_rx(Bank::A, &mut prod);
let errors = on_interrupt_rx(UartId::A, &mut prod);
critical_section::with(|cs| *PRODUCER_UART_A.borrow(cs).borrow_mut() = Some(prod));
// In a production app, we could use a channel to send the errors to the main task.
if let Err(errors) = errors {
@ -157,7 +158,7 @@ fn OC2() {
fn OC3() {
let mut prod =
critical_section::with(|cs| PRODUCER_UART_B.borrow(cs).borrow_mut().take().unwrap());
let errors = on_interrupt_rx_overwriting(Bank::B, &mut prod, &CONSUMER_UART_B);
let errors = on_interrupt_rx_overwriting(UartId::B, &mut prod, &CONSUMER_UART_B);
critical_section::with(|cs| *PRODUCER_UART_B.borrow(cs).borrow_mut() = Some(prod));
// In a production app, we could use a channel to send the errors to the main task.
if let Err(errors) = errors {

View File

@ -17,10 +17,11 @@ use embassy_executor::Spawner;
use embassy_time::{Duration, Instant, Ticker};
use embedded_io_async::Write;
use va108xx_hal::{
gpio::PinsA,
gpio::{Output, PinState},
pac::{self, interrupt},
pins::PinsA,
prelude::*,
uart::{self, on_interrupt_tx, Bank, TxAsync},
uart::{self, on_interrupt_tx, TxAsync, UartId},
InterruptConfig,
};
@ -49,22 +50,23 @@ async fn main(_spawner: Spawner) {
dp.tim22,
);
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
let mut led0 = porta.pa10.into_readable_push_pull_output();
let mut led1 = porta.pa7.into_readable_push_pull_output();
let mut led2 = porta.pa6.into_readable_push_pull_output();
let porta = PinsA::new(dp.porta);
let tx = porta.pa9.into_funsel_2();
let rx = porta.pa8.into_funsel_2();
let mut led0 = Output::new(porta.pa10, PinState::Low);
let mut led1 = Output::new(porta.pa7, PinState::Low);
let mut led2 = Output::new(porta.pa6, PinState::Low);
let tx = porta.pa9;
let rx = porta.pa8;
let uarta = uart::Uart::new_with_interrupt(
&mut dp.sysconfig,
50.MHz(),
dp.uarta,
(tx, rx),
115200.Hz(),
115200.Hz().into(),
InterruptConfig::new(pac::Interrupt::OC2, true, true),
);
)
.unwrap();
let (tx, _rx) = uarta.split();
let mut async_tx = TxAsync::new(tx);
let mut ticker = Ticker::every(Duration::from_secs(1));
@ -89,5 +91,5 @@ async fn main(_spawner: Spawner) {
#[interrupt]
#[allow(non_snake_case)]
fn OC2() {
on_interrupt_tx(Bank::A);
on_interrupt_tx(UartId::A);
}

View File

@ -12,7 +12,12 @@ cfg_if::cfg_if! {
}
}
use va108xx_hal::{gpio::PinsA, pac, prelude::*};
use va108xx_hal::{
gpio::{Output, PinState},
pac,
pins::PinsA,
prelude::*,
};
const SYSCLK_FREQ: Hertz = Hertz::from_raw(50_000_000);
@ -35,8 +40,6 @@ async fn main(_spawner: Spawner) {
);
} else {
va108xx_embassy::init_with_custom_irqs(
&mut dp.sysconfig,
&dp.irqsel,
SYSCLK_FREQ,
dp.tim23,
dp.tim22,
@ -46,10 +49,10 @@ async fn main(_spawner: Spawner) {
}
}
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
let mut led0 = porta.pa10.into_readable_push_pull_output();
let mut led1 = porta.pa7.into_readable_push_pull_output();
let mut led2 = porta.pa6.into_readable_push_pull_output();
let porta = PinsA::new(dp.porta);
let mut led0 = Output::new(porta.pa10, PinState::Low);
let mut led1 = Output::new(porta.pa7, PinState::Low);
let mut led2 = Output::new(porta.pa6, PinState::Low);
let mut ticker = Ticker::every(Duration::from_secs(1));
loop {
ticker.next().await;

View File

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

View File

@ -9,10 +9,10 @@ mod app {
use rtt_target::{rprintln, rtt_init_default, set_print_channel};
use va108xx_hal::{
clock::{set_clk_div_register, FilterClkSel},
gpio::{FilterType, InterruptEdge, PinsA},
gpio::{FilterType, InterruptEdge},
pac,
prelude::*,
timer::{default_ms_irq_handler, set_up_ms_tick, InterruptConfig},
pins::PinsA,
timer::InterruptConfig,
};
use vorago_reb1::button::Button;
use vorago_reb1::leds::Leds;
@ -61,39 +61,28 @@ mod app {
rprintln!("Using {:?} mode", mode);
let mut dp = cx.device;
let pinsa = PinsA::new(&mut dp.sysconfig, dp.porta);
let pinsa = PinsA::new(dp.porta);
let edge_irq = match mode {
PressMode::Toggle => InterruptEdge::HighToLow,
PressMode::Keep => InterruptEdge::BothEdges,
};
// Configure an edge interrupt on the button and route it to interrupt vector 15
let mut button = Button::new(pinsa.pa11.into_floating_input());
let mut button = Button::new(pinsa.pa11);
if mode == PressMode::Toggle {
// This filter debounces the switch for edge based interrupts
button.configure_filter_type(FilterType::FilterFourClockCycles, FilterClkSel::Clk1);
button.configure_filter_type(FilterType::FilterFourCycles, FilterClkSel::Clk1);
set_clk_div_register(&mut dp.sysconfig, FilterClkSel::Clk1, 50_000);
}
button.configure_and_enable_edge_interrupt(
edge_irq,
InterruptConfig::new(pac::interrupt::OC15, true, true),
);
let mut leds = Leds::new(
pinsa.pa10.into_push_pull_output(),
pinsa.pa7.into_push_pull_output(),
pinsa.pa6.into_push_pull_output(),
);
let mut leds = Leds::new(pinsa.pa10, pinsa.pa7, pinsa.pa6);
for led in leds.iter_mut() {
led.off();
}
set_up_ms_tick(
InterruptConfig::new(pac::Interrupt::OC0, true, true),
&mut dp.sysconfig,
Some(&mut dp.irqsel),
50.MHz(),
dp.tim0,
);
(Shared {}, Local { leds, button, mode })
}
@ -119,11 +108,6 @@ mod app {
}
}
#[task(binds = OC0)]
fn ms_tick(_cx: ms_tick::Context) {
default_ms_irq_handler();
}
fn prompt_mode(mut down_channel: rtt_target::DownChannel) -> PressMode {
rprintln!("Using prompt mode");
rprintln!("Please enter the mode [0: Toggle, 1: Keep]");

View File

@ -20,17 +20,13 @@ mod app {
use rtic_monotonics::Monotonic;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::PinsA,
pac,
prelude::*,
uart::{self, RxWithInterrupt, Tx},
InterruptConfig,
pac, pins::PinsA, prelude::*, uart::{self, RxWithInterrupt, Tx}, InterruptConfig
};
#[local]
struct Local {
rx: RxWithInterrupt<pac::Uarta>,
tx: Tx<pac::Uarta>,
rx: RxWithInterrupt,
tx: Tx,
}
#[shared]
@ -47,19 +43,18 @@ mod app {
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
let mut dp = cx.device;
let gpioa = PinsA::new(&mut dp.sysconfig, dp.porta);
let tx = gpioa.pa9.into_funsel_2();
let rx = gpioa.pa8.into_funsel_2();
let dp = cx.device;
let gpioa = PinsA::new(dp.porta);
let tx = gpioa.pa9;
let rx = gpioa.pa8;
let irq_uart = uart::Uart::new_with_interrupt(
&mut dp.sysconfig,
SYSCLK_FREQ,
dp.uarta,
(tx, rx),
115200.Hz(),
115200.Hz().into(),
InterruptConfig::new(pac::Interrupt::OC3, true, true),
);
).unwrap();
let (tx, rx) = irq_uart.split();
let mut rx = rx.into_rx_with_irq();

View File

@ -11,15 +11,15 @@ mod app {
use rtic_monotonics::Monotonic;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::{OutputReadablePushPull, Pin, PinsA, PA10, PA6, PA7},
pac,
gpio::{Output, PinState},
pac, pins::PinsA,
};
#[local]
struct Local {
led0: Pin<PA10, OutputReadablePushPull>,
led1: Pin<PA7, OutputReadablePushPull>,
led2: Pin<PA6, OutputReadablePushPull>,
led0: Output,
led1: Output,
led2: Output,
}
#[shared]
@ -28,16 +28,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) {
rtt_init_print!();
rprintln!("-- Vorago VA108xx RTIC template --");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
let porta = PinsA::new(&mut cx.device.sysconfig, cx.device.porta);
let led0 = porta.pa10.into_readable_push_pull_output();
let led1 = porta.pa7.into_readable_push_pull_output();
let led2 = porta.pa6.into_readable_push_pull_output();
let porta = PinsA::new(cx.device.porta);
let led0 = Output::new(porta.pa10, PinState::Low);
let led1 = Output::new(porta.pa7, PinState::Low);
let led2 = Output::new(porta.pa6, PinState::Low);
blinky::spawn().ok();
(Shared {}, Local { led0, led1, led2 })
}

View File

@ -17,7 +17,9 @@ cortex-m-semihosting = "0.5.0"
[dependencies.va108xx-hal]
version = "0.11"
path = "../../va108xx-hal"
features = ["defmt"]
[dependencies.vorago-reb1]
path = "../../vorago-reb1"
version = "0.8"

View File

@ -10,52 +10,37 @@ use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use panic_halt as _;
use va108xx_hal::{
gpio::PinsA,
pac::{self, interrupt},
gpio::{Output, PinState},
pac::{self},
pins::PinsA,
prelude::*,
timer::DelayMs,
timer::{default_ms_irq_handler, set_up_ms_tick, CountdownTimer},
InterruptConfig,
timer::CountdownTimer,
};
#[entry]
fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap();
let mut delay_ms = DelayMs::new(set_up_ms_tick(
InterruptConfig::new(interrupt::OC0, true, true),
&mut dp.sysconfig,
Some(&mut dp.irqsel),
50.MHz(),
dp.tim0,
))
.unwrap();
let mut delay_tim1 = CountdownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim1);
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
let mut led1 = porta.pa10.into_readable_push_pull_output();
let mut led2 = porta.pa7.into_readable_push_pull_output();
let mut led3 = porta.pa6.into_readable_push_pull_output();
let dp = pac::Peripherals::take().unwrap();
let mut delay = CountdownTimer::new(50.MHz(), dp.tim1);
let porta = PinsA::new(dp.porta);
let mut led1 = Output::new(porta.pa10, PinState::Low);
let mut led2 = Output::new(porta.pa7, PinState::Low);
let mut led3 = Output::new(porta.pa6, PinState::Low);
for _ in 0..10 {
led1.set_low();
led2.set_low();
led3.set_low();
delay_ms.delay_ms(200);
delay.delay_ms(200);
led1.set_high();
led2.set_high();
led3.set_high();
delay_tim1.delay_ms(200);
delay.delay_ms(200);
}
loop {
led1.toggle();
delay_ms.delay_ms(200);
delay.delay_ms(200);
led2.toggle();
delay_tim1.delay_ms(200);
delay.delay_ms(200);
led3.toggle();
delay_ms.delay_ms(200);
delay.delay_ms(200);
}
}
#[interrupt]
#[allow(non_snake_case)]
fn OC0() {
default_ms_irq_handler()
}

View File

@ -15,38 +15,27 @@ use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
pac::{self, interrupt},
prelude::*,
timer::{
default_ms_irq_handler, set_up_ms_delay_provider, CascadeCtrl, CascadeSource,
CountdownTimer, Event, InterruptConfig,
},
timer::{CascadeCtrl, CascadeSource, CountdownTimer, InterruptConfig},
};
static CSD_TGT_1: Mutex<RefCell<Option<CountdownTimer<pac::Tim4>>>> =
Mutex::new(RefCell::new(None));
static CSD_TGT_2: Mutex<RefCell<Option<CountdownTimer<pac::Tim5>>>> =
Mutex::new(RefCell::new(None));
static CSD_TGT_1: Mutex<RefCell<Option<CountdownTimer>>> = Mutex::new(RefCell::new(None));
static CSD_TGT_2: Mutex<RefCell<Option<CountdownTimer>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx Cascade example application--");
let mut dp = pac::Peripherals::take().unwrap();
let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0);
let dp = pac::Peripherals::take().unwrap();
let mut delay = CountdownTimer::new(50.MHz(), dp.tim0);
// Will be started periodically to trigger a cascade
let mut cascade_triggerer =
CountdownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim3).auto_disable(true);
cascade_triggerer.listen(
Event::TimeOut,
InterruptConfig::new(pac::Interrupt::OC1, true, false),
Some(&mut dp.irqsel),
Some(&mut dp.sysconfig),
);
let mut cascade_triggerer = CountdownTimer::new(50.MHz(), dp.tim3).auto_disable(true);
cascade_triggerer.enable_interupt(InterruptConfig::new(pac::Interrupt::OC1, true, false));
cascade_triggerer.enable();
// First target for cascade
let mut cascade_target_1 =
CountdownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim4).auto_deactivate(true);
let mut cascade_target_1 = CountdownTimer::new(50.MHz(), dp.tim4).auto_deactivate(true);
cascade_target_1
.cascade_0_source(CascadeSource::Tim(3))
.expect("Configuring cascade source for TIM4 failed");
@ -60,19 +49,13 @@ fn main() -> ! {
// Normally it should already be sufficient to activate IRQ in the CTRL
// register but a full interrupt is use here to display print output when
// the timer expires
cascade_target_1.listen(
Event::TimeOut,
InterruptConfig::new(pac::Interrupt::OC2, true, false),
Some(&mut dp.irqsel),
Some(&mut dp.sysconfig),
);
cascade_target_1.enable_interupt(InterruptConfig::new(pac::Interrupt::OC2, true, false));
// The counter will only activate when the cascade signal is coming in so
// it is okay to call start here to set the reset value
cascade_target_1.start(1.Hz());
// Activated by first cascade target
let mut cascade_target_2 =
CountdownTimer::new(&mut dp.sysconfig, 50.MHz(), dp.tim5).auto_deactivate(true);
let mut cascade_target_2 = CountdownTimer::new(50.MHz(), dp.tim5).auto_deactivate(true);
// Set TIM4 as cascade source
cascade_target_2
.cascade_1_source(CascadeSource::Tim(4))
@ -86,12 +69,7 @@ fn main() -> ! {
// Normally it should already be sufficient to activate IRQ in the CTRL
// register but a full interrupt is use here to display print output when
// the timer expires
cascade_target_2.listen(
Event::TimeOut,
InterruptConfig::new(pac::Interrupt::OC3, true, false),
Some(&mut dp.irqsel),
Some(&mut dp.sysconfig),
);
cascade_target_2.enable_interupt(InterruptConfig::new(pac::Interrupt::OC3, true, false));
// The counter will only activate when the cascade signal is coming in so
// it is okay to call start here to set the reset value
cascade_target_2.start(1.Hz());
@ -115,11 +93,6 @@ fn main() -> ! {
}
}
#[interrupt]
fn OC0() {
default_ms_irq_handler()
}
#[interrupt]
fn OC1() {
static mut IDX: u32 = 0;

View File

@ -7,33 +7,27 @@ use embedded_hal::{delay::DelayNs, pwm::SetDutyCycle};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::PinsA,
pac,
pins::PinsA,
prelude::*,
pwm::{self, get_duty_from_percent, PwmA, PwmB, ReducedPwmPin},
timer::set_up_ms_delay_provider,
pwm::{self, get_duty_from_percent, PwmA, PwmB, PwmPin},
timer::CountdownTimer,
};
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx PWM example application--");
let mut dp = pac::Peripherals::take().unwrap();
let pinsa = PinsA::new(&mut dp.sysconfig, dp.porta);
let mut pwm = pwm::PwmPin::new(
&mut dp.sysconfig,
50.MHz(),
(pinsa.pa3.into_funsel_1(), dp.tim3),
10.Hz(),
);
let mut delay = set_up_ms_delay_provider(&mut dp.sysconfig, 50.MHz(), dp.tim0);
let dp = pac::Peripherals::take().unwrap();
let pinsa = PinsA::new(dp.porta);
let mut pwm = pwm::PwmPin::new(50.MHz(), (pinsa.pa3, dp.tim3), 10.Hz()).unwrap();
let mut delay = CountdownTimer::new(50.MHz(), dp.tim0);
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
@ -45,8 +39,7 @@ fn main() -> ! {
rprintln!("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();
}
@ -55,7 +48,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 {
@ -67,6 +60,6 @@ fn main() -> ! {
rprintln!("Lower limit: {}", pwmb.pwmb_lower_limit());
rprintln!("Upper limit: {}", pwmb.pwmb_upper_limit());
}
reduced_pin = ReducedPwmPin::<PwmA>::from(pwmb);
pwm = PwmPin::<PwmA>::from(pwmb);
}
}

View File

@ -12,11 +12,11 @@ use embedded_hal::{
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::{PinsA, PinsB},
pac::{self, interrupt},
pins::{PinsA, PinsB},
prelude::*,
spi::{self, Spi, SpiBase, SpiClkConfig, TransferConfigWithHwcs},
timer::{default_ms_irq_handler, set_up_ms_tick},
spi::{self, configure_pin_as_hw_cs_pin, Spi, SpiClkConfig, TransferConfig},
timer::CountdownTimer,
InterruptConfig,
};
@ -46,20 +46,15 @@ fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx SPI example application--");
let mut dp = pac::Peripherals::take().unwrap();
let mut delay = set_up_ms_tick(
InterruptConfig::new(interrupt::OC0, true, true),
&mut dp.sysconfig,
Some(&mut dp.irqsel),
50.MHz(),
dp.tim0,
);
let mut delay = CountdownTimer::new(50.MHz(), dp.tim0);
let spi_clk_cfg = SpiClkConfig::from_clk(50.MHz(), SPI_SPEED_KHZ.kHz())
.expect("creating SPI clock config failed");
let spia_ref: RefCell<Option<SpiBase<pac::Spia, u8>>> = RefCell::new(None);
let spib_ref: RefCell<Option<SpiBase<pac::Spib, u8>>> = RefCell::new(None);
let pinsa = PinsA::new(&mut dp.sysconfig, dp.porta);
let pinsb = PinsB::new(&mut dp.sysconfig, dp.portb);
//let spia_ref: RefCell<Option<SpiBase<pac::Spia, u8>>> = RefCell::new(None);
//let spib_ref: RefCell<Option<SpiBase<pac::Spib, u8>>> = RefCell::new(None);
let spi = None;
let pinsa = PinsA::new(dp.porta);
let pinsb = PinsB::new(dp.portb);
let mut spi_cfg = spi::SpiConfig::default();
if EXAMPLE_SEL == ExampleSelect::Loopback {
@ -67,158 +62,82 @@ fn main() -> ! {
}
// Set up the SPI peripheral
match SPI_BUS_SEL {
let spi = match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA => {
let (sck, mosi, miso) = (
pinsa.pa31.into_funsel_1(),
pinsa.pa30.into_funsel_1(),
pinsa.pa29.into_funsel_1(),
);
let mut spia = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spia,
(sck, miso, mosi),
spi_cfg,
);
let (sck, mosi, miso) = (pinsa.pa31, pinsa.pa30, pinsa.pa29);
let mut spia = Spi::new(50.MHz(), dp.spia, (sck, miso, mosi), spi_cfg).unwrap();
spia.set_fill_word(FILL_WORD);
spia_ref.borrow_mut().replace(spia.downgrade());
spia
}
SpiBusSelect::SpiAPortB => {
let (sck, mosi, miso) = (
pinsb.pb9.into_funsel_2(),
pinsb.pb8.into_funsel_2(),
pinsb.pb7.into_funsel_2(),
);
let mut spia = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spia,
(sck, miso, mosi),
spi_cfg,
);
let (sck, mosi, miso) = (pinsb.pb9, pinsb.pb8, pinsb.pb7);
let mut spia = Spi::new(50.MHz(), dp.spia, (sck, miso, mosi), spi_cfg).unwrap();
spia.set_fill_word(FILL_WORD);
spia_ref.borrow_mut().replace(spia.downgrade());
spia
}
SpiBusSelect::SpiBPortB => {
let (sck, mosi, miso) = (
pinsb.pb5.into_funsel_1(),
pinsb.pb4.into_funsel_1(),
pinsb.pb3.into_funsel_1(),
);
let mut spib = Spi::new(
&mut dp.sysconfig,
50.MHz(),
dp.spib,
(sck, miso, mosi),
spi_cfg,
);
let (sck, mosi, miso) = (pinsb.pb5, pinsb.pb4, pinsb.pb3);
let mut spib = Spi::new(50.MHz(), dp.spib, (sck, miso, mosi), spi_cfg).unwrap();
spib.set_fill_word(FILL_WORD);
spib_ref.borrow_mut().replace(spib.downgrade());
spib
}
}
};
// Configure transfer specific properties here
match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => {
if let Some(ref mut spi) = *spia_ref.borrow_mut() {
let transfer_cfg = TransferConfigWithHwcs::new_no_hw_cs(
Some(spi_clk_cfg),
Some(SPI_MODE),
BLOCKMODE,
true,
false,
);
spi.cfg_transfer(&transfer_cfg);
}
let transfer_cfg = TransferConfig {
clk_cfg: Some(spi_clk_cfg),
mode: Some(SPI_MODE),
sod: true,
blockmode: BLOCKMODE,
bmstall: true,
hw_cs: None,
};
spi.cfg_transfer(&transfer_cfg);
}
SpiBusSelect::SpiBPortB => {
if let Some(ref mut spi) = *spib_ref.borrow_mut() {
let hw_cs_pin = pinsb.pb2.into_funsel_1();
let transfer_cfg = TransferConfigWithHwcs::new(
Some(spi_clk_cfg),
Some(SPI_MODE),
Some(hw_cs_pin),
BLOCKMODE,
true,
false,
);
spi.cfg_transfer(&transfer_cfg);
}
let hw_cs_pin = configure_pin_as_hw_cs_pin(pinsb.pb2);
let transfer_cfg = TransferConfig {
clk_cfg: Some(spi_clk_cfg),
mode: Some(SPI_MODE),
sod: false,
blockmode: BLOCKMODE,
bmstall: true,
hw_cs: Some(hw_cs_pin),
};
spi.cfg_transfer(&transfer_cfg);
}
}
// Application logic
loop {
let mut reply_buf: [u8; 8] = [0; 8];
match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => {
if let Some(ref mut spi) = *spia_ref.borrow_mut() {
// Can't really verify correct reply here.
spi.write(&[0x42]).expect("write failed");
// Because of the loopback mode, we should get back the fill word here.
spi.read(&mut reply_buf[0..1]).unwrap();
assert_eq!(reply_buf[0], FILL_WORD);
delay.delay_ms(500_u32);
// Can't really verify correct reply here.
spi.write(&[0x42]).expect("write failed");
// Because of the loopback mode, we should get back the fill word here.
spi.read(&mut reply_buf[0..1]).unwrap();
assert_eq!(reply_buf[0], FILL_WORD);
delay.delay_ms(500_u32);
let tx_buf: [u8; 3] = [0x01, 0x02, 0x03];
spi.transfer(&mut reply_buf[0..3], &tx_buf).unwrap();
assert_eq!(tx_buf, reply_buf[0..3]);
rprintln!(
"Received reply: {}, {}, {}",
reply_buf[0],
reply_buf[1],
reply_buf[2]
);
delay.delay_ms(500_u32);
let tx_buf: [u8; 3] = [0x01, 0x02, 0x03];
spi.transfer(&mut reply_buf[0..3], &tx_buf).unwrap();
assert_eq!(tx_buf, reply_buf[0..3]);
rprintln!(
"Received reply: {}, {}, {}",
reply_buf[0],
reply_buf[1],
reply_buf[2]
);
delay.delay_ms(500_u32);
let mut tx_rx_buf: [u8; 3] = [0x03, 0x02, 0x01];
spi.transfer_in_place(&mut tx_rx_buf).unwrap();
rprintln!(
"Received reply: {}, {}, {}",
tx_rx_buf[0],
tx_rx_buf[1],
tx_rx_buf[2]
);
assert_eq!(&tx_rx_buf[0..3], &[0x03, 0x02, 0x01]);
}
}
SpiBusSelect::SpiBPortB => {
if let Some(ref mut spi) = *spib_ref.borrow_mut() {
// Can't really verify correct reply here.
spi.write(&[0x42]).expect("write failed");
// Because of the loopback mode, we should get back the fill word here.
spi.read(&mut reply_buf[0..1]).unwrap();
assert_eq!(reply_buf[0], FILL_WORD);
delay.delay_ms(500_u32);
let tx_buf: [u8; 3] = [0x01, 0x02, 0x03];
spi.transfer(&mut reply_buf[0..3], &tx_buf).unwrap();
assert_eq!(tx_buf, reply_buf[0..3]);
rprintln!(
"Received reply: {}, {}, {}",
reply_buf[0],
reply_buf[1],
reply_buf[2]
);
delay.delay_ms(500_u32);
let mut tx_rx_buf: [u8; 3] = [0x03, 0x02, 0x01];
spi.transfer_in_place(&mut tx_rx_buf).unwrap();
rprintln!(
"Received reply: {}, {}, {}",
tx_rx_buf[0],
tx_rx_buf[1],
tx_rx_buf[2]
);
assert_eq!(&tx_rx_buf[0..3], &[0x03, 0x02, 0x01]);
}
}
}
let mut tx_rx_buf: [u8; 3] = [0x03, 0x02, 0x01];
spi.transfer_in_place(&mut tx_rx_buf).unwrap();
rprintln!(
"Received reply: {}, {}, {}",
tx_rx_buf[0],
tx_rx_buf[1],
tx_rx_buf[2]
);
assert_eq!(&tx_rx_buf[0..3], &[0x03, 0x02, 0x01]);
}
}
#[interrupt]
#[allow(non_snake_case)]
fn OC0() {
default_ms_irq_handler()
}

View File

@ -12,9 +12,7 @@ use va108xx_hal::{
pac::{self, interrupt},
prelude::*,
time::Hertz,
timer::{
default_ms_irq_handler, set_up_ms_tick, CountdownTimer, Event, InterruptConfig, MS_COUNTER,
},
timer::{default_ms_irq_handler, CountdownTimer, Event, InterruptConfig, MS_COUNTER},
};
#[allow(dead_code)]
@ -66,21 +64,11 @@ fn main() -> ! {
}
}
LibType::Hal => {
set_up_ms_tick(
InterruptConfig::new(interrupt::OC0, true, true),
&mut dp.sysconfig,
Some(&mut dp.irqsel),
50.MHz(),
dp.tim0,
);
let mut second_timer =
CountdownTimer::new(&mut dp.sysconfig, get_sys_clock().unwrap(), dp.tim1);
second_timer.listen(
Event::TimeOut,
InterruptConfig::new(interrupt::OC1, true, true),
Some(&mut dp.irqsel),
Some(&mut dp.sysconfig),
);
let mut ms_timer = CountdownTimer::new(get_sys_clock().unwrap(), dp.tim0);
ms_timer.enable_interupt(InterruptConfig::new(interrupt::OC0, true, true));
ms_timer.start(1.kHz());
let mut second_timer = CountdownTimer::new(get_sys_clock().unwrap(), dp.tim1);
second_timer.enable_interupt(InterruptConfig::new(interrupt::OC1, true, true));
second_timer.start(1.Hz());
}
}

View File

@ -15,25 +15,20 @@ use embedded_hal_nb::{nb, serial::Read};
use embedded_io::Write as _;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{gpio::PinsA, pac, prelude::*, uart};
use va108xx_hal::{pac, pins::PinsA, prelude::*, uart};
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx UART example application--");
let mut dp = pac::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
let gpioa = PinsA::new(&mut dp.sysconfig, dp.porta);
let tx = gpioa.pa9.into_funsel_2();
let rx = gpioa.pa8.into_funsel_2();
let uart = uart::Uart::new_without_interrupt(
&mut dp.sysconfig,
50.MHz(),
dp.uarta,
(tx, rx),
115200.Hz(),
);
let gpioa = PinsA::new(dp.porta);
let tx = gpioa.pa9;
let rx = gpioa.pa8;
let uart = uart::Uart::new_without_interrupt(50.MHz(), dp.uarta, (tx, rx), 115200.Hz().into())
.unwrap();
let (mut tx, mut rx) = uart.split();
writeln!(tx, "Hello World\r").unwrap();