Skip to content

Commit

Permalink
finished basic ADC and DAC HAL
Browse files Browse the repository at this point in the history
  • Loading branch information
robamu committed Jul 1, 2024
1 parent 78e6c52 commit 5f50892
Show file tree
Hide file tree
Showing 16 changed files with 910 additions and 124 deletions.
70 changes: 70 additions & 0 deletions examples/simple/examples/adc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! Simple ADC example.
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use simple_examples::peb1;
use va416xx_hal::{
adc::{Adc, ChannelSelect, ChannelValue, MultiChannelSelect},
pac,
prelude::*,
timer::CountdownTimer,
};

// Quite spammy and disabled by default.
const ENABLE_BUF_PRINTOUT: bool = false;

#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("VA416xx ADC example");

let mut dp = pac::Peripherals::take().unwrap();
// Use the external clock connected to XTAL_N.
let clocks = dp
.clkgen
.constrain()
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
.freeze(&mut dp.sysconfig)
.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 mut read_buf: [ChannelValue; 8] = [ChannelValue::default(); 8];
loop {
let single_value = adc
.trigger_and_read_single_channel(va416xx_hal::adc::ChannelSelect::AnIn0)
.expect("reading single channel value failed");
rprintln!("Read single ADC value on channel 0: {:?}", single_value);
let read_num = adc
.sweep_and_read_range(0, 7, &mut read_buf)
.expect("ADC range read failed");
if ENABLE_BUF_PRINTOUT {
rprintln!("ADC Range Read (0-8) read {} values", read_num);
rprintln!("ADC Range Read (0-8): {:?}", read_buf);
}
assert_eq!(read_num, 8);
for (idx, ch_val) in read_buf.iter().enumerate() {
assert_eq!(
ch_val.channel(),
ChannelSelect::try_from(idx as u8).unwrap()
);
}

adc.sweep_and_read_multiselect(
MultiChannelSelect::AnIn0 | MultiChannelSelect::AnIn2 | MultiChannelSelect::TempSensor,
&mut read_buf[0..3],
)
.expect("ADC multiselect read failed");
if ENABLE_BUF_PRINTOUT {
rprintln!("ADC Multiselect Read(0, 2 and 10): {:?}", &read_buf[0..3]);
}
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);
}
}
1 change: 0 additions & 1 deletion examples/simple/examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ fn main() -> ! {
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 mut delay = CountDownTimer::new(&mut dp.SYSCONFIG, 50.mhz(), dp.TIM0);
loop {
cortex_m::asm::delay(2_000_000);
led.toggle().ok();
Expand Down
78 changes: 78 additions & 0 deletions examples/simple/examples/dac-adc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Simple DAC-ADC example.
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use simple_examples::peb1;
use va416xx_hal::{adc::Adc, dac::Dac, pac, prelude::*, timer::CountdownTimer};

const DAC_INCREMENT: u16 = 256;

#[derive(Debug, PartialEq, Eq)]
pub enum AppMode {
// Measurements on AIN0.
AdcOnly,
// AOUT0. You can use a multi-meter to measure the changing voltage on the pin.
DacOnly,
/// AOUT0 needs to be wired to AIN0.
DacAndAdc,
}

const APP_MODE: AppMode = AppMode::DacAndAdc;

#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("VA416xx DAC/ADC example");

let mut dp = pac::Peripherals::take().unwrap();
// Use the external clock connected to XTAL_N.
let clocks = dp
.clkgen
.constrain()
.xtal_n_clk_with_src_freq(peb1::EXTCLK_FREQ)
.freeze(&mut dp.sysconfig)
.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,
));
}
let mut adc = None;
if APP_MODE == AppMode::AdcOnly || APP_MODE == AppMode::DacAndAdc {
adc = Some(Adc::new(&mut dp.sysconfig, dp.adc, &clocks));
}
let mut delay_provider = CountdownTimer::new(&mut dp.sysconfig, dp.tim0, &clocks);
let mut current_val = 0;
loop {
if let Some(dac) = &dac {
rprintln!("loading DAC with value {}", current_val);
dac.load_and_trigger_manually(current_val)
.expect("loading DAC value failed");
if current_val + DAC_INCREMENT >= 4096 {
current_val = 0;
} else {
current_val += DAC_INCREMENT;
}
}
if let Some(dac) = &dac {
// This should never block.
nb::block!(dac.is_settled()).unwrap();
}
if let Some(adc) = &adc {
let ch_value = adc
.trigger_and_read_single_channel(va416xx_hal::adc::ChannelSelect::AnIn0)
.expect("reading ADC channel 0 failed");
rprintln!("Received channel value {:?}", ch_value);
}

delay_provider.delay_ms(500);
}
}
4 changes: 3 additions & 1 deletion scripts/VA416xx_Series.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ variants:
range:
start: 0x0
end: 0x40000
is_boot_memory: true
# is_boot_memory: true
access:
boot: true
cores:
- main
- !Generic
Expand Down
2 changes: 2 additions & 0 deletions va416xx-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ paste = "1"
embedded-hal-nb = "1"
embedded-hal = "1"
embedded-io = "0.6"
num_enum = { version = "0.7", default-features = false }
typenum = "1"
bitflags = "2"
defmt = { version = "0.3", optional = true }
fugit = "0.3"
delegate = "0.12"
Expand Down
Loading

0 comments on commit 5f50892

Please sign in to comment.