I’m trying to implement ADC conversion in a non blocking mode using DMA from gpio analog input at the sample rates: 192kHz.
My questions:
How to be implemented ADC in non-blocking mode (DMA). Something like:
// DMA
let dma = pdma::Dma::new(system.dma, &mut system.peripheral_clock_control);
dma.alloc_buffer::<u64>(256);
let dmaChannel = dma....
...
Already tried:
- ADC in blocking mode (polling)
#![no_std]
#![no_main]
#![allow(non_snake_case)]
use esp_backtrace as _;
use esp_println::println;
use esp32_hal::{
prelude::*,
peripherals::Peripherals,
clock::{ClockControl, CpuClock},
Rtc,
timer::TimerGroup,
adc::{self, ADC1, AdcConfig, ADC, Attenuation},
IO,
Delay,
};
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let mut system = peripherals.DPORT.split();
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Disable the RTC and TIMG watchdog timers
let rtcCntl = Rtc::new(peripherals.RTC_CNTL);
let mut rwdt = rtcCntl.rwdt;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let mut wdt1 = timer_group1.wdt;
rwdt.disable();
wdt0.disable();
wdt1.disable();
// ADC
let analog = peripherals.SENS.split();
let mut adcConfig: AdcConfig<ADC1> = adc::AdcConfig::new();
let mut adcPin = adcConfig.enable_pin(
io.pins.gpio34.into_analog(),
Attenuation::Attenuation11dB,
);
let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adcConfig).unwrap();
let mut delay = Delay::new(&clocks);
loop {
match nb::block!(adc1.read(&mut adcPin)) {
Ok(value) => {
println!("{}", value);
value
},
Err(err) => {
println!("ADC1 read error: {:?}", err);
0
},
};
delay.delay_ms(1_u32);
};
}
- ADC in non-blocking mode (interrupt)
it’s worked only at lower frequencies (up to 1 kHz).
Need to be implemented ADC in non-blocking mode (DMA)t o free up the cpu for another tasks, like transferring samples from adc via Ethernet and some DSP tasks.