Implemented fifo readout.

This commit is contained in:
2025-08-15 22:23:27 +02:00
parent 8d96817029
commit b3843b529e
3 changed files with 92 additions and 59 deletions

View File

@@ -1,5 +1,6 @@
use defmt::*;
use embassy_embedded_hal::shared_bus::asynch::spi;
use embassy_stm32::{gpio::Output, mode::Blocking, spi::Spi, spi::Error};
use embassy_time::Timer;
@@ -237,6 +238,54 @@ impl AD5940 {
Ok(())
}
pub async fn read_fifo(&mut self, buf: &mut [u32]) -> Result<(), Error> {
if buf.len() < 3 {
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?;
self.spi.blocking_write(&[Register::DATAFIFORD as u16])?;
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
for i in 0..buf.len() {
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_READREG as u8])?;//Write Host status/Don't care
self.spi.blocking_write(&[0 as u8])?;//Write Host status/Don't care
let mut byte = [0u32];
self.spi.blocking_read(&mut byte)?;
buf[i] = byte[0];
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
}
} else {
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_READFIFO as u8])?;
// 6 dummy writes
for _ in 0..6 {
self.spi.blocking_write(&[0u8])?;
}
// Read all but last 2 elements
for i in 0..buf.len()-2 {
let mut byte = [0u32];
self.spi.blocking_read(&mut byte)?;
buf[i] = byte[0];
}
// Read last 2 elements with transfer
let mut bytes = [0u32; 2];
self.spi.blocking_transfer(&mut bytes, &mut [0x4444_4444, 0x4444_4444])?;
buf[buf.len()-2] = bytes[0];
buf[buf.len()-1] = bytes[1];
self.cs.set_high();
}
Ok(())
}
pub async fn system_init(&mut self) -> Result<(), Error> {
// See table 14
self.write_reg_raw(0x0908, 0x02C9).await?;
@@ -645,7 +694,7 @@ impl AD5940 {
#[allow(non_camel_case_types)]
#[repr(u8)]
enum Command {
SPICMD_SETADDR = 0x20,
SPICMD_READREG = 0x6D,

View File

@@ -2,6 +2,7 @@ use bitflags::bitflags;
pub trait Resettable {
fn reset() -> Self;
// fn msk() -> u32;
}
#[allow(dead_code)]
@@ -14,6 +15,9 @@ impl Resettable for T9CON {
fn reset() -> Self {
T9CON::T9Open
}
// fn msk() -> u32 {
// 0b1
// }
}
#[allow(dead_code)]

View File

@@ -75,10 +75,6 @@ async fn main(spawner: Spawner) {
let cs = Output::new(p.PC9, Level::High, Speed::Low);
let rst = Output::new(p.PB3, Level::High, Speed::Low);
// Set up interrupt at GPIO for AD5940
let ad5940_gpio_0 = ExtiInput::new(p.PC8, p.EXTI8, embassy_stm32::gpio::Pull::Up);
spawner.must_spawn(ad5940_readout_task(ad5940_gpio_0));
let spi = spi::Spi::new_blocking(
p.SPI1,
p.PA5, // SCK
@@ -158,7 +154,7 @@ async fn main(spawner: Spawner) {
// Toggle leds
ad5940.write_reg(ad5940::Register::SYNCEXTDEVICE, 0b010).await.unwrap();
ad5940.sequencer_wait(16 * 100_000).await; // 0.1 second
ad5940.sequencer_wait(16 * 25_000).await; // 0.025 second
ad5940.write_reg(ad5940::Register::SYNCEXTDEVICE, 0b111).await.unwrap();
ad5940.sequencer_enable(false).await;
@@ -178,6 +174,13 @@ async fn main(spawner: Spawner) {
// Green led task
// spawner.must_spawn(green_led(led));
// Trigger the sequencer
ad5940.sequencer_trigger(0).await;
// Set up interrupt at GPIO for AD5940
let ad5940_gpio_0 = ExtiInput::new(p.PC8, p.EXTI8, embassy_stm32::gpio::Pull::Up);
spawner.must_spawn(ad5940_readout_task(ad5940_gpio_0, ad5940));
loop {
// Read chip id
// let chip_id = ad5940.get_chipid().await;
@@ -190,56 +193,7 @@ async fn main(spawner: Spawner) {
// let result = electrodes.get_all();
// info!("Electrodes states: {:?}", result);
// info!("high");
ad5940.sequencer_trigger(0).await;
// info!("Mainloop still running!");
Timer::after_micros((102_400.0 * 3.0) as u64).await;
let count = ad5940.get_fifo_count().await.unwrap();
info!("FIFOCNTSTA: {}", count);
// for _ in 0..count {
// let mut data = ad5940.read_reg(ad5940::Register::DATAFIFORD).await.unwrap();
// data &= 0xFFFF; // Mask to 16 bits
// use libm::powf;
// let value = 1.82 * (data as i32 - 0x8000) as f32 / powf(2f32, 15f32);
// // let value = (data as i32 - 0x8000) as f32;
// match IMPEDANCE_CHANNEL.try_send(value) {
// Ok(_) => {counter += 1;},
// Err(e) => {
// info!("Failed to send impedance data: {}", e);
// }
// }
// }
// info!("Counter: {}", counter);
if count >= 4 {
let mut data: [u32; 4] = [0; 4];
data[0] = ad5940.read_reg(ad5940::Register::DATAFIFORD).await.unwrap();
data[1] = ad5940.read_reg(ad5940::Register::DATAFIFORD).await.unwrap();
data[2] = ad5940.read_reg(ad5940::Register::DATAFIFORD).await.unwrap();
data[3] = ad5940.read_reg(ad5940::Register::DATAFIFORD).await.unwrap();
let result = calculate_impedance(data);
// Youll need to implement your own logging or send this over serial in embedded
info!("Impedance: Magnitude = {} Ω, Phase = {} rad", result.magnitude, result.phase);
let data = Impedance {
magnitude: result.magnitude,
phase: result.phase,
};
IMPEDANCE_CHANNEL.try_send(data).ok();
}
Timer::after_secs(1).await;
}
}
@@ -267,9 +221,35 @@ async fn green_led(mut led: Output<'static>) {
}
#[embassy_executor::task]
async fn ad5940_readout_task(mut pin: ExtiInput<'static>) {
async fn ad5940_readout_task(mut pin: ExtiInput<'static>, mut ad5940: AD5940) {
loop {
pin.wait_for_falling_edge().await;
// Wait untill sequence is done
pin.wait_for_rising_edge().await;
// Trigger the sequencer agina
ad5940.sequencer_trigger(0).await;
// Read the FIFO count
let count = ad5940.get_fifo_count().await.unwrap();
// info!("FIFOCNTSTA: {}", count);
if count >= 4 {
let mut data: [u32; 4] = [0; 4];
ad5940.read_fifo(data.as_mut_slice()).await.unwrap();
let result = calculate_impedance(data);
// Youll need to implement your own logging or send this over serial in embedded
info!("Impedance: Magnitude = {} Ω, Phase = {} rad", result.magnitude, result.phase);
let data = Impedance {
magnitude: result.magnitude,
phase: result.phase,
};
IMPEDANCE_CHANNEL.try_send(data).ok();
}
}
}