Major refactoring
Some checks failed
Rust/va108xx-hal/pipeline/head There was a failure building this commit

- Improved IRQ handling, which makes most unsafe unmask operations
  in user code absolete
- Add first UART RX handlers which use an IRQ
This commit is contained in:
2021-12-19 14:18:10 +01:00
parent dc2426a905
commit f376a43f41
12 changed files with 491 additions and 133 deletions

View File

@ -9,7 +9,7 @@
use cortex_m_rt::entry;
use embedded_hal::digital::v2::ToggleableOutputPin;
use panic_halt as _;
use va108xx_hal::{gpio::PinsA, pac, prelude::*, timer::set_up_ms_timer};
use va108xx_hal::{gpio::PinsA, pac, prelude::*, timer::CountDownTimer};
#[entry]
fn main() -> ! {
@ -18,13 +18,7 @@ fn main() -> ! {
let mut led1 = porta.pa10.into_push_pull_output();
let mut led2 = porta.pa7.into_push_pull_output();
let mut led3 = porta.pa6.into_push_pull_output();
let mut delay = set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
pac::Interrupt::OC0,
);
let mut delay = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
for _ in 0..10 {
led1.set_low().ok();
led2.set_low().ok();

View File

@ -14,8 +14,8 @@ use va108xx_hal::{
pac::{self, interrupt, TIM4, TIM5},
prelude::*,
timer::{
default_ms_irq_handler, set_up_ms_timer, CascadeCtrl, CascadeSource, CountDownTimer, Delay,
Event,
default_ms_irq_handler, set_up_ms_delay_provider, CascadeCtrl, CascadeSource,
CountDownTimer, Event, IrqCfg,
},
};
@ -28,23 +28,16 @@ fn main() -> ! {
rprintln!("-- VA108xx Cascade example application--");
let mut dp = pac::Peripherals::take().unwrap();
let timer = set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
pac::Interrupt::OC0,
);
let mut delay = Delay::new(timer);
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 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,
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
va108xx::Interrupt::OC1,
IrqCfg::new(va108xx::Interrupt::OC1, true, false),
Some(&mut dp.IRQSEL),
Some(&mut dp.SYSCONFIG),
);
// First target for cascade
@ -63,9 +56,9 @@ fn main() -> ! {
// the timer expires
cascade_target_1.listen(
Event::TimeOut,
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
va108xx::Interrupt::OC2,
IrqCfg::new(va108xx::Interrupt::OC2, true, false),
Some(&mut dp.IRQSEL),
Some(&mut dp.SYSCONFIG),
);
// 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
@ -89,9 +82,9 @@ fn main() -> ! {
// the timer expires
cascade_target_2.listen(
Event::TimeOut,
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
va108xx::Interrupt::OC3,
IrqCfg::new(va108xx::Interrupt::OC3, true, false),
Some(&mut dp.IRQSEL),
Some(&mut dp.SYSCONFIG),
);
// 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
@ -112,7 +105,7 @@ fn main() -> ! {
loop {
rprintln!("-- Triggering cascade in 0.5 seconds --");
cascade_triggerer.start(2.hz());
delay.delay_ms(5000);
delay.delay_ms(5000_u16);
}
}

View File

@ -8,10 +8,10 @@ use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::PinsA,
pac::{self, interrupt},
pac,
prelude::*,
pwm::{self, get_duty_from_percent, ReducedPwmPin, PWMA, PWMB},
timer::{default_ms_irq_handler, set_up_ms_timer, Delay},
timer::set_up_ms_delay_provider,
};
#[entry]
@ -26,17 +26,7 @@ fn main() -> ! {
&mut dp.SYSCONFIG,
10.hz(),
);
let timer = set_up_ms_timer(
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
dp.TIM0,
pac::Interrupt::OC0,
);
let mut delay = Delay::new(timer);
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
}
let mut delay = set_up_ms_delay_provider(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
let mut current_duty_cycle = 0.0;
PwmPin::set_duty(&mut pwm, get_duty_from_percent(current_duty_cycle));
PwmPin::enable(&mut pwm);
@ -46,7 +36,7 @@ fn main() -> ! {
loop {
// Increase duty cycle continuously
while current_duty_cycle < 1.0 {
delay.delay_ms(200);
delay.delay_ms(200_u16);
current_duty_cycle += 0.02;
PwmPin::set_duty(&mut reduced_pin, get_duty_from_percent(current_duty_cycle));
}
@ -60,7 +50,7 @@ fn main() -> ! {
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 {
delay.delay_ms(200);
delay.delay_ms(200_u16);
lower_limit += 0.01;
upper_limit -= 0.01;
pwmb.set_pwmb_lower_limit(get_duty_from_percent(lower_limit));
@ -71,8 +61,3 @@ fn main() -> ! {
reduced_pin = ReducedPwmPin::<PWMA>::from(pwmb);
}
}
#[interrupt]
fn OC0() {
default_ms_irq_handler()
}

View File

@ -14,7 +14,7 @@ use va108xx_hal::{
pac::{self, interrupt},
prelude::*,
time::Hertz,
timer::{default_ms_irq_handler, set_up_ms_timer, CountDownTimer, Delay},
timer::{default_ms_irq_handler, set_up_ms_timer, CountDownTimer, Delay, IrqCfg},
};
#[allow(dead_code)]
@ -146,15 +146,12 @@ fn main() -> ! {
}
TestCase::DelayMs => {
let ms_timer = set_up_ms_timer(
IrqCfg::new(pac::Interrupt::OC0, true, true),
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
Some(&mut dp.IRQSEL),
50.mhz(),
dp.TIM0,
pac::Interrupt::OC0,
);
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
}
let mut delay = Delay::new(ms_timer);
for _ in 0..5 {
led1.toggle().ok();
@ -163,7 +160,7 @@ fn main() -> ! {
delay.delay_ms(500);
}
let mut delay_timer = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz().into(), dp.TIM1);
let mut delay_timer = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM1);
let mut pa0 = pinsa.pa0.into_push_pull_output();
for _ in 0..5 {
led1.toggle().ok();

View File

@ -12,7 +12,7 @@ use va108xx_hal::{
pac::{self, interrupt},
prelude::*,
time::Hertz,
timer::{default_ms_irq_handler, set_up_ms_timer, CountDownTimer, Event, MS_COUNTER},
timer::{default_ms_irq_handler, set_up_ms_timer, CountDownTimer, Event, IrqCfg, MS_COUNTER},
};
#[allow(dead_code)]
@ -65,22 +65,21 @@ fn main() -> ! {
}
LibType::Hal => {
set_up_ms_timer(
IrqCfg::new(interrupt::OC0, true, true),
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
50.mhz().into(),
Some(&mut dp.IRQSEL),
50.mhz(),
dp.TIM0,
interrupt::OC0,
);
let mut second_timer =
CountDownTimer::new(&mut dp.SYSCONFIG, get_sys_clock().unwrap(), dp.TIM1);
second_timer.listen(
Event::TimeOut,
&mut dp.SYSCONFIG,
&mut dp.IRQSEL,
interrupt::OC1,
IrqCfg::new(interrupt::OC1, true, true),
Some(&mut dp.IRQSEL),
Some(&mut dp.SYSCONFIG),
);
second_timer.start(1.hz());
unmask_irqs();
}
}
loop {

44
examples/uart-irq.rs Normal file
View File

@ -0,0 +1,44 @@
//! UART example application. Sends a test string over a UART and then enters
//! echo mode
#![no_main]
#![no_std]
use core::fmt::Write;
use cortex_m_rt::entry;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{gpio::PinsB, pac, prelude::*, uart};
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx UART example application--");
let mut dp = pac::Peripherals::take().unwrap();
let gpiob = PinsB::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTB);
let tx = gpiob.pb21.into_funsel_1();
let rx = gpiob.pb20.into_funsel_1();
let uartb = uart::Uart::uartb(
dp.UARTB,
(tx, rx),
115200.bps(),
&mut dp.SYSCONFIG,
50.mhz(),
);
let (mut tx, mut rx) = uartb.split();
writeln!(tx, "Hello World\r").unwrap();
loop {
// Echo what is received on the serial link.
match rx.read() {
Ok(recv) => {
nb::block!(tx.write(recv)).expect("TX send error");
}
Err(nb::Error::WouldBlock) => (),
Err(nb::Error::Other(uart_error)) => {
rprintln!("UART receive error {:?}", uart_error);
}
}
}
}