Robin Mueller 60f4a52953 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.
- All HAL API constructors now have a more consistent argument order: PAC structures and resource
  management structures first, then clock configuration, then any other configuration.
- 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.
2025-04-24 16:54:29 +02:00

186 lines
6.2 KiB
Rust

//! Test image
//!
//! It would be nice to use a test framework like defmt-test, but I have issues
//! with probe run and it would be better to make the RTT work first
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
// Logging provider
use defmt_rtt as _;
// Panic provider
use panic_probe as _;
use va108xx_hal::{
gpio::{regs::Gpio, Input, Output, PinState, Pull},
pac,
pins::{PinsA, PinsB, Port},
prelude::*,
time::Hertz,
timer::CountdownTimer,
};
#[allow(dead_code)]
#[derive(Debug, defmt::Format)]
enum TestCase {
// Tie PORTA[0] to PORTA[1] for these tests!
TestBasic,
TestPullup,
TestPulldown,
TestMask,
// Tie PORTB[22] to PORTB[23] for this test
PortB,
Perid,
// Tie PA0 to an oscilloscope and configure pulse detection
Pulse,
// Tie PA0, PA1 and PA3 to an oscilloscope
DelayGpio,
DelayMs,
}
#[entry]
fn main() -> ! {
defmt::println!("-- VA108xx Test Application --");
let dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::Peripherals::take().unwrap();
let pinsa = PinsA::new(dp.porta);
let pinsb = PinsB::new(dp.portb);
let mut led1 = Output::new(pinsa.pa10, PinState::Low);
let test_case = TestCase::DelayMs;
match test_case {
TestCase::TestBasic
| TestCase::TestPulldown
| TestCase::TestPullup
| TestCase::TestMask => {
defmt::info!(
"Test case {:?}. Make sure to tie PORTA[0] to PORTA[1]",
test_case
);
}
_ => {
defmt::info!("Test case {:?}", test_case);
}
}
match test_case {
TestCase::TestBasic => {
// Tie PORTA[0] to PORTA[1] for these tests!
let mut out = Output::new(pinsa.pa0, PinState::Low);
let input = Input::new_floating(pinsa.pa1);
out.set_high();
assert!(input.is_high());
out.set_low();
assert!(input.is_low());
}
TestCase::TestPullup => {
// Tie PORTA[0] to PORTA[1] for these tests!
let input = Input::new_with_pull(pinsa.pa1, Pull::Up);
assert!(input.is_high());
let mut out = Output::new(pinsa.pa0, PinState::Low);
out.set_low();
assert!(input.is_low());
out.set_high();
assert!(input.is_high());
}
TestCase::TestPulldown => {
// Tie PORTA[0] to PORTA[1] for these tests!
let input = Input::new_with_pull(pinsa.pa1, Pull::Down);
assert!(input.is_low());
let mut out = Output::new(pinsa.pa0, PinState::Low);
out.set_low();
assert!(input.is_low());
out.set_high();
assert!(input.is_high());
}
TestCase::TestMask => {
// Tie PORTA[0] to PORTA[1] for these tests!
// Need to test this low-level..
/*
let mut input = Input::new_with_pull(pinsa.pa1, Pull::Down);
input.clear_datamask();
assert!(!input.datamask());
let mut out = pinsa.pa0.into_push_pull_output();
out.clear_datamask();
assert!(input.is_low_masked().is_err());
assert!(out.set_high_masked().is_err());
*/
}
TestCase::PortB => {
// Tie PORTB[22] to PORTB[23] for these tests!
let mut out = Output::new(pinsb.pb22, PinState::Low);
let input = Input::new_floating(pinsb.pb23);
out.set_high();
assert!(input.is_high());
out.set_low();
assert!(input.is_low());
}
TestCase::Perid => {
let mmio_porta = Gpio::new_mmio(Port::A);
assert_eq!(mmio_porta.read_perid(), 0x004007e1);
let mmio_porta = Gpio::new_mmio(Port::B);
assert_eq!(mmio_porta.read_perid(), 0x004007e1);
}
TestCase::Pulse => {
// TODO: Fix
let mut output_pulsed = Output::new(pinsa.pa0, PinState::Low);
output_pulsed.configure_pulse_mode(true, PinState::Low);
defmt::info!("Pulsing high 10 times..");
output_pulsed.set_low();
for _ in 0..10 {
output_pulsed.set_high();
cortex_m::asm::delay(25_000_000);
}
output_pulsed.configure_pulse_mode(true, PinState::High);
defmt::info!("Pulsing low 10 times..");
for _ in 0..10 {
output_pulsed.set_low();
cortex_m::asm::delay(25_000_000);
}
}
TestCase::DelayGpio => {
let mut out_0 = Output::new(pinsa.pa0, PinState::Low);
out_0.configure_delay(true, false);
let mut out_1 = Output::new(pinsa.pa1, PinState::Low);
out_1.configure_delay(false, true);
let mut out_2 = Output::new(pinsa.pa3, PinState::Low);
out_2.configure_delay(true, true);
for _ in 0..20 {
out_0.toggle();
out_1.toggle();
out_2.toggle();
cortex_m::asm::delay(25_000_000);
}
}
TestCase::DelayMs => {
let mut delay_timer = CountdownTimer::new(dp.tim1, 50.MHz());
let mut pa0 = Output::new(pinsa.pa0, PinState::Low);
for _ in 0..5 {
led1.toggle();
delay_timer.delay_ms(500);
led1.toggle();
delay_timer.delay_ms(500);
}
let ahb_freq: Hertz = 50.MHz();
let mut syst_delay = cortex_m::delay::Delay::new(cp.SYST, ahb_freq.raw());
// Test usecond delay using both TIM peripheral and SYST. Use the release image if you
// want to verify the timings!
loop {
pa0.toggle();
delay_timer.delay_us(50);
pa0.toggle();
delay_timer.delay_us(50);
pa0.toggle();
syst_delay.delay_us(50);
pa0.toggle();
syst_delay.delay_us(50);
}
}
}
defmt::info!("Test success");
loop {
led1.toggle();
cortex_m::asm::delay(25_000_000);
}
}