Updated library.

This commit is contained in:
2025-08-18 14:49:58 +02:00
parent eaeff4f527
commit d17ef6c7ae
5 changed files with 346 additions and 116 deletions

View File

@@ -18,10 +18,6 @@ pub struct SwitchConfig {
}
impl SwitchConfig {
pub fn new() -> Self {
Self::default()
}
pub fn t9con(mut self, t9con: T9CON) -> Self {
self.t9con = Some(t9con);
self
@@ -64,10 +60,6 @@ pub struct DspConfig {
}
impl DspConfig {
pub fn new() -> Self {
Self::default()
}
pub fn adc_mux_n(mut self, muxseln: MUXSELN) -> Self {
self.muxseln = Some(muxseln);
self
@@ -119,6 +111,43 @@ impl DspConfig {
}
}
#[allow(dead_code)]
#[derive(Default)]
pub struct SramConfig {
datafifosrcsel: Option<DATAFIFOSRCSEL>,
datafifoen: Option<DATAFIFOEN>,
data_mem_size: Option<DATA_MEM_SEL>,
cmd_mem_mode: Option<CMDMEMMDE>,
cmd_mem_size: Option<CMD_MEM_SEL>,
}
impl SramConfig {
pub fn datafifosrcsel(mut self, datafifosrcsel: DATAFIFOSRCSEL) -> Self {
self.datafifosrcsel = Some(datafifosrcsel);
self
}
pub fn datafifoen(mut self, datafifoen: DATAFIFOEN) -> Self {
self.datafifoen = Some(datafifoen);
self
}
pub fn data_size(mut self, data_mem_size: DATA_MEM_SEL) -> Self {
self.data_mem_size = Some(data_mem_size);
self
}
pub fn cmd_mode(mut self, cmd_mem_mode: CMDMEMMDE) -> Self {
self.cmd_mem_mode = Some(cmd_mem_mode);
self
}
pub fn cmd_size(mut self, cmd_mem_size: CMD_MEM_SEL) -> Self {
self.cmd_mem_size = Some(cmd_mem_size);
self
}
}
pub struct Sequencer {
}
@@ -464,28 +493,23 @@ impl AD5940 {
let mut current = self.read_reg(Register::SWCON).await?;
if let Some(t9con) = config.t9con {
current &= !(0b1 << 17);
current |= (t9con as u32) << 17;
current = T9CON::apply(current, t9con as u32);
}
if let Some(tmuxcon) = config.tmuxcon {
current &= !(0b1111 << 12);
current |= (tmuxcon as u32) << 12;
current = TMUXCON::apply(current, tmuxcon as u32);
}
if let Some(nmuxcon) = config.nmuxcon {
current &= !(0b1111 << 8);
current |= (nmuxcon as u32) << 8;
current = NMUXCON::apply(current, nmuxcon as u32);
}
if let Some(pmuxcon) = config.pmuxcon {
current &= !(0b1111 << 4);
current |= (pmuxcon as u32) << 4;
current = PMUXCON::apply(current, pmuxcon as u32);
}
if let Some(dmuxcon) = config.dmuxcon {
current &= !(0b1111);
current |= dmuxcon as u32;
current = DMUXCON::apply(current, dmuxcon as u32);
}
self.write_reg(Register::SWCON, current).await?;
@@ -498,12 +522,10 @@ impl AD5940 {
let mut current = self.read_reg(Register::ADCCON).await?;
if let Some(muxseln) = config.muxseln {
current &= !(0b11111 << 8);
current |= (muxseln as u32) << 8;
current = MUXSELN::apply(current, muxseln as u32);
}
if let Some(muxselp) = config.muxselp {
current &= !(0b11111);
current |= (muxselp as u32);
current = MUXSELP::apply(current, muxselp as u32);
}
self.write_reg(Register::ADCCON, current).await?;
@@ -512,13 +534,11 @@ impl AD5940 {
let mut current = self.read_reg(Register::HSRTIACON).await?;
if let Some(ctiacon) = config.ctiacon {
current &= !(0b1111 << 5);
current |= (ctiacon as u32) << 5;
current = CTIACON::apply(current, ctiacon as u32);
}
if let Some(rtiacon) = config.rtiacon {
current &= !(0b1111);
current |= rtiacon as u32;
current = RTIACON::apply(current, rtiacon as u32);
}
self.write_reg(Register::HSRTIACON, current).await?;
@@ -527,18 +547,15 @@ impl AD5940 {
let mut current = self.read_reg(Register::ADCFILTERCON).await?;
if let Some(sinc3osr) = config.sinc3osr{
current &= !(0b11 << 12);
current |= (sinc3osr as u32) << 12;
current = SINC3OSR::apply(current, sinc3osr as u32);
}
if let Some(sinc2osr) = config.sinc2osr {
current &= !(0b1111 << 8);
current |= (sinc2osr as u32) << 8;
current = SINC2OSR::apply(current, sinc2osr as u32);
}
if let Some(adcsamplerate) = config.adcsamplerate {
current &= !1;
current |= adcsamplerate as u32;
current = ADCSAMPLERATE::apply(current, adcsamplerate as u32);
}
self.write_reg(Register::ADCFILTERCON, current).await?;
@@ -547,16 +564,13 @@ impl AD5940 {
let mut current = self.read_reg(Register::DFTCON).await?;
if let Some(dftin) = config.dftin {
current &= !(0b11 << 20);
current |= (dftin as u32) << 20;
current = DFTINSEL::apply(current, dftin as u32);
}
if let Some(dftnum) = config.dftnum {
current &= !(0b1111 << 4);
current |= (dftnum as u32) << 4;
current = DFTNUM::apply(current, dftnum as u32);
}
if let Some(hanning) = config.hanning {
current &= !(0b1 << 0);
current |= (hanning as u32) << 0;
current = HANNING::apply(current, hanning as u32);
}
self.write_reg(Register::DFTCON, current).await?;
@@ -603,30 +617,42 @@ impl AD5940 {
self.write_reg(Register::WGFCW, sinefcw).await.unwrap();
}
pub async fn cmddatacon(&mut self) {
pub async fn apply_sram_config(&mut self, config: SramConfig) -> Result<(), Error> {
// Disable sequencer
let mut reg = self.read_reg(Register::SEQCON).await.unwrap();
reg &= !0x0000_0001; // Clear the enable bits
self.write_reg(Register::SEQCON, reg).await.unwrap();
self.write_reg(Register::SEQCON, 0x0000_0002).await?;
// Reset SEQCON
self.write_reg(Register::SEQCNT, 0x0000_0001).await.unwrap();
self.write_reg(Register::SEQCNT, 0x0000_0001).await?;
// Disable fifo
self.write_reg(Register::FIFOCON, 0b010 << 13).await.unwrap();
// self.write_reg(Register::FIFOCON, 0b011 << 13).await.unwrap();
// FIFICON
let mut current_fifocon = self.read_reg(Register::FIFOCON).await?;
if let Some(datafifosrcsel) = config.datafifosrcsel {
current_fifocon = DATAFIFOSRCSEL::apply(current_fifocon, datafifosrcsel as u32);
}
current_fifocon &= !(0b1 << 11); // Disable FIFO
self.write_reg(Register::FIFOCON, current_fifocon).await?;
let cmd = 0b101 << 9 | 0b001 << 6 | 0b01 << 3 | 0b01;
self.write_reg(Register::CMDDATACON, cmd).await.unwrap();
// CMDDATACON
let mut current = self.read_reg(Register::CMDDATACON).await?;
if let Some(size) = config.data_mem_size {
current = DATA_MEM_SEL::apply(current, size as u32);
}
if let Some(mode) = config.cmd_mem_mode {
current = CMDMEMMDE::apply(current, mode as u32);
}
if let Some(size) = config.cmd_mem_size {
current = CMD_MEM_SEL::apply(current, size as u32);
}
self.write_reg(Register::CMDDATACON, current).await?;
// Enable FIFO
self.write_reg(Register::FIFOCON, 0b010 << 13 | 1 << 11 ).await.unwrap();
// self.write_reg(Register::FIFOCON, 0b011 << 13 | 1 << 11 ).await.unwrap();
current_fifocon |= 0b1 << 11; // Enable FIFO
self.write_reg(Register::FIFOCON, current_fifocon).await?;
// Enable sequencer
let mut reg = self.read_reg(Register::SEQCON).await.unwrap();
reg |= 0x0000_0001; // Set the enable bit
self.write_reg(Register::SEQCON, reg).await.unwrap();
self.write_reg(Register::SEQCON, 0x0000_0003).await?;
Ok(())
}
pub async fn get_chipid(&mut self) -> u16 {
@@ -682,7 +708,7 @@ impl AD5940 {
self.write_reg(Register::WGCON, config_wgcon).await?;
// SWCON - set up switch matri
let switch_config = SwitchConfig::new()
let switch_config = SwitchConfig::default()
.nmuxcon(NMUXCON::N2Closed)
.pmuxcon(PMUXCON::P11Closed)
.dmuxcon(DMUXCON::D5Closed);
@@ -705,8 +731,6 @@ impl AD5940 {
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[repr(u8)]
enum Command {
SPICMD_SETADDR = 0x20,
@@ -722,9 +746,9 @@ enum Command {
pub enum Register {
ADIID = 0x0000_0400, // Analog Devices Inc., identification register
CHIPID = 0x0000_0404, // Chip identification register
TRIGSEQ = 0x0000_0430, // Trigger Sequencer Register
TRIGSEQ = 0x0000_0430, // Trigger Sequencer Register
AFECON = 0x0000_2000, // Configuration Register
SEQCON = 0x0000_2004, // Sequencer Configuration Register
SEQCON = 0x0000_2004, // Sequencer Configuration Register
FIFOCON = 0x0000_2008, // FIFO Configuration Register
SWCON = 0x0000_200C, // Switch Matrix Configuration Register
WGCON = 0x0000_2014, // Waveform Generator Configuration Register
@@ -739,7 +763,7 @@ pub enum Register {
SEQ0INFO = 0x0000_21CC, // Sequence 0 Information Register
SEQ1INFO = 0x0000_21E8, // Sequence 1 Information Register
SEQ2INFO = 0x0000_21D0, // Sequence 2 Information Register
CMDDATACON = 0x0000_21D8, // Command Data Control Register
CMDDATACON = 0x0000_21D8, // Command Data Control Register
SEQ3INFO = 0x0000_21E4, // Sequence 3 Information Register
AFEGENINTSTA = 0x0000_209C, // Analog Generation Interrupt Register
CMDFIFOWADDR = 0x0000_21D4, // Command FIFO Write Address Register
@@ -751,12 +775,12 @@ pub enum Register {
SEQCRC = 0x0000_2060, // Sequencer CRC Value Register
DATAFIFOTHRES = 0x0000_21E0, // Data FIFO Threshold Register
SYNCEXTDEVICE = 0x0000_2054, // Sync External Device Register
GP0CON = 0x0000_0000, // GPIO Port 0 Configuration Register
DATAFIFORD = 0x0000_206C, // Data FIFO Read Register
DFTCON = 0x0000_20D0, // DFT Configuration Register
HSDACCON = 0x0000_2010, // High Speed DAC Configuration Register
HSRTIACON = 0x0000_20F0, // High Speed RTIA Configuration Register
BUFSENCON = 0x0000_2180, // HIGH POWER AND LOW POWER BUFFER CONTROL REGISTER
FIFOCNTSTA = 0x0000_2200, // Command and data FIFO internal data count register
GP0CON = 0x0000_0000, // GPIO Port 0 Configuration Register
DATAFIFORD = 0x0000_206C, // Data FIFO Read Register
DFTCON = 0x0000_20D0, // DFT Configuration Register
HSDACCON = 0x0000_2010, // High Speed DAC Configuration Register
HSRTIACON = 0x0000_20F0, // High Speed RTIA Configuration Register
BUFSENCON = 0x0000_2180, // HIGH POWER AND LOW POWER BUFFER CONTROL REGISTER
FIFOCNTSTA = 0x0000_2200, // Command and data FIFO internal data count register
ADCFILTERCON = 0x0000_2044 // ADC Output Filters Configuration Register
}

View File

@@ -1,9 +1,27 @@
use bitflags::bitflags;
#[allow(dead_code)]
pub trait Resettable {
pub trait RegisterField {
/// Reset value for this field
fn reset() -> Self;
// fn msk() -> u32;
/// Bit offset of the field within the register
const BIT_OFFSET: u32;
/// Bitmask of the field (not shifted)
const MASK: u32;
/// Clears the field bits in the register
fn clear(reg: u32) -> u32 {
reg & !(Self::MASK << Self::BIT_OFFSET)
}
/// Applies a new value to the field in the register
fn apply(reg: u32, val: u32) -> u32 {
let cleared = reg & !(Self::MASK << Self::BIT_OFFSET);
let shifted = (val & Self::MASK) << Self::BIT_OFFSET;
cleared | shifted
}
}
#[allow(dead_code)]
@@ -12,13 +30,12 @@ pub enum T9CON {
T9Open = 0,
}
impl Resettable for T9CON {
impl RegisterField for T9CON {
fn reset() -> Self {
T9CON::T9Open
}
// fn msk() -> u32 {
// 0b1
// }
const BIT_OFFSET: u32 = 17;
const MASK: u32 = 0b1;
}
#[allow(dead_code)]
@@ -35,10 +52,12 @@ pub enum TMUXCON {
AllClosed = 0b1001,
}
impl Resettable for TMUXCON {
impl RegisterField for TMUXCON {
fn reset() -> Self {
TMUXCON::AllOpen
}
const BIT_OFFSET: u32 = 12;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -57,10 +76,12 @@ pub enum NMUXCON {
AllOpen = 0b1111,
}
impl Resettable for NMUXCON {
impl RegisterField for NMUXCON {
fn reset() -> Self {
NMUXCON::AllOpen
}
const BIT_OFFSET: u32 = 8;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -79,10 +100,12 @@ pub enum PMUXCON {
AllOpen = 0b1111,
}
impl Resettable for PMUXCON {
impl RegisterField for PMUXCON {
fn reset() -> Self {
PMUXCON::AllOpen
}
const BIT_OFFSET: u32 = 4;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -99,10 +122,12 @@ pub enum DMUXCON {
AllClosed = 0b1001
}
impl Resettable for DMUXCON {
impl RegisterField for DMUXCON {
fn reset() -> Self {
DMUXCON::AllOpen
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -110,19 +135,37 @@ impl Resettable for DMUXCON {
#[derive(Copy, Clone)]
pub enum MUXSELN
{
Floating = 0b00000,
HsTiaNeg = 0b00001,
LpTiaNeg = 0b00010,
AIN1 = 0b00101,
}
impl RegisterField for MUXSELN {
fn reset() -> Self {
MUXSELN::Floating
}
const BIT_OFFSET: u32 = 8;
const MASK: u32 = 0b11111;
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum MUXSELP {
Floating = 0b00000,
HsTiaPos = 0b00001,
AIN1 = 0b00101,
}
impl RegisterField for MUXSELP {
fn reset() -> Self {
MUXSELP::Floating
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b11111;
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Copy, Clone)]
@@ -132,10 +175,12 @@ pub enum DFTINSEL {
AdcRaw = 0b10
}
impl Resettable for DFTINSEL {
impl RegisterField for DFTINSEL {
fn reset() -> Self {
DFTINSEL::Sinc2
}
const BIT_OFFSET: u32 = 20;
const MASK: u32 = 0b11;
}
#[allow(dead_code)]
@@ -157,10 +202,28 @@ pub enum DFTNUM {
Num16384 = 0b1100,
}
impl Resettable for DFTNUM {
impl RegisterField for DFTNUM {
fn reset() -> Self {
DFTNUM::Num2048
}
const BIT_OFFSET: u32 = 4;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Copy, Clone)]
pub enum HANNING {
Disable = 0,
Enable = 1,
}
impl RegisterField for HANNING {
fn reset() -> Self {
HANNING::Disable
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b1;
}
#[allow(dead_code)]
@@ -174,10 +237,12 @@ pub enum CTIACON {
C32 = 1 << 4,
}
impl Resettable for CTIACON {
impl RegisterField for CTIACON {
fn reset() -> Self {
CTIACON::C1
}
const BIT_OFFSET: u32 = 5;
const MASK: u32 = 0b111_1111;
}
#[allow(dead_code)]
@@ -194,10 +259,12 @@ pub enum RTIACON {
Open = 0b1111,
}
impl Resettable for RTIACON {
impl RegisterField for RTIACON {
fn reset() -> Self {
RTIACON::Open
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -208,10 +275,12 @@ pub enum SINC3OSR {
R2 = 0b10,
}
impl Resettable for SINC3OSR {
impl RegisterField for SINC3OSR {
fn reset() -> Self {
SINC3OSR::R5
}
const BIT_OFFSET: u32 = 12;
const MASK: u32 = 0b11;
}
#[allow(dead_code)]
@@ -231,10 +300,12 @@ pub enum SINC2OSR {
R1333 = 0b1011,
}
impl Resettable for SINC2OSR {
impl RegisterField for SINC2OSR {
fn reset() -> Self {
SINC2OSR::R178
}
const BIT_OFFSET: u32 = 8;
const MASK: u32 = 0b1111;
}
#[allow(dead_code)]
@@ -244,10 +315,109 @@ pub enum ADCSAMPLERATE {
R1_6MHz = 0,
}
impl Resettable for ADCSAMPLERATE {
impl RegisterField for ADCSAMPLERATE {
fn reset() -> Self {
ADCSAMPLERATE::R1_6MHz
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b1;
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum DATAMEMMDE {
FIFOMode = 0b10,
Stream = 0b11,
}
impl RegisterField for DATAMEMMDE {
fn reset() -> Self {
DATAMEMMDE::FIFOMode
}
const BIT_OFFSET: u32 = 9;
const MASK: u32 = 0b11;
}
#[allow(dead_code, non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum DATA_MEM_SEL {
Reserved = 0b000,
Size2kB = 0b001,
Size4kB = 0b010,
Size6kB = 0b011,
}
impl RegisterField for DATA_MEM_SEL {
fn reset() -> Self {
DATA_MEM_SEL::Reserved
}
const BIT_OFFSET: u32 = 6;
const MASK: u32 = 0b111;
}
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum CMDMEMMDE {
MemoryMode = 0b01,
Reserved = 0b10,
}
impl RegisterField for CMDMEMMDE {
fn reset() -> Self {
CMDMEMMDE::Reserved
}
const BIT_OFFSET: u32 = 3;
const MASK: u32 = 0b111;
}
#[allow(dead_code, non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum CMD_MEM_SEL {
Reserved = 0x0,
Size2kB = 0x1,
Size4kB = 0x2,
Size6kB = 0x3,
}
impl RegisterField for CMD_MEM_SEL {
fn reset() -> Self {
CMD_MEM_SEL::Reserved
}
const BIT_OFFSET: u32 = 0;
const MASK: u32 = 0b111;
}
#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum DATAFIFOSRCSEL {
ADC = 0b000,
DFT = 0b010,
Sinc2 = 0b011,
Variance = 0b100,
Mean = 0b101,
}
impl RegisterField for DATAFIFOSRCSEL {
fn reset() -> Self {
DATAFIFOSRCSEL::ADC
}
const BIT_OFFSET: u32 = 13;
const MASK: u32 = 0b111;
}
#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum DATAFIFOEN {
FIFOisReset = 0b0,
Normal = 0b1,
}
impl RegisterField for DATAFIFOEN {
fn reset() -> Self {
DATAFIFOEN::FIFOisReset
}
const BIT_OFFSET: u32 = 11;
const MASK: u32 = 0b1;
}
bitflags! {

View File

@@ -21,7 +21,7 @@ use postcard_rpc::{
use bioz_icd_rs::{PingEndpoint, GetUniqueIdEndpoint, SetGreenLedEndpoint, StartImpedanceEndpoint, StopImpedanceEndpoint, StartImpedance, ImpedanceOutputTopic, ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST};
use crate::impedance::{IMPEDANCE_CHANNEL};
use crate::impedance::{ImpedanceSetupType, IMPEDANCE_CHANNEL};
// Postcard RPC types
type AppDriver = usb::Driver<'static, peripherals::USB>;
@@ -37,15 +37,19 @@ static STORAGE: AppStorage = AppStorage::new();
pub struct Context {
pub unique_id: [u8; 12],
pub impedance_setup: &'static ImpedanceSetupType,
}
pub struct SpawnCtx {
pub impedance_setup: &'static ImpedanceSetupType,
}
impl SpawnContext for Context {
type SpawnCtxt = SpawnCtx;
fn spawn_ctxt(&mut self) -> Self::SpawnCtxt {
SpawnCtx {}
SpawnCtx {
impedance_setup: self.impedance_setup,
}
}
}
@@ -59,13 +63,13 @@ define_dispatch! {
endpoints: {
list: ENDPOINT_LIST;
| EndpointTy | kind | handler |
| ---------- | ---- | ------- |
| PingEndpoint | blocking | ping_handler |
| GetUniqueIdEndpoint | blocking | get_unique_id_handler |
| SetGreenLedEndpoint | async | set_green_led_handler |
| StartImpedanceEndpoint | spawn | start_impedance_handler |
| StopImpedanceEndpoint | async | stop_impedance_handler |
| EndpointTy | kind | handler |
| ---------- | ---- | ------- |
| PingEndpoint | blocking | ping_handler |
| GetUniqueIdEndpoint | blocking | get_unique_id_handler |
| SetGreenLedEndpoint | async | set_green_led_handler |
| StartImpedanceEndpoint | spawn | start_single_impedance_handler |
| StopImpedanceEndpoint | async | stop_single_impedance_handler |
};
topics_in: {
list: TOPICS_IN_LIST;
@@ -111,13 +115,14 @@ async fn server_run(mut server: AppServer) {
// ---
pub fn init_communication(usb_driver: Driver<'static, peripherals::USB>, spawner: Spawner) {
pub fn init_communication(usb_driver: Driver<'static, peripherals::USB>, impedance_setup: &'static ImpedanceSetupType, spawner: Spawner) {
// Initialize communication peripherals
let pbufs = PBUFS.take();
let config = usb_config();
let context = Context {
unique_id: *uid::uid(),
impedance_setup: impedance_setup,
};
let (device, tx_impl, rx_impl) = STORAGE.init(usb_driver, config, pbufs.tx_buf.as_mut_slice());
@@ -158,11 +163,16 @@ static RUNNING: Mutex<ThreadModeRawMutex, bool> = Mutex::new(false);
static STOP: Mutex<ThreadModeRawMutex, bool> = Mutex::new(false);
#[embassy_executor::task]
pub async fn start_impedance_handler(_context: SpawnCtx, header: VarHeader, rqst: StartImpedance, sender: Sender<AppTx>) {
info!("Start impedance measurement with rate {:?} Hz.", rqst.update_frequency);
pub async fn start_single_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: StartImpedance, sender: Sender<AppTx>) {
info!("Start impedance measurement at {:?} Hz.", rqst.sinus_frequency);
*RUNNING.lock().await = true;
// Init the sequencer
context.impedance_setup.lock().await.init_single_frequency_measurement(rqst.sinus_frequency).await;
// Trigger the sequencer
context.impedance_setup.lock().await.start_measurement().await;
if sender
.reply::<StartImpedanceEndpoint>(header.seq_no, &())
.await
@@ -193,7 +203,7 @@ pub async fn start_impedance_handler(_context: SpawnCtx, header: VarHeader, rqst
*STOP.lock().await = false;
}
pub async fn stop_impedance_handler(_context: &mut Context, _header: VarHeader, _rqst: ()) -> bool {
pub async fn stop_single_impedance_handler(_context: &mut Context, _header: VarHeader, _rqst: ()) -> bool {
info!("Stop impedance measurement");
let was_busy = *RUNNING.lock().await;
if was_busy {

View File

@@ -3,6 +3,9 @@ use defmt::{info, error};
use embassy_stm32::spi::Error;
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
use embassy_sync::channel::Channel;
use embassy_sync::mutex::Mutex;
use static_cell::StaticCell;
use crate::ad5940::*;
use crate::ad5940_registers::*;
@@ -11,13 +14,17 @@ use bioz_icd_rs::ImpedanceOutput;
pub static IMPEDANCE_CHANNEL: Channel<ThreadModeRawMutex, ImpedanceOutput, 2000> = Channel::new();
pub type ImpedanceSetupType = Mutex<ThreadModeRawMutex, ImpedanceSetup>;
pub static IMPEDANCE_SETUP: StaticCell<ImpedanceSetupType> = StaticCell::new();
pub struct ImpedanceSetup {
ad5940: AD5940,
dsp_config: Option<DspConfig>,
}
impl ImpedanceSetup {
pub fn new(ad5940: AD5940) -> Self {
ImpedanceSetup { ad5940 }
ImpedanceSetup { ad5940, dsp_config: None }
}
pub async fn init(&mut self) -> Result<(), Error> {
@@ -48,10 +55,16 @@ impl ImpedanceSetup {
.hanning(true);
self.ad5940.apply_dsp_config(&dsp_config).await.unwrap();
self.dsp_config = Some(dsp_config);
let test = self.ad5940.sequencer_calculate_wait_time(&dsp_config).await.unwrap();
info!("Wait time: {:?}", test);
// Set SRAM configuration (cmd and data sram)
let sram_config = SramConfig::default()
.datafifosrcsel(DATAFIFOSRCSEL::DFT)
.datafifoen(DATAFIFOEN::Normal)
.data_size(DATA_MEM_SEL::Size2kB)
.cmd_mode(CMDMEMMDE::MemoryMode)
.cmd_size(CMD_MEM_SEL::Size2kB);
self.ad5940.apply_sram_config(sram_config).await.unwrap();
// WGCON: set sinus output
let config_wgcon = WGCON::TYPESEL_SIN.bits();
@@ -60,15 +73,24 @@ impl ImpedanceSetup {
Ok(())
}
pub async fn init_measurement(&mut self) {
pub async fn init_single_frequency_measurement(&mut self, frequency: u32) {
// Configure GPIOs
self.ad5940.write_reg(Register::GP0CON, 0b10 << 4 | 0b10 << 2 | 0b10).await.unwrap();
self.ad5940.write_reg(Register::SYNCEXTDEVICE, 0b111).await.unwrap();
// Calculate wait time between measurement start and stop
let mut wait_time = 0;
if let Some(dsp_config) = &self.dsp_config {
wait_time = self.ad5940.sequencer_calculate_wait_time(dsp_config).await.unwrap();
info!("Sinus periods per DFT: {}", wait_time as f32 / 16e6 * frequency as f32);
} else {
error!("DSP configuration not set, cannot calculate wait time");
}
// Configure sequencer
self.ad5940.sequencer_enable(true).await;
self.ad5940.wgfcw(50000).await;
self.ad5940.wgfcw(frequency).await;
let wg_amplitude = 557; // 2047 is the maximum amplitude for a 12-bit DAC --> 1.62V peak-to-peak
self.ad5940.write_reg(Register::WGAMPLITUDE, wg_amplitude).await.unwrap();
@@ -83,9 +105,8 @@ impl ImpedanceSetup {
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON::ADCEN, true).await;
self.ad5940.sequencer_wait(16*10).await; // 10 us
self.ad5940.afecon(AFECON::ADCCONVEN | AFECON::DFTEN, true).await;
// self.ad5940.sequencer_wait(16 * 102_400).await; // 0.75 second // 0,0512
self.ad5940.sequencer_wait(16 * 12_800).await; // 0.75 second // 0,0512
self.ad5940.sequencer_wait(16*20).await; // 0.75 second // 0,0512
self.ad5940.sequencer_wait(wait_time).await; // Determined above
self.ad5940.sequencer_wait(16*20).await; // 10 us
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
// Rz
@@ -99,9 +120,8 @@ impl ImpedanceSetup {
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON::ADCEN, true).await;
self.ad5940.sequencer_wait(16*10).await; // 10 us
self.ad5940.afecon(AFECON::ADCCONVEN | AFECON::DFTEN, true).await;
// self.ad5940.sequencer_wait(16 * 102_400).await; // 0.75 second
self.ad5940.sequencer_wait(16 * 12_800).await; // 0.75 second // 0,0512
self.ad5940.sequencer_wait(16*20).await; // 0.75 second // 0,0512
self.ad5940.sequencer_wait(wait_time).await; // Determined above
self.ad5940.sequencer_wait(16*20).await; // 10 us
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
// Toggle leds
@@ -111,13 +131,13 @@ impl ImpedanceSetup {
self.ad5940.sequencer_enable(false).await;
// // Configure the sequencer cmd data sram
self.ad5940.cmddatacon().await;
// Write sequence to SRAM
let start_address = 0;
self.ad5940.sequencer_cmd_write(start_address).await;
self.ad5940.sequencer_info_configure(0, self.ad5940.seq_len, start_address).await;
self.start_measurement().await;
}
pub async fn start_measurement(&mut self) {

View File

@@ -4,6 +4,7 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_stm32::exti::ExtiInput;
use embassy_sync::mutex::Mutex;
use embassy_time::{Timer, Duration};
use embassy_futures::{select::select, select::Either};
use embassy_stm32::gpio::{Level, Output, Speed};
@@ -37,7 +38,7 @@ use communication::{init_communication, LED_FREQUENCY_SIGNAL};
use impedance::IMPEDANCE_CHANNEL;
mod impedance;
use impedance::ImpedanceSetup;
use impedance::{ImpedanceSetup, ImpedanceSetupType, IMPEDANCE_SETUP};
bind_interrupts!(struct Irqs {
USB_DRD_FS => usb::InterruptHandler<peripherals::USB>;
@@ -93,7 +94,9 @@ async fn main(spawner: Spawner) {
// ad5940.init_waveform().await.unwrap();
let mut impedance_setup = ImpedanceSetup::new(ad5940);
impedance_setup.init().await.unwrap();
impedance_setup.init_measurement().await;
let mut impedance_setup = IMPEDANCE_SETUP.init(Mutex::new(impedance_setup));
// impedance_setup.lock().await.init_single_frequency_measurement().await;
// // Set up I2C for ADG2128
// let i2c = i2c::I2c::new_blocking(
@@ -117,13 +120,13 @@ async fn main(spawner: Spawner) {
// Create USB driver and start postcard-rpc server
let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
init_communication(driver, spawner);
init_communication(driver, impedance_setup, spawner);
// Green led task
// spawner.must_spawn(green_led(led));
// Trigger the sequencer
impedance_setup.start_measurement().await;
// impedance_setup.start_measurement().await;
// Set up interrupt at GPIO for AD5940
let ad5940_gpio_0 = ExtiInput::new(p.PC8, p.EXTI8, embassy_stm32::gpio::Pull::Up);
@@ -169,11 +172,14 @@ async fn green_led(mut led: Output<'static>) {
}
#[embassy_executor::task]
async fn impedance_setup_readout_task(mut pin: ExtiInput<'static>, mut impedance_setup: ImpedanceSetup) {
async fn impedance_setup_readout_task(mut pin: ExtiInput<'static>, impedance_setup: &'static ImpedanceSetupType) {
loop {
// Wait untill sequence is done
pin.wait_for_rising_edge().await;
// Lock the impedance setup
let mut impedance_setup = impedance_setup.lock().await;
// Trigger the sequencer again
impedance_setup.start_measurement().await;