Working temperature readout.

This commit is contained in:
2025-07-16 14:57:34 +02:00
parent c6b250a4a8
commit ed49071ffa
4 changed files with 176 additions and 13 deletions

View File

@@ -1,4 +1,7 @@
use embassy_stm32::{gpio::Output, mode::Blocking, spi::Spi};
use embassy_stm32::{gpio::Output, mode::Blocking, spi::Spi, spi::Error};
use embassy_time::Timer;
use crate::ad5940_registers::*;
pub struct AD5940 {
spi: Spi<'static, Blocking>,
@@ -10,15 +13,16 @@ impl AD5940 {
AD5940 { spi, cs }
}
fn read_reg_16(&mut self, address: u16) -> Result<u16, embassy_stm32::spi::Error> {
let addr_bytes = address.to_be_bytes();
async fn read_reg_16(&mut self, address: Register) -> Result<u16, Error> {
// Write address command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?;
self.spi.blocking_write(&addr_bytes)?;
self.spi.blocking_write(&[address as u16])?;
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
// Read command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_READREG as u8])?;
@@ -30,22 +34,139 @@ impl AD5940 {
Ok(u16::from_be_bytes([data[1], data[2]]))
}
pub fn get_chipid(&mut self) -> Result<u16, embassy_stm32::spi::Error> {
self.read_reg_16(Register::CHIPID as u16)
async fn read_reg_32(&mut self, address: Register) -> Result<u32, Error> {
// Write address command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?;
self.spi.blocking_write(&[address as u16])?;
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
// Read command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_READREG as u8])?;
let mut data = [0u8; 5]; // First byte dummy, then four data bytes
self.spi.blocking_read(&mut data)?;
self.cs.set_high();
Ok(u32::from_be_bytes([data[1], data[2], data[3], data[4]]))
}
async fn write_reg_32(&mut self, address: Register, value: u32) -> Result<(), Error> {
self.write_reg_32_raw(address as u16, value).await
}
async fn write_reg_32_raw(&mut self, address: u16, value: u32) -> Result<(), Error> {
// Write address command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?;
self.spi.blocking_write(&[address as u16])?;
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
// Write value command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_WRITEREG as u8])?;
self.spi.blocking_write(&[value])?;
self.cs.set_high();
Ok(())
}
async fn write_reg_16_raw(&mut self, address: u16, value: u16) -> Result<(), Error> {
// Write address command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?;
self.spi.blocking_write(&[address as u16])?;
self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
// Write value command
self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_WRITEREG as u8])?;
self.spi.blocking_write(&[value])?;
self.cs.set_high();
Ok(())
}
pub async fn system_init(&mut self) -> Result<(), Error> {
// See table 14
self.write_reg_16_raw(0x0908, 0x02C9).await?;
self.write_reg_16_raw(0x0C08, 0x206C).await?;
self.write_reg_16_raw(0x21F0, 0x0010).await?;
self.write_reg_16_raw(0x0410, 0x02C9).await?;
self.write_reg_16_raw(0x0A28, 0x0009).await?;
self.write_reg_16_raw(0x238C, 0x0104).await?;
self.write_reg_16_raw(0x0A04, 0x4859).await?;
self.write_reg_16_raw(0x0A04, 0xF27B).await?;
self.write_reg_16_raw(0x0A00, 0x8009).await?;
self.write_reg_16_raw(0x22F0, 0x0000).await?;
Ok(())
}
pub async fn get_chipid(&mut self) -> Result<u16, Error> {
self.read_reg_16(Register::CHIPID).await
}
pub async fn get_adiid(&mut self) -> Result<u16, Error> {
self.read_reg_16(Register::ADIID).await
}
pub async fn init_temperature(&mut self) -> Result<(), Error> {
// AFECON:
let mut config_afecon = ConfigurationRegister::reset.bits() | ConfigurationRegister::TEMPSENSEN.bits() | ConfigurationRegister::ADCEN.bits();
self.write_reg_32(Register::AFECON, config_afecon).await?;
// ADCCON
let config_adccon = ADCConfigurationRegister::GNPGA_1_5.bits() | ADCConfigurationRegister::MUXSELN_TEMP.bits() | ADCConfigurationRegister::MUXSELP_TEMP.bits();
self.write_reg_32(Register::ADCCON, config_adccon).await?;
// AFECON - start conversion
config_afecon |= ConfigurationRegister::TEMPCONVEN.bits();
config_afecon |= ConfigurationRegister::ADCCONVEN.bits();
self.write_reg_32(Register::AFECON, config_afecon).await?;
Ok(())
}
pub async fn get_temperature(&mut self) -> Result<f32, Error> {
// See page 57 of the datasheet for temperature calculation
let pga_gain = 1.5;
let k = 8.13;
let mut tempsensdat0: u32 = self.read_reg_32(Register::TEMPSENSDAT).await?;
tempsensdat0 &= 0x0000FFFF;
Ok((tempsensdat0 as f32/(pga_gain * k)) - 273.15)
}
}
#[allow(dead_code)]
#[allow(non_camel_case_types)]
enum Command {
SPICMD_SETADDR = 0x20,
SPICMD_READREG = 0x6D,
SPICMD_SETADDR = 0x20,
SPICMD_READREG = 0x6D,
SPICMD_WRITEREG = 0x2D,
SPICMD_READFIFO = 0x5F,
}
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[repr(u16)]
enum Register {
CHIPID = 0x0000_0404, // Changed from u32 to u16, as expected by SPI write
ADIID = 0x0000_0400, // Analog Devices Inc., identification register
CHIPID = 0x0000_0404, // Chip identification register
AFECON = 0x0000_2000, // Configuration 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
}