mirror of
https://github.com/hubaldv/bioz-firmware-rs.git
synced 2026-04-24 08:42:03 +00:00
Pass electrode config from GUI to hardware.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use defmt::info;
|
use defmt::{info, error};
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_sync::blocking_mutex::raw::{ThreadModeRawMutex, CriticalSectionRawMutex};
|
use embassy_sync::blocking_mutex::raw::{ThreadModeRawMutex, CriticalSectionRawMutex};
|
||||||
@@ -20,10 +20,13 @@ use postcard_rpc::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bioz_icd_rs::{GetUniqueIdEndpoint, MeasurementPointSet, SweepImpedanceOutputTopic, SweepImpedanceResult, SweepImpedanceStartRequest, PingEndpoint, SetGreenLedEndpoint, SingleImpedanceOutputTopic, SingleImpedanceStartRequest, StartSweepImpedanceEndpoint, StartSingleImpedanceEndpoint, StopImpedanceEndpoint, BioImpedanceLeadMode, ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST};
|
use bioz_icd_rs::{GetUniqueIdEndpoint, GetMultiplexerCapabilityEndpoint, MultiplexerCapability, ElectrodeConfiguration, MeasurementPointSet, SweepImpedanceOutputTopic, SweepImpedanceResult, SweepImpedanceStartRequest, PingEndpoint, SetGreenLedEndpoint, SingleImpedanceOutputTopic, SingleImpedanceStartRequest, StartSweepImpedanceEndpoint, StartSingleImpedanceEndpoint, StopImpedanceEndpoint, BioImpedanceLeadMode, ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST};
|
||||||
|
|
||||||
|
use crate::electrodes;
|
||||||
use crate::impedance::{ImpedanceSetupType, RunningMode, IMPEDANCE_CHANNEL_SWEEP, IMPEDANCE_CHANNEL_SINGLE};
|
use crate::impedance::{ImpedanceSetupType, RunningMode, IMPEDANCE_CHANNEL_SWEEP, IMPEDANCE_CHANNEL_SINGLE};
|
||||||
|
|
||||||
|
use crate::icd_mapping::IntoLocalElectrode;
|
||||||
|
|
||||||
// Postcard RPC types
|
// Postcard RPC types
|
||||||
type AppDriver = usb::Driver<'static, peripherals::USB>;
|
type AppDriver = usb::Driver<'static, peripherals::USB>;
|
||||||
type AppStorage = WireStorage<ThreadModeRawMutex, AppDriver, 256, 256, 64, 256>;
|
type AppStorage = WireStorage<ThreadModeRawMutex, AppDriver, 256, 256, 64, 256>;
|
||||||
@@ -64,14 +67,15 @@ define_dispatch! {
|
|||||||
endpoints: {
|
endpoints: {
|
||||||
list: ENDPOINT_LIST;
|
list: ENDPOINT_LIST;
|
||||||
|
|
||||||
| EndpointTy | kind | handler |
|
| EndpointTy | kind | handler |
|
||||||
| ---------- | ---- | ------- |
|
| ---------- | ---- | ------- |
|
||||||
| PingEndpoint | blocking | ping_handler |
|
| PingEndpoint | blocking | ping_handler |
|
||||||
| GetUniqueIdEndpoint | blocking | get_unique_id_handler |
|
| GetUniqueIdEndpoint | blocking | get_unique_id_handler |
|
||||||
| SetGreenLedEndpoint | async | set_green_led_handler |
|
| GetMultiplexerCapabilityEndpoint | async | get_multiplexer_capability_handler |
|
||||||
| StartSingleImpedanceEndpoint | spawn | start_single_impedance_handler |
|
| SetGreenLedEndpoint | async | set_green_led_handler |
|
||||||
| StartSweepImpedanceEndpoint | spawn | start_sweep_impedance_handler |
|
| StartSingleImpedanceEndpoint | spawn | start_single_impedance_handler |
|
||||||
| StopImpedanceEndpoint | async | stop_impedance_handler |
|
| StartSweepImpedanceEndpoint | spawn | start_sweep_impedance_handler |
|
||||||
|
| StopImpedanceEndpoint | async | stop_impedance_handler |
|
||||||
};
|
};
|
||||||
topics_in: {
|
topics_in: {
|
||||||
list: TOPICS_IN_LIST;
|
list: TOPICS_IN_LIST;
|
||||||
@@ -153,6 +157,15 @@ pub fn get_unique_id_handler(context: &mut Context, _header: VarHeader, _rqst: (
|
|||||||
context.unique_id
|
context.unique_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_multiplexer_capability_handler(context: &mut Context, _header: VarHeader, _rqst: ()) -> MultiplexerCapability {
|
||||||
|
info!("get_multiplexer_capability");
|
||||||
|
if context.impedance_setup.lock().await.electrodes.is_some() {
|
||||||
|
MultiplexerCapability::Present
|
||||||
|
} else {
|
||||||
|
MultiplexerCapability::Absent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub static LED_FREQUENCY_SIGNAL: Signal<CriticalSectionRawMutex, f32> = Signal::new();
|
pub static LED_FREQUENCY_SIGNAL: Signal<CriticalSectionRawMutex, f32> = Signal::new();
|
||||||
|
|
||||||
pub async fn set_green_led_handler(_context: &mut Context, _header: VarHeader, rqst: f32) {
|
pub async fn set_green_led_handler(_context: &mut Context, _header: VarHeader, rqst: f32) {
|
||||||
@@ -167,6 +180,31 @@ static STOP: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
|||||||
pub async fn start_single_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: SingleImpedanceStartRequest, sender: Sender<AppTx>) {
|
pub async fn start_single_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: SingleImpedanceStartRequest, sender: Sender<AppTx>) {
|
||||||
info!("Start impedance measurement at {:?} Hz.", rqst.sinus_frequency);
|
info!("Start impedance measurement at {:?} Hz.", rqst.sinus_frequency);
|
||||||
|
|
||||||
|
// Set the electrodes
|
||||||
|
if let Some(config) = rqst.electrode_config {
|
||||||
|
let mut setup = context.impedance_setup.lock().await;
|
||||||
|
|
||||||
|
let Some(e) = &mut setup.electrodes else {
|
||||||
|
error!("Cannot set electrode configuration, multiplexer not present");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
e.reset_all();
|
||||||
|
|
||||||
|
match config {
|
||||||
|
ElectrodeConfiguration::WithMultiplexer2Lead(i1, i2) => {
|
||||||
|
e.set(i1.into_embedded_electrode_number(), electrodes::AD5940Pin::CE0, crate::State::ENABLED);
|
||||||
|
e.set(i2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN1, crate::State::ENABLED);
|
||||||
|
}
|
||||||
|
ElectrodeConfiguration::WithMultiplexer4Lead(i1, i2, v1, v2) => {
|
||||||
|
e.set(i1.into_embedded_electrode_number(), electrodes::AD5940Pin::CE0, crate::State::ENABLED);
|
||||||
|
e.set(i2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN1, crate::State::ENABLED);
|
||||||
|
e.set(v1.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN2, crate::State::ENABLED);
|
||||||
|
e.set(v2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN3, crate::State::ENABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mark the impedance setup as running
|
// Mark the impedance setup as running
|
||||||
match rqst.lead_mode {
|
match rqst.lead_mode {
|
||||||
BioImpedanceLeadMode::TwoLead => context.impedance_setup.lock().await.running_mode = RunningMode::SingleFrequency2Lead,
|
BioImpedanceLeadMode::TwoLead => context.impedance_setup.lock().await.running_mode = RunningMode::SingleFrequency2Lead,
|
||||||
@@ -221,8 +259,36 @@ pub async fn start_single_impedance_handler(context: SpawnCtx, header: VarHeader
|
|||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn start_sweep_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: SweepImpedanceStartRequest, sender: Sender<AppTx>) {
|
pub async fn start_sweep_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: SweepImpedanceStartRequest, sender: Sender<AppTx>) {
|
||||||
// Mark the impedance setup as running
|
// Set the electrodes
|
||||||
|
if let Some(config) = rqst.electrode_config {
|
||||||
|
let mut setup = context.impedance_setup.lock().await;
|
||||||
|
|
||||||
|
let Some(e) = &mut setup.electrodes else {
|
||||||
|
error!("Cannot set electrode configuration, multiplexer not present");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
e.reset_all();
|
||||||
|
|
||||||
|
match config {
|
||||||
|
ElectrodeConfiguration::WithMultiplexer2Lead(i1, i2) => {
|
||||||
|
e.set(i1.into_embedded_electrode_number(), electrodes::AD5940Pin::CE0, crate::State::ENABLED);
|
||||||
|
e.set(i2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN1, crate::State::ENABLED);
|
||||||
|
}
|
||||||
|
ElectrodeConfiguration::WithMultiplexer4Lead(i1, i2, v1, v2) => {
|
||||||
|
e.set(i1.into_embedded_electrode_number(), electrodes::AD5940Pin::CE0, crate::State::ENABLED);
|
||||||
|
e.set(i2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN1, crate::State::ENABLED);
|
||||||
|
e.set(v1.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN2, crate::State::ENABLED);
|
||||||
|
e.set(v2.into_embedded_electrode_number(), electrodes::AD5940Pin::AIN3, crate::State::ENABLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the impedance setup as running
|
||||||
|
match rqst.lead_mode {
|
||||||
|
BioImpedanceLeadMode::TwoLead => context.impedance_setup.lock().await.running_mode = RunningMode::SweepFrequency2Lead(rqst.points),
|
||||||
|
BioImpedanceLeadMode::FourLead => context.impedance_setup.lock().await.running_mode = RunningMode::SweepFrequency4Lead(rqst.points),
|
||||||
|
}
|
||||||
|
|
||||||
// Init the sequencer
|
// Init the sequencer
|
||||||
let response = match (rqst.lead_mode, rqst.points) {
|
let response = match (rqst.lead_mode, rqst.points) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use embassy_sync::blocking_mutex::NoopMutex;
|
|||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use crate::{ad5940, adg2128::{GetX, SetX, SetY, State, ADG2128}};
|
use crate::{adg2128::{GetX, SetX, SetY, State, ADG2128}};
|
||||||
|
|
||||||
static I2C_BUS: StaticCell<NoopMutex<RefCell<i2c::I2c<'static, Blocking, Master>>>> = StaticCell::new();
|
static I2C_BUS: StaticCell<NoopMutex<RefCell<i2c::I2c<'static, Blocking, Master>>>> = StaticCell::new();
|
||||||
|
|
||||||
@@ -26,7 +26,6 @@ impl Electrode {
|
|||||||
Electrode::E16, Electrode::E17, Electrode::E18, Electrode::E19,
|
Electrode::E16, Electrode::E17, Electrode::E18, Electrode::E19,
|
||||||
Electrode::E20, Electrode::E21, Electrode::E22, Electrode::E23,
|
Electrode::E20, Electrode::E21, Electrode::E22, Electrode::E23,
|
||||||
];
|
];
|
||||||
|
|
||||||
*VARIANTS.get(value as usize).expect("Invalid value for SetX")
|
*VARIANTS.get(value as usize).expect("Invalid value for SetX")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::ad5940_registers::DFTNUM;
|
use crate::ad5940_registers::DFTNUM;
|
||||||
use bioz_icd_rs::IcdDftNum;
|
use crate::electrodes::Electrode;
|
||||||
|
use bioz_icd_rs::{IcdDftNum, ElectrodeOptionsWithMultiplexer};
|
||||||
|
|
||||||
// Map ICD types to register types
|
// Map ICD types to register types
|
||||||
pub trait IntoDftnum {
|
pub trait IntoDftnum {
|
||||||
@@ -25,3 +26,38 @@ impl IntoDftnum for IcdDftNum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IntoLocalElectrode {
|
||||||
|
fn into_embedded_electrode_number(self) -> Electrode;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoLocalElectrode for ElectrodeOptionsWithMultiplexer {
|
||||||
|
fn into_embedded_electrode_number(self) -> Electrode {
|
||||||
|
match self {
|
||||||
|
ElectrodeOptionsWithMultiplexer::E0 => Electrode::E0,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E1 => Electrode::E1,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E2 => Electrode::E2,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E3 => Electrode::E3,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E4 => Electrode::E4,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E5 => Electrode::E5,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E6 => Electrode::E6,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E7 => Electrode::E7,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E8 => Electrode::E8,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E9 => Electrode::E9,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E10 => Electrode::E10,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E11 => Electrode::E11,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E12 => Electrode::E12,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E13 => Electrode::E13,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E14 => Electrode::E14,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E15 => Electrode::E15,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E16 => Electrode::E16,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E17 => Electrode::E17,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E18 => Electrode::E18,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E19 => Electrode::E19,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E20 => Electrode::E20,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E21 => Electrode::E21,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E22 => Electrode::E22,
|
||||||
|
ElectrodeOptionsWithMultiplexer::E23 => Electrode::E23,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use defmt::{info, error};
|
use defmt::error;
|
||||||
|
|
||||||
use embassy_stm32::spi::Error;
|
use embassy_stm32::spi::Error;
|
||||||
use embassy_stm32::exti::ExtiInput;
|
use embassy_stm32::exti::ExtiInput;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ async fn main(spawner: Spawner) {
|
|||||||
// ad5940.init_waveform().await.unwrap();
|
// ad5940.init_waveform().await.unwrap();
|
||||||
let mut impedance_setup = ImpedanceSetup::new(ad5940);
|
let mut impedance_setup = ImpedanceSetup::new(ad5940);
|
||||||
impedance_setup.init().await.unwrap();
|
impedance_setup.init().await.unwrap();
|
||||||
let mut impedance_setup = IMPEDANCE_SETUP.init(Mutex::new(impedance_setup));
|
let impedance_setup = IMPEDANCE_SETUP.init(Mutex::new(impedance_setup));
|
||||||
|
|
||||||
// impedance_setup.lock().await.init_single_frequency_measurement().await;
|
// impedance_setup.lock().await.init_single_frequency_measurement().await;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user