diff --git a/src/ad5940.rs b/src/ad5940.rs index d81acaa..10b1dda 100644 --- a/src/ad5940.rs +++ b/src/ad5940.rs @@ -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, diff --git a/src/ad5940_registers.rs b/src/ad5940_registers.rs index feaf033..ce18a3a 100644 --- a/src/ad5940_registers.rs +++ b/src/ad5940_registers.rs @@ -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)] diff --git a/src/main.rs b/src/main.rs index f90a38b..708e740 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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; @@ -188,58 +191,9 @@ async fn main(spawner: Spawner) { // info!("Temperature: {}°C", temp); // let result = electrodes.get_all(); - // info!("Electrodes states: {:?}", result); + // 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); - - // You’ll 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); + + // You’ll 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(); + } } }