From e6c3d6d06f447f44d4619cc8fb40773b5bd92602 Mon Sep 17 00:00:00 2001 From: Hubald Verzijl Date: Wed, 23 Jul 2025 14:56:41 +0200 Subject: [PATCH] Working waveform (sinus) generator. --- src/ad5940.rs | 60 +++++++++++++++++++++++++++++++++++++++-- src/ad5940_registers.rs | 28 +++++++++++++++++++ src/main.rs | 19 ++++++++----- 3 files changed, 98 insertions(+), 9 deletions(-) diff --git a/src/ad5940.rs b/src/ad5940.rs index 4946167..eddd74c 100644 --- a/src/ad5940.rs +++ b/src/ad5940.rs @@ -6,11 +6,19 @@ use crate::ad5940_registers::*; pub struct AD5940 { spi: Spi<'static, Blocking>, cs: Output<'static>, + rst: Output<'static>, } impl AD5940 { - pub fn new(spi: Spi<'static, Blocking>, cs: Output<'static>) -> Self { - AD5940 { spi, cs } + pub fn new(spi: Spi<'static, Blocking>, cs: Output<'static>, rst: Output<'static>) -> Self { + AD5940 { spi, cs, rst } + } + + pub async fn reset(&mut self) -> Result<(), Error> { + self.rst.set_low(); + Timer::after_millis(1).await; + self.rst.set_high(); + Ok(()) } async fn read_reg_16(&mut self, address: Register) -> Result { @@ -109,6 +117,13 @@ impl AD5940 { self.write_reg_16_raw(0x0A04, 0xF27B).await?; self.write_reg_16_raw(0x0A00, 0x8009).await?; self.write_reg_16_raw(0x22F0, 0x0000).await?; + + // According to library + // self.write_reg_32_raw(0x2230, 0xDE87A5AF).await?; + // self.write_reg_16_raw(0x2250, 0x103F).await?; + // self.write_reg_16_raw(0x22B0, 0x203C).await?; + // self.write_reg_32_raw(0x2230, 0xDE87A5A0).await?; + Ok(()) } @@ -147,6 +162,42 @@ impl AD5940 { Ok((tempsensdat0 as f32/(pga_gain * k)) - 273.15) } + + pub async fn init_waveform(&mut self) -> Result<(), Error> { + // Set frequency + let freq: u32 = 2000; + let sinefcw = (freq as f64) * (1_073_741_824.0 / 16_000_000.0); + let sinefcw = 0x00FFFFFF & sinefcw as u32; + self.write_reg_32(Register::WGFCW, sinefcw).await?; + + // Init amplitude + let wg_amplitude = 1279; + self.write_reg_32(Register::WGAMPLITUDE, wg_amplitude).await?; + + // WGCON, enable waveform generator and set to sinusoidal, NO DACCAL + let config_wgcon = WaveformGeneratorConfigurationRegister::TYPESEL_SIN.bits(); + self.write_reg_32(Register::WGCON, config_wgcon).await?; + + // SWCON - set up switch matrix + let mut swcon = SwitchMatrixConfigurationRegister::reset.bits(); + + swcon &= !SwitchMatrixConfigurationRegister::NMUXCON_MSK.bits(); + swcon |= SwitchMatrixConfigurationRegister::NMUXCON_N2.bits(); + + swcon &= !SwitchMatrixConfigurationRegister::PMUXCON_MSK.bits(); + swcon |= SwitchMatrixConfigurationRegister::PMUXCON_P11.bits(); + + swcon &= !SwitchMatrixConfigurationRegister::DMUXCON_MSK.bits(); + swcon |= SwitchMatrixConfigurationRegister::DMUXCON_D5.bits(); + + self.write_reg_32(Register::SWCON, swcon).await?; + + // AFECON: + let config_afecon = ConfigurationRegister::reset.bits() | ConfigurationRegister::DACREFEN.bits() | ConfigurationRegister::EXBUFEN.bits() | ConfigurationRegister::INAMPEN.bits() | ConfigurationRegister::DACEN.bits() | ConfigurationRegister::WAVEGENEN.bits(); + self.write_reg_32(Register::AFECON, config_afecon).await?; + + Ok(()) + } } #[allow(dead_code)] @@ -165,8 +216,13 @@ enum Register { ADIID = 0x0000_0400, // Analog Devices Inc., identification register CHIPID = 0x0000_0404, // Chip identification register AFECON = 0x0000_2000, // Configuration Register + SWCON = 0x0000_200C, // Switch Matrix Configuration Register + WGCON = 0x0000_2014, // Waveform Generator Configuration Register + WGFCW = 0x0000_2030, // Waveform Generator, Sinusoid Frequency Control Word Register + WGAMPLITUDE = 0x0000_203C, // Waveform Generator, Sinusoid Amplitude Register TEMPSENSDAT = 0x0000_2084, // Temperature Sensor Result Register ADCDAT = 0x0000_2074, // ADC Raw Result Register TEMPSENS = 0x0000_2174, // Temperature Sensor Configuration Register ADCCON = 0x0000_21A8, // ADC Configuration Register + PMBW = 0x0000_22F0, // Power Mode Configuration Register } diff --git a/src/ad5940_registers.rs b/src/ad5940_registers.rs index 10c0c3d..a56e5bb 100644 --- a/src/ad5940_registers.rs +++ b/src/ad5940_registers.rs @@ -21,6 +21,34 @@ bitflags! { } } +bitflags! { + // Address 0x0000200C, Reset: 0x00000000, Name: SWCON + pub struct SwitchMatrixConfigurationRegister: u32 { + const reset = 0x0000_FFFF; + const NMUXCON_MSK = 0b1111 << 8; + const NMUXCON_N2 = 0b0010 << 8; // N2 switch + const NMUXCON_N5 = 0b0101 << 8; // N5 switch + const PMUXCON_MSK = 0b1111 << 4; + const PMUXCON_P2 = 0b0010 << 4; // P2 switch + const PMUXCON_P11 = 0b1011 << 4; // P11 switch + const DMUXCON_MSK = 0b1111; + const DMUXCON_D5 = 0b0101; // D5 switch + } +} + +bitflags! { + // Address 0x00002014, Reset: 0x00000030, Name: WGCON + pub struct WaveformGeneratorConfigurationRegister: u32 { + const reset = 0x00000030; + const DACGAINCAL = 1 << 5; + const DACOFFSETCAL = 1 << 4; + const TYPESEL_DAC = 0b00 << 1; // Direct DAC + const TYPESEL_SIN = 0b10 << 1; // Sinusoidal + const TYPESEL_TRA = 0b11 << 1; // Trapezoidal + const TRAPRSTEN = 1; + } +} + bitflags! { // Address 0x000021A8, Reset: 0x00000000, Name: ADCCON pub struct ADCConfigurationRegister: u32 { diff --git a/src/main.rs b/src/main.rs index 6827c94..1499025 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ async fn main(_spawner: Spawner) { // Set up SPI for AD5940 let cs = Output::new(p.PC9, Level::High, Speed::Low); + let rst = Output::new(p.PB3, Level::High, Speed::Low); let spi = spi::Spi::new_blocking( p.SPI1, @@ -52,10 +53,13 @@ async fn main(_spawner: Spawner) { spi::Config::default() ); - let mut ad5940 = AD5940::new(spi, cs); + let mut ad5940 = AD5940::new(spi, cs, rst); + ad5940.reset().await.unwrap(); + Timer::after_millis(1).await; ad5940.system_init().await.unwrap(); - ad5940.init_temperature().await.unwrap(); + // ad5940.init_temperature().await.unwrap(); + ad5940.init_waveform().await.unwrap(); // Set up I2C for ADG2128 let i2c = i2c::I2c::new_blocking( @@ -69,17 +73,18 @@ async fn main(_spawner: Spawner) { // Initialize electrodes let mut electrodes = Electrodes::new(i2c); electrodes.reset_all(); - electrodes.set(Electrode::E11, AD5940Pin::CE0, State::ENABLED); - electrodes.set(Electrode::E12, AD5940Pin::RE0, State::ENABLED); - + electrodes.set(Electrode::E1, AD5940Pin::CE0, State::ENABLED); + electrodes.set(Electrode::E3, AD5940Pin::AIN1, State::ENABLED); + // electrodes.set(Electrode::E12, AD5940Pin::RE0, State::ENABLED); + loop { // Read chip id // let chip_id = ad5940.get_chipid().await.unwrap(); // info!("Chip ID: 0x{:04X}", chip_id); // Read temperature - let temp = ad5940.get_temperature().await.unwrap(); - info!("Temperature: {}°C", temp); + // let temp = ad5940.get_temperature().await.unwrap(); + // info!("Temperature: {}°C", temp); let result = electrodes.get_all(); info!("Electrodes states: {:?}", result);