Working waveform (sinus) generator.

This commit is contained in:
2025-07-23 14:56:41 +02:00
parent 0c18664e48
commit e6c3d6d06f
3 changed files with 98 additions and 9 deletions

View File

@@ -6,11 +6,19 @@ use crate::ad5940_registers::*;
pub struct AD5940 { pub struct AD5940 {
spi: Spi<'static, Blocking>, spi: Spi<'static, Blocking>,
cs: Output<'static>, cs: Output<'static>,
rst: Output<'static>,
} }
impl AD5940 { impl AD5940 {
pub fn new(spi: Spi<'static, Blocking>, cs: Output<'static>) -> Self { pub fn new(spi: Spi<'static, Blocking>, cs: Output<'static>, rst: Output<'static>) -> Self {
AD5940 { spi, cs } 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<u16, Error> { async fn read_reg_16(&mut self, address: Register) -> Result<u16, Error> {
@@ -109,6 +117,13 @@ impl AD5940 {
self.write_reg_16_raw(0x0A04, 0xF27B).await?; self.write_reg_16_raw(0x0A04, 0xF27B).await?;
self.write_reg_16_raw(0x0A00, 0x8009).await?; self.write_reg_16_raw(0x0A00, 0x8009).await?;
self.write_reg_16_raw(0x22F0, 0x0000).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(()) Ok(())
} }
@@ -147,6 +162,42 @@ impl AD5940 {
Ok((tempsensdat0 as f32/(pga_gain * k)) - 273.15) 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)] #[allow(dead_code)]
@@ -165,8 +216,13 @@ enum Register {
ADIID = 0x0000_0400, // Analog Devices Inc., identification register ADIID = 0x0000_0400, // Analog Devices Inc., identification register
CHIPID = 0x0000_0404, // Chip identification register CHIPID = 0x0000_0404, // Chip identification register
AFECON = 0x0000_2000, // Configuration 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 TEMPSENSDAT = 0x0000_2084, // Temperature Sensor Result Register
ADCDAT = 0x0000_2074, // ADC Raw Result Register ADCDAT = 0x0000_2074, // ADC Raw Result Register
TEMPSENS = 0x0000_2174, // Temperature Sensor Configuration Register TEMPSENS = 0x0000_2174, // Temperature Sensor Configuration Register
ADCCON = 0x0000_21A8, // ADC Configuration Register ADCCON = 0x0000_21A8, // ADC Configuration Register
PMBW = 0x0000_22F0, // Power Mode Configuration Register
} }

View File

@@ -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! { bitflags! {
// Address 0x000021A8, Reset: 0x00000000, Name: ADCCON // Address 0x000021A8, Reset: 0x00000000, Name: ADCCON
pub struct ADCConfigurationRegister: u32 { pub struct ADCConfigurationRegister: u32 {

View File

@@ -43,6 +43,7 @@ async fn main(_spawner: Spawner) {
// Set up SPI for AD5940 // Set up SPI for AD5940
let cs = Output::new(p.PC9, Level::High, Speed::Low); 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( let spi = spi::Spi::new_blocking(
p.SPI1, p.SPI1,
@@ -52,10 +53,13 @@ async fn main(_spawner: Spawner) {
spi::Config::default() 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.system_init().await.unwrap();
ad5940.init_temperature().await.unwrap(); // ad5940.init_temperature().await.unwrap();
ad5940.init_waveform().await.unwrap();
// Set up I2C for ADG2128 // Set up I2C for ADG2128
let i2c = i2c::I2c::new_blocking( let i2c = i2c::I2c::new_blocking(
@@ -69,17 +73,18 @@ async fn main(_spawner: Spawner) {
// Initialize electrodes // Initialize electrodes
let mut electrodes = Electrodes::new(i2c); let mut electrodes = Electrodes::new(i2c);
electrodes.reset_all(); electrodes.reset_all();
electrodes.set(Electrode::E11, AD5940Pin::CE0, State::ENABLED); electrodes.set(Electrode::E1, AD5940Pin::CE0, State::ENABLED);
electrodes.set(Electrode::E12, AD5940Pin::RE0, State::ENABLED); electrodes.set(Electrode::E3, AD5940Pin::AIN1, State::ENABLED);
// electrodes.set(Electrode::E12, AD5940Pin::RE0, State::ENABLED);
loop { loop {
// Read chip id // Read chip id
// let chip_id = ad5940.get_chipid().await.unwrap(); // let chip_id = ad5940.get_chipid().await.unwrap();
// info!("Chip ID: 0x{:04X}", chip_id); // info!("Chip ID: 0x{:04X}", chip_id);
// Read temperature // Read temperature
let temp = ad5940.get_temperature().await.unwrap(); // let temp = ad5940.get_temperature().await.unwrap();
info!("Temperature: {}°C", temp); // info!("Temperature: {}°C", temp);
let result = electrodes.get_all(); let result = electrodes.get_all();
info!("Electrodes states: {:?}", result); info!("Electrodes states: {:?}", result);