mirror of
https://github.com/hubaldv/bioz-firmware-rs.git
synced 2025-12-06 05:01:18 +00:00
Updated library.
This commit is contained in:
136
src/ad5940.rs
136
src/ad5940.rs
@@ -18,10 +18,6 @@ pub struct SwitchConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SwitchConfig {
|
impl SwitchConfig {
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn t9con(mut self, t9con: T9CON) -> Self {
|
pub fn t9con(mut self, t9con: T9CON) -> Self {
|
||||||
self.t9con = Some(t9con);
|
self.t9con = Some(t9con);
|
||||||
self
|
self
|
||||||
@@ -64,10 +60,6 @@ pub struct DspConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DspConfig {
|
impl DspConfig {
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn adc_mux_n(mut self, muxseln: MUXSELN) -> Self {
|
pub fn adc_mux_n(mut self, muxseln: MUXSELN) -> Self {
|
||||||
self.muxseln = Some(muxseln);
|
self.muxseln = Some(muxseln);
|
||||||
self
|
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 {
|
pub struct Sequencer {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -464,28 +493,23 @@ impl AD5940 {
|
|||||||
let mut current = self.read_reg(Register::SWCON).await?;
|
let mut current = self.read_reg(Register::SWCON).await?;
|
||||||
|
|
||||||
if let Some(t9con) = config.t9con {
|
if let Some(t9con) = config.t9con {
|
||||||
current &= !(0b1 << 17);
|
current = T9CON::apply(current, t9con as u32);
|
||||||
current |= (t9con as u32) << 17;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tmuxcon) = config.tmuxcon {
|
if let Some(tmuxcon) = config.tmuxcon {
|
||||||
current &= !(0b1111 << 12);
|
current = TMUXCON::apply(current, tmuxcon as u32);
|
||||||
current |= (tmuxcon as u32) << 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(nmuxcon) = config.nmuxcon {
|
if let Some(nmuxcon) = config.nmuxcon {
|
||||||
current &= !(0b1111 << 8);
|
current = NMUXCON::apply(current, nmuxcon as u32);
|
||||||
current |= (nmuxcon as u32) << 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pmuxcon) = config.pmuxcon {
|
if let Some(pmuxcon) = config.pmuxcon {
|
||||||
current &= !(0b1111 << 4);
|
current = PMUXCON::apply(current, pmuxcon as u32);
|
||||||
current |= (pmuxcon as u32) << 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dmuxcon) = config.dmuxcon {
|
if let Some(dmuxcon) = config.dmuxcon {
|
||||||
current &= !(0b1111);
|
current = DMUXCON::apply(current, dmuxcon as u32);
|
||||||
current |= dmuxcon as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_reg(Register::SWCON, current).await?;
|
self.write_reg(Register::SWCON, current).await?;
|
||||||
@@ -498,12 +522,10 @@ impl AD5940 {
|
|||||||
let mut current = self.read_reg(Register::ADCCON).await?;
|
let mut current = self.read_reg(Register::ADCCON).await?;
|
||||||
|
|
||||||
if let Some(muxseln) = config.muxseln {
|
if let Some(muxseln) = config.muxseln {
|
||||||
current &= !(0b11111 << 8);
|
current = MUXSELN::apply(current, muxseln as u32);
|
||||||
current |= (muxseln as u32) << 8;
|
|
||||||
}
|
}
|
||||||
if let Some(muxselp) = config.muxselp {
|
if let Some(muxselp) = config.muxselp {
|
||||||
current &= !(0b11111);
|
current = MUXSELP::apply(current, muxselp as u32);
|
||||||
current |= (muxselp as u32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_reg(Register::ADCCON, current).await?;
|
self.write_reg(Register::ADCCON, current).await?;
|
||||||
@@ -512,13 +534,11 @@ impl AD5940 {
|
|||||||
let mut current = self.read_reg(Register::HSRTIACON).await?;
|
let mut current = self.read_reg(Register::HSRTIACON).await?;
|
||||||
|
|
||||||
if let Some(ctiacon) = config.ctiacon {
|
if let Some(ctiacon) = config.ctiacon {
|
||||||
current &= !(0b1111 << 5);
|
current = CTIACON::apply(current, ctiacon as u32);
|
||||||
current |= (ctiacon as u32) << 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rtiacon) = config.rtiacon {
|
if let Some(rtiacon) = config.rtiacon {
|
||||||
current &= !(0b1111);
|
current = RTIACON::apply(current, rtiacon as u32);
|
||||||
current |= rtiacon as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_reg(Register::HSRTIACON, current).await?;
|
self.write_reg(Register::HSRTIACON, current).await?;
|
||||||
@@ -527,18 +547,15 @@ impl AD5940 {
|
|||||||
let mut current = self.read_reg(Register::ADCFILTERCON).await?;
|
let mut current = self.read_reg(Register::ADCFILTERCON).await?;
|
||||||
|
|
||||||
if let Some(sinc3osr) = config.sinc3osr{
|
if let Some(sinc3osr) = config.sinc3osr{
|
||||||
current &= !(0b11 << 12);
|
current = SINC3OSR::apply(current, sinc3osr as u32);
|
||||||
current |= (sinc3osr as u32) << 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sinc2osr) = config.sinc2osr {
|
if let Some(sinc2osr) = config.sinc2osr {
|
||||||
current &= !(0b1111 << 8);
|
current = SINC2OSR::apply(current, sinc2osr as u32);
|
||||||
current |= (sinc2osr as u32) << 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(adcsamplerate) = config.adcsamplerate {
|
if let Some(adcsamplerate) = config.adcsamplerate {
|
||||||
current &= !1;
|
current = ADCSAMPLERATE::apply(current, adcsamplerate as u32);
|
||||||
current |= adcsamplerate as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.write_reg(Register::ADCFILTERCON, current).await?;
|
self.write_reg(Register::ADCFILTERCON, current).await?;
|
||||||
@@ -547,16 +564,13 @@ impl AD5940 {
|
|||||||
let mut current = self.read_reg(Register::DFTCON).await?;
|
let mut current = self.read_reg(Register::DFTCON).await?;
|
||||||
|
|
||||||
if let Some(dftin) = config.dftin {
|
if let Some(dftin) = config.dftin {
|
||||||
current &= !(0b11 << 20);
|
current = DFTINSEL::apply(current, dftin as u32);
|
||||||
current |= (dftin as u32) << 20;
|
|
||||||
}
|
}
|
||||||
if let Some(dftnum) = config.dftnum {
|
if let Some(dftnum) = config.dftnum {
|
||||||
current &= !(0b1111 << 4);
|
current = DFTNUM::apply(current, dftnum as u32);
|
||||||
current |= (dftnum as u32) << 4;
|
|
||||||
}
|
}
|
||||||
if let Some(hanning) = config.hanning {
|
if let Some(hanning) = config.hanning {
|
||||||
current &= !(0b1 << 0);
|
current = HANNING::apply(current, hanning as u32);
|
||||||
current |= (hanning as u32) << 0;
|
|
||||||
}
|
}
|
||||||
self.write_reg(Register::DFTCON, current).await?;
|
self.write_reg(Register::DFTCON, current).await?;
|
||||||
|
|
||||||
@@ -603,30 +617,42 @@ impl AD5940 {
|
|||||||
self.write_reg(Register::WGFCW, sinefcw).await.unwrap();
|
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
|
// Disable sequencer
|
||||||
let mut reg = self.read_reg(Register::SEQCON).await.unwrap();
|
self.write_reg(Register::SEQCON, 0x0000_0002).await?;
|
||||||
reg &= !0x0000_0001; // Clear the enable bits
|
|
||||||
self.write_reg(Register::SEQCON, reg).await.unwrap();
|
|
||||||
|
|
||||||
// Reset SEQCON
|
// Reset SEQCON
|
||||||
self.write_reg(Register::SEQCNT, 0x0000_0001).await.unwrap();
|
self.write_reg(Register::SEQCNT, 0x0000_0001).await?;
|
||||||
|
|
||||||
// Disable fifo
|
// FIFICON
|
||||||
self.write_reg(Register::FIFOCON, 0b010 << 13).await.unwrap();
|
let mut current_fifocon = self.read_reg(Register::FIFOCON).await?;
|
||||||
// self.write_reg(Register::FIFOCON, 0b011 << 13).await.unwrap();
|
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;
|
// CMDDATACON
|
||||||
self.write_reg(Register::CMDDATACON, cmd).await.unwrap();
|
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
|
// Enable FIFO
|
||||||
self.write_reg(Register::FIFOCON, 0b010 << 13 | 1 << 11 ).await.unwrap();
|
current_fifocon |= 0b1 << 11; // Enable FIFO
|
||||||
// self.write_reg(Register::FIFOCON, 0b011 << 13 | 1 << 11 ).await.unwrap();
|
self.write_reg(Register::FIFOCON, current_fifocon).await?;
|
||||||
|
|
||||||
// Enable sequencer
|
// Enable sequencer
|
||||||
let mut reg = self.read_reg(Register::SEQCON).await.unwrap();
|
self.write_reg(Register::SEQCON, 0x0000_0003).await?;
|
||||||
reg |= 0x0000_0001; // Set the enable bit
|
|
||||||
self.write_reg(Register::SEQCON, reg).await.unwrap();
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_chipid(&mut self) -> u16 {
|
pub async fn get_chipid(&mut self) -> u16 {
|
||||||
@@ -682,7 +708,7 @@ impl AD5940 {
|
|||||||
self.write_reg(Register::WGCON, config_wgcon).await?;
|
self.write_reg(Register::WGCON, config_wgcon).await?;
|
||||||
|
|
||||||
// SWCON - set up switch matri
|
// SWCON - set up switch matri
|
||||||
let switch_config = SwitchConfig::new()
|
let switch_config = SwitchConfig::default()
|
||||||
.nmuxcon(NMUXCON::N2Closed)
|
.nmuxcon(NMUXCON::N2Closed)
|
||||||
.pmuxcon(PMUXCON::P11Closed)
|
.pmuxcon(PMUXCON::P11Closed)
|
||||||
.dmuxcon(DMUXCON::D5Closed);
|
.dmuxcon(DMUXCON::D5Closed);
|
||||||
@@ -705,8 +731,6 @@ impl AD5940 {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum Command {
|
enum Command {
|
||||||
SPICMD_SETADDR = 0x20,
|
SPICMD_SETADDR = 0x20,
|
||||||
|
|||||||
@@ -1,9 +1,27 @@
|
|||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub trait Resettable {
|
pub trait RegisterField {
|
||||||
|
/// Reset value for this field
|
||||||
fn reset() -> Self;
|
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)]
|
#[allow(dead_code)]
|
||||||
@@ -12,13 +30,12 @@ pub enum T9CON {
|
|||||||
T9Open = 0,
|
T9Open = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for T9CON {
|
impl RegisterField for T9CON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
T9CON::T9Open
|
T9CON::T9Open
|
||||||
}
|
}
|
||||||
// fn msk() -> u32 {
|
const BIT_OFFSET: u32 = 17;
|
||||||
// 0b1
|
const MASK: u32 = 0b1;
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -35,10 +52,12 @@ pub enum TMUXCON {
|
|||||||
AllClosed = 0b1001,
|
AllClosed = 0b1001,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for TMUXCON {
|
impl RegisterField for TMUXCON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
TMUXCON::AllOpen
|
TMUXCON::AllOpen
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 12;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -57,10 +76,12 @@ pub enum NMUXCON {
|
|||||||
AllOpen = 0b1111,
|
AllOpen = 0b1111,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for NMUXCON {
|
impl RegisterField for NMUXCON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
NMUXCON::AllOpen
|
NMUXCON::AllOpen
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 8;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -79,10 +100,12 @@ pub enum PMUXCON {
|
|||||||
AllOpen = 0b1111,
|
AllOpen = 0b1111,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for PMUXCON {
|
impl RegisterField for PMUXCON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
PMUXCON::AllOpen
|
PMUXCON::AllOpen
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 4;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -99,10 +122,12 @@ pub enum DMUXCON {
|
|||||||
AllClosed = 0b1001
|
AllClosed = 0b1001
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for DMUXCON {
|
impl RegisterField for DMUXCON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
DMUXCON::AllOpen
|
DMUXCON::AllOpen
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 0;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -110,19 +135,37 @@ impl Resettable for DMUXCON {
|
|||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum MUXSELN
|
pub enum MUXSELN
|
||||||
{
|
{
|
||||||
|
Floating = 0b00000,
|
||||||
HsTiaNeg = 0b00001,
|
HsTiaNeg = 0b00001,
|
||||||
LpTiaNeg = 0b00010,
|
LpTiaNeg = 0b00010,
|
||||||
AIN1 = 0b00101,
|
AIN1 = 0b00101,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RegisterField for MUXSELN {
|
||||||
|
fn reset() -> Self {
|
||||||
|
MUXSELN::Floating
|
||||||
|
}
|
||||||
|
const BIT_OFFSET: u32 = 8;
|
||||||
|
const MASK: u32 = 0b11111;
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum MUXSELP {
|
pub enum MUXSELP {
|
||||||
|
Floating = 0b00000,
|
||||||
HsTiaPos = 0b00001,
|
HsTiaPos = 0b00001,
|
||||||
AIN1 = 0b00101,
|
AIN1 = 0b00101,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RegisterField for MUXSELP {
|
||||||
|
fn reset() -> Self {
|
||||||
|
MUXSELP::Floating
|
||||||
|
}
|
||||||
|
const BIT_OFFSET: u32 = 0;
|
||||||
|
const MASK: u32 = 0b11111;
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@@ -132,10 +175,12 @@ pub enum DFTINSEL {
|
|||||||
AdcRaw = 0b10
|
AdcRaw = 0b10
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for DFTINSEL {
|
impl RegisterField for DFTINSEL {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
DFTINSEL::Sinc2
|
DFTINSEL::Sinc2
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 20;
|
||||||
|
const MASK: u32 = 0b11;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -157,10 +202,28 @@ pub enum DFTNUM {
|
|||||||
Num16384 = 0b1100,
|
Num16384 = 0b1100,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for DFTNUM {
|
impl RegisterField for DFTNUM {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
DFTNUM::Num2048
|
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)]
|
#[allow(dead_code)]
|
||||||
@@ -174,10 +237,12 @@ pub enum CTIACON {
|
|||||||
C32 = 1 << 4,
|
C32 = 1 << 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for CTIACON {
|
impl RegisterField for CTIACON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
CTIACON::C1
|
CTIACON::C1
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 5;
|
||||||
|
const MASK: u32 = 0b111_1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -194,10 +259,12 @@ pub enum RTIACON {
|
|||||||
Open = 0b1111,
|
Open = 0b1111,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for RTIACON {
|
impl RegisterField for RTIACON {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
RTIACON::Open
|
RTIACON::Open
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 0;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -208,10 +275,12 @@ pub enum SINC3OSR {
|
|||||||
R2 = 0b10,
|
R2 = 0b10,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for SINC3OSR {
|
impl RegisterField for SINC3OSR {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
SINC3OSR::R5
|
SINC3OSR::R5
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 12;
|
||||||
|
const MASK: u32 = 0b11;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -231,10 +300,12 @@ pub enum SINC2OSR {
|
|||||||
R1333 = 0b1011,
|
R1333 = 0b1011,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for SINC2OSR {
|
impl RegisterField for SINC2OSR {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
SINC2OSR::R178
|
SINC2OSR::R178
|
||||||
}
|
}
|
||||||
|
const BIT_OFFSET: u32 = 8;
|
||||||
|
const MASK: u32 = 0b1111;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -244,10 +315,109 @@ pub enum ADCSAMPLERATE {
|
|||||||
R1_6MHz = 0,
|
R1_6MHz = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resettable for ADCSAMPLERATE {
|
impl RegisterField for ADCSAMPLERATE {
|
||||||
fn reset() -> Self {
|
fn reset() -> Self {
|
||||||
ADCSAMPLERATE::R1_6MHz
|
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! {
|
bitflags! {
|
||||||
|
|||||||
@@ -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 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
|
// Postcard RPC types
|
||||||
type AppDriver = usb::Driver<'static, peripherals::USB>;
|
type AppDriver = usb::Driver<'static, peripherals::USB>;
|
||||||
@@ -37,15 +37,19 @@ static STORAGE: AppStorage = AppStorage::new();
|
|||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub unique_id: [u8; 12],
|
pub unique_id: [u8; 12],
|
||||||
|
pub impedance_setup: &'static ImpedanceSetupType,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SpawnCtx {
|
pub struct SpawnCtx {
|
||||||
|
pub impedance_setup: &'static ImpedanceSetupType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpawnContext for Context {
|
impl SpawnContext for Context {
|
||||||
type SpawnCtxt = SpawnCtx;
|
type SpawnCtxt = SpawnCtx;
|
||||||
fn spawn_ctxt(&mut self) -> Self::SpawnCtxt {
|
fn spawn_ctxt(&mut self) -> Self::SpawnCtxt {
|
||||||
SpawnCtx {}
|
SpawnCtx {
|
||||||
|
impedance_setup: self.impedance_setup,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +68,8 @@ define_dispatch! {
|
|||||||
| 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 |
|
| SetGreenLedEndpoint | async | set_green_led_handler |
|
||||||
| StartImpedanceEndpoint | spawn | start_impedance_handler |
|
| StartImpedanceEndpoint | spawn | start_single_impedance_handler |
|
||||||
| StopImpedanceEndpoint | async | stop_impedance_handler |
|
| StopImpedanceEndpoint | async | stop_single_impedance_handler |
|
||||||
};
|
};
|
||||||
topics_in: {
|
topics_in: {
|
||||||
list: TOPICS_IN_LIST;
|
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
|
// Initialize communication peripherals
|
||||||
let pbufs = PBUFS.take();
|
let pbufs = PBUFS.take();
|
||||||
let config = usb_config();
|
let config = usb_config();
|
||||||
|
|
||||||
let context = Context {
|
let context = Context {
|
||||||
unique_id: *uid::uid(),
|
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());
|
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);
|
static STOP: Mutex<ThreadModeRawMutex, bool> = Mutex::new(false);
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn start_impedance_handler(_context: SpawnCtx, header: VarHeader, rqst: StartImpedance, sender: Sender<AppTx>) {
|
pub async fn start_single_impedance_handler(context: SpawnCtx, header: VarHeader, rqst: StartImpedance, sender: Sender<AppTx>) {
|
||||||
info!("Start impedance measurement with rate {:?} Hz.", rqst.update_frequency);
|
info!("Start impedance measurement at {:?} Hz.", rqst.sinus_frequency);
|
||||||
|
|
||||||
*RUNNING.lock().await = true;
|
*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
|
if sender
|
||||||
.reply::<StartImpedanceEndpoint>(header.seq_no, &())
|
.reply::<StartImpedanceEndpoint>(header.seq_no, &())
|
||||||
.await
|
.await
|
||||||
@@ -193,7 +203,7 @@ pub async fn start_impedance_handler(_context: SpawnCtx, header: VarHeader, rqst
|
|||||||
*STOP.lock().await = false;
|
*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");
|
info!("Stop impedance measurement");
|
||||||
let was_busy = *RUNNING.lock().await;
|
let was_busy = *RUNNING.lock().await;
|
||||||
if was_busy {
|
if was_busy {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ use defmt::{info, error};
|
|||||||
use embassy_stm32::spi::Error;
|
use embassy_stm32::spi::Error;
|
||||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
|
|
||||||
|
use static_cell::StaticCell;
|
||||||
|
|
||||||
use crate::ad5940::*;
|
use crate::ad5940::*;
|
||||||
use crate::ad5940_registers::*;
|
use crate::ad5940_registers::*;
|
||||||
@@ -11,13 +14,17 @@ use bioz_icd_rs::ImpedanceOutput;
|
|||||||
|
|
||||||
pub static IMPEDANCE_CHANNEL: Channel<ThreadModeRawMutex, ImpedanceOutput, 2000> = Channel::new();
|
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 {
|
pub struct ImpedanceSetup {
|
||||||
ad5940: AD5940,
|
ad5940: AD5940,
|
||||||
|
dsp_config: Option<DspConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImpedanceSetup {
|
impl ImpedanceSetup {
|
||||||
pub fn new(ad5940: AD5940) -> Self {
|
pub fn new(ad5940: AD5940) -> Self {
|
||||||
ImpedanceSetup { ad5940 }
|
ImpedanceSetup { ad5940, dsp_config: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init(&mut self) -> Result<(), Error> {
|
pub async fn init(&mut self) -> Result<(), Error> {
|
||||||
@@ -48,10 +55,16 @@ impl ImpedanceSetup {
|
|||||||
.hanning(true);
|
.hanning(true);
|
||||||
|
|
||||||
self.ad5940.apply_dsp_config(&dsp_config).await.unwrap();
|
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();
|
// Set SRAM configuration (cmd and data sram)
|
||||||
info!("Wait time: {:?}", test);
|
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
|
// WGCON: set sinus output
|
||||||
let config_wgcon = WGCON::TYPESEL_SIN.bits();
|
let config_wgcon = WGCON::TYPESEL_SIN.bits();
|
||||||
@@ -60,15 +73,24 @@ impl ImpedanceSetup {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init_measurement(&mut self) {
|
pub async fn init_single_frequency_measurement(&mut self, frequency: u32) {
|
||||||
// Configure GPIOs
|
// Configure GPIOs
|
||||||
self.ad5940.write_reg(Register::GP0CON, 0b10 << 4 | 0b10 << 2 | 0b10).await.unwrap();
|
self.ad5940.write_reg(Register::GP0CON, 0b10 << 4 | 0b10 << 2 | 0b10).await.unwrap();
|
||||||
self.ad5940.write_reg(Register::SYNCEXTDEVICE, 0b111).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
|
// Configure sequencer
|
||||||
self.ad5940.sequencer_enable(true).await;
|
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
|
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();
|
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.afecon(AFECON::WAVEGENEN | AFECON::ADCEN, true).await;
|
||||||
self.ad5940.sequencer_wait(16*10).await; // 10 us
|
self.ad5940.sequencer_wait(16*10).await; // 10 us
|
||||||
self.ad5940.afecon(AFECON::ADCCONVEN | AFECON::DFTEN, true).await;
|
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(wait_time).await; // Determined above
|
||||||
self.ad5940.sequencer_wait(16 * 12_800).await; // 0.75 second // 0,0512
|
self.ad5940.sequencer_wait(16*20).await; // 10 us
|
||||||
self.ad5940.sequencer_wait(16*20).await; // 0.75 second // 0,0512
|
|
||||||
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
|
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
|
||||||
|
|
||||||
// Rz
|
// Rz
|
||||||
@@ -99,9 +120,8 @@ impl ImpedanceSetup {
|
|||||||
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON::ADCEN, true).await;
|
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON::ADCEN, true).await;
|
||||||
self.ad5940.sequencer_wait(16*10).await; // 10 us
|
self.ad5940.sequencer_wait(16*10).await; // 10 us
|
||||||
self.ad5940.afecon(AFECON::ADCCONVEN | AFECON::DFTEN, true).await;
|
self.ad5940.afecon(AFECON::ADCCONVEN | AFECON::DFTEN, true).await;
|
||||||
// self.ad5940.sequencer_wait(16 * 102_400).await; // 0.75 second
|
self.ad5940.sequencer_wait(wait_time).await; // Determined above
|
||||||
self.ad5940.sequencer_wait(16 * 12_800).await; // 0.75 second // 0,0512
|
self.ad5940.sequencer_wait(16*20).await; // 10 us
|
||||||
self.ad5940.sequencer_wait(16*20).await; // 0.75 second // 0,0512
|
|
||||||
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
|
self.ad5940.afecon(AFECON::WAVEGENEN | AFECON:: ADCEN | AFECON::ADCCONVEN | AFECON::DFTEN, false).await;
|
||||||
|
|
||||||
// Toggle leds
|
// Toggle leds
|
||||||
@@ -111,13 +131,13 @@ impl ImpedanceSetup {
|
|||||||
|
|
||||||
self.ad5940.sequencer_enable(false).await;
|
self.ad5940.sequencer_enable(false).await;
|
||||||
|
|
||||||
// // Configure the sequencer cmd data sram
|
// Write sequence to SRAM
|
||||||
self.ad5940.cmddatacon().await;
|
|
||||||
|
|
||||||
let start_address = 0;
|
let start_address = 0;
|
||||||
self.ad5940.sequencer_cmd_write(start_address).await;
|
self.ad5940.sequencer_cmd_write(start_address).await;
|
||||||
|
|
||||||
self.ad5940.sequencer_info_configure(0, self.ad5940.seq_len, 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) {
|
pub async fn start_measurement(&mut self) {
|
||||||
|
|||||||
16
src/main.rs
16
src/main.rs
@@ -4,6 +4,7 @@
|
|||||||
use defmt::info;
|
use defmt::info;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::exti::ExtiInput;
|
use embassy_stm32::exti::ExtiInput;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
use embassy_time::{Timer, Duration};
|
use embassy_time::{Timer, Duration};
|
||||||
use embassy_futures::{select::select, select::Either};
|
use embassy_futures::{select::select, select::Either};
|
||||||
use embassy_stm32::gpio::{Level, Output, Speed};
|
use embassy_stm32::gpio::{Level, Output, Speed};
|
||||||
@@ -37,7 +38,7 @@ use communication::{init_communication, LED_FREQUENCY_SIGNAL};
|
|||||||
use impedance::IMPEDANCE_CHANNEL;
|
use impedance::IMPEDANCE_CHANNEL;
|
||||||
|
|
||||||
mod impedance;
|
mod impedance;
|
||||||
use impedance::ImpedanceSetup;
|
use impedance::{ImpedanceSetup, ImpedanceSetupType, IMPEDANCE_SETUP};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
USB_DRD_FS => usb::InterruptHandler<peripherals::USB>;
|
USB_DRD_FS => usb::InterruptHandler<peripherals::USB>;
|
||||||
@@ -93,7 +94,9 @@ 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();
|
||||||
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
|
// // Set up I2C for ADG2128
|
||||||
// let i2c = i2c::I2c::new_blocking(
|
// let i2c = i2c::I2c::new_blocking(
|
||||||
@@ -117,13 +120,13 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
// Create USB driver and start postcard-rpc server
|
// Create USB driver and start postcard-rpc server
|
||||||
let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
|
let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
|
||||||
init_communication(driver, spawner);
|
init_communication(driver, impedance_setup, spawner);
|
||||||
|
|
||||||
// Green led task
|
// Green led task
|
||||||
// spawner.must_spawn(green_led(led));
|
// spawner.must_spawn(green_led(led));
|
||||||
|
|
||||||
// Trigger the sequencer
|
// Trigger the sequencer
|
||||||
impedance_setup.start_measurement().await;
|
// impedance_setup.start_measurement().await;
|
||||||
|
|
||||||
// Set up interrupt at GPIO for AD5940
|
// Set up interrupt at GPIO for AD5940
|
||||||
let ad5940_gpio_0 = ExtiInput::new(p.PC8, p.EXTI8, embassy_stm32::gpio::Pull::Up);
|
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]
|
#[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 {
|
loop {
|
||||||
// Wait untill sequence is done
|
// Wait untill sequence is done
|
||||||
pin.wait_for_rising_edge().await;
|
pin.wait_for_rising_edge().await;
|
||||||
|
|
||||||
|
// Lock the impedance setup
|
||||||
|
let mut impedance_setup = impedance_setup.lock().await;
|
||||||
|
|
||||||
// Trigger the sequencer again
|
// Trigger the sequencer again
|
||||||
impedance_setup.start_measurement().await;
|
impedance_setup.start_measurement().await;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user