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

@@ -16,6 +16,8 @@ embassy-time = { version = "0.4.0", features = ["defmt", "defmt-timestamp-uptime
defmt = "1.0.1" defmt = "1.0.1"
defmt-rtt = "1.0.0" defmt-rtt = "1.0.0"
bitflags = "2.9.1"
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0" cortex-m-rt = "0.7.0"
# embedded-hal = "0.2.6" # embedded-hal = "0.2.6"

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 { pub struct AD5940 {
spi: Spi<'static, Blocking>, spi: Spi<'static, Blocking>,
@@ -10,15 +13,16 @@ impl AD5940 {
AD5940 { spi, cs } AD5940 { spi, cs }
} }
fn read_reg_16(&mut self, address: u16) -> Result<u16, embassy_stm32::spi::Error> { async fn read_reg_16(&mut self, address: Register) -> Result<u16, Error> {
let addr_bytes = address.to_be_bytes();
// Write address command // Write address command
self.cs.set_low(); self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_SETADDR as u8])?; 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(); self.cs.set_high();
// Wait after cs is high
Timer::after_nanos(80).await;
// Read command // Read command
self.cs.set_low(); self.cs.set_low();
self.spi.blocking_write(&[Command::SPICMD_READREG as u8])?; self.spi.blocking_write(&[Command::SPICMD_READREG as u8])?;
@@ -30,22 +34,139 @@ impl AD5940 {
Ok(u16::from_be_bytes([data[1], data[2]])) Ok(u16::from_be_bytes([data[1], data[2]]))
} }
pub fn get_chipid(&mut self) -> Result<u16, embassy_stm32::spi::Error> { async fn read_reg_32(&mut self, address: Register) -> Result<u32, Error> {
self.read_reg_16(Register::CHIPID as u16) // 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(dead_code)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
enum Command { enum Command {
SPICMD_SETADDR = 0x20, SPICMD_SETADDR = 0x20,
SPICMD_READREG = 0x6D, SPICMD_READREG = 0x6D,
SPICMD_WRITEREG = 0x2D, SPICMD_WRITEREG = 0x2D,
SPICMD_READFIFO = 0x5F, SPICMD_READFIFO = 0x5F,
} }
#[allow(dead_code)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[repr(u16)] #[repr(u16)]
enum Register { 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
} }

31
src/ad5940_registers.rs Normal file
View File

@@ -0,0 +1,31 @@
use bitflags::bitflags;
bitflags! {
// Address 0x00002000, Reset: 0x00080000, Name: AFECON
pub struct ConfigurationRegister: u32 {
const reset = 0x00080000;
const DACBUFEN = 1 << 21;
const DACREFEN = 1 << 20;
const SINC2EN = 1 << 16;
const DFTEN = 1 << 15;
const WAVEGENEN = 1 << 14;
const TEMPCONVEN = 1 << 13;
const TEMPSENSEN = 1 << 12;
const TIAEN = 1 << 11;
const INAMPEN = 1 << 10;
const EXBUFEN = 1 << 9;
const ADCCONVEN = 1 << 8;
const ADCEN = 1 << 7;
const DACEN = 1 << 6;
const HSREFDIS = 1 << 5;
}
}
bitflags! {
// Address 0x000021A8, Reset: 0x00000000, Name: ADCCON
pub struct ADCConfigurationRegister: u32 {
const GNPGA_1_5 = 1 << 16;
const MUXSELN_TEMP = 0b01011 << 8;
const MUXSELP_TEMP = 0b01011;
}
}

View File

@@ -4,13 +4,15 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_stm32::{spi, Config}; use embassy_stm32::{adc, spi, Config};
use embassy_time::Timer; use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
mod ad5940; mod ad5940;
use ad5940::AD5940; use ad5940::AD5940;
mod ad5940_registers;
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
@@ -43,11 +45,18 @@ async fn main(_spawner: Spawner) {
); );
let mut ad5940 = AD5940::new(spi, cs); let mut ad5940 = AD5940::new(spi, cs);
ad5940.system_init().await.unwrap();
ad5940.init_temperature().await.unwrap();
loop { loop {
// Read chip id // Read chip id
let chip_id = ad5940.get_chipid().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
let temp = ad5940.get_temperature().await.unwrap();
info!("Temperature: {}°C", temp);
// info!("high"); // info!("high");
// led.set_high(); // led.set_high();