Adding input power measurement support
This commit is contained in:
parent
6f7bb0569c
commit
6792ab5469
|
@ -58,7 +58,7 @@ branch = "feature/device-dependency"
|
||||||
[dependencies.stm32h7xx-hal]
|
[dependencies.stm32h7xx-hal]
|
||||||
git = "https://github.com/quartiq/stm32h7xx-hal.git"
|
git = "https://github.com/quartiq/stm32h7xx-hal.git"
|
||||||
branch = "feature/quad-spi"
|
branch = "feature/quad-spi"
|
||||||
features = ["stm32h743v", "rt"]
|
features = ["stm32h743v", "rt", "unproven"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
||||||
|
|
31
src/main.rs
31
src/main.rs
|
@ -166,6 +166,8 @@ const APP: () = {
|
||||||
|
|
||||||
clocks.rb.d2ccip1r.modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q());
|
clocks.rb.d2ccip1r.modify(|_, w| w.spi123sel().pll2_p().spi45sel().pll2_q());
|
||||||
|
|
||||||
|
let mut delay = hal::delay::Delay::new(cp.SYST, clocks.clocks);
|
||||||
|
|
||||||
let gpioa = dp.GPIOA.split(&mut clocks.ahb4);
|
let gpioa = dp.GPIOA.split(&mut clocks.ahb4);
|
||||||
let gpiob = dp.GPIOB.split(&mut clocks.ahb4);
|
let gpiob = dp.GPIOB.split(&mut clocks.ahb4);
|
||||||
let gpioc = dp.GPIOC.split(&mut clocks.ahb4);
|
let gpioc = dp.GPIOC.split(&mut clocks.ahb4);
|
||||||
|
@ -291,7 +293,7 @@ const APP: () = {
|
||||||
let io_update = gpiog.pg7.into_push_pull_output();
|
let io_update = gpiog.pg7.into_push_pull_output();
|
||||||
|
|
||||||
|
|
||||||
let delay = {
|
let asm_delay = {
|
||||||
let frequency_hz = clocks.clocks.c_ck().0;
|
let frequency_hz = clocks.clocks.c_ck().0;
|
||||||
asm_delay::AsmDelay::new(asm_delay::bitrate::Hertz (frequency_hz))
|
asm_delay::AsmDelay::new(asm_delay::bitrate::Hertz (frequency_hz))
|
||||||
};
|
};
|
||||||
|
@ -299,7 +301,7 @@ const APP: () = {
|
||||||
ad9959::Ad9959::new(qspi_interface,
|
ad9959::Ad9959::new(qspi_interface,
|
||||||
&mut reset_pin,
|
&mut reset_pin,
|
||||||
io_update,
|
io_update,
|
||||||
delay,
|
asm_delay,
|
||||||
ad9959::Mode::FourBitSerial,
|
ad9959::Mode::FourBitSerial,
|
||||||
100_000_000).unwrap()
|
100_000_000).unwrap()
|
||||||
};
|
};
|
||||||
|
@ -325,7 +327,30 @@ const APP: () = {
|
||||||
dp.SPI1.spi((spi_sck, spi_miso, spi_mosi), config, 25.mhz(), &clocks)
|
dp.SPI1.spi((spi_sck, spi_miso, spi_mosi), config, 25.mhz(), &clocks)
|
||||||
};
|
};
|
||||||
|
|
||||||
pounder::PounderDevices::new(io_expander, ad9959, spi).unwrap()
|
let adc1 = {
|
||||||
|
let mut adc = dp.ADC1.adc(&mut delay, &mut clocks);
|
||||||
|
adc.calibrate();
|
||||||
|
|
||||||
|
adc.enable()
|
||||||
|
};
|
||||||
|
|
||||||
|
let adc2 = {
|
||||||
|
let mut adc = dp.ADC2.adc(&mut delay, &mut clocks);
|
||||||
|
adc.calibrate();
|
||||||
|
|
||||||
|
adc.enable()
|
||||||
|
};
|
||||||
|
|
||||||
|
let adc1_in_p = gpiof.pf11.into_analog();
|
||||||
|
let adc2_in_p = gpiof.pf14.into_analog();
|
||||||
|
|
||||||
|
pounder::PounderDevices::new(io_expander,
|
||||||
|
ad9959,
|
||||||
|
spi,
|
||||||
|
adc1,
|
||||||
|
adc2,
|
||||||
|
adc1_in_p,
|
||||||
|
adc2_in_p).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut fp_led_0 = gpiod.pd5.into_push_pull_output();
|
let mut fp_led_0 = gpiod.pd5.into_push_pull_output();
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
use super::DdsChannel;
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Channel {
|
|
||||||
One = 0,
|
|
||||||
Two = 1,
|
|
||||||
Three = 2,
|
|
||||||
Four = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AttenuatorInterface {
|
pub trait AttenuatorInterface {
|
||||||
fn modify(&mut self, attenuation: f32, channel: Channel) -> Result<f32, Error> {
|
fn modify(&mut self, attenuation: f32, channel: DdsChannel) -> Result<f32, Error> {
|
||||||
if attenuation > 31.5 {
|
if attenuation > 31.5 {
|
||||||
return Err(Error::Bounds);
|
return Err(Error::Bounds);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +23,7 @@ pub trait AttenuatorInterface {
|
||||||
Ok(attenuation_code as f32 / 2.0)
|
Ok(attenuation_code as f32 / 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&mut self, channel: Channel) -> Result<f32, Error> {
|
fn read(&mut self, channel: DdsChannel) -> Result<f32, Error> {
|
||||||
let mut channels = [0_u8; 4];
|
let mut channels = [0_u8; 4];
|
||||||
|
|
||||||
// Reading the data always shifts data out of the staging registers, so we perform a
|
// Reading the data always shifts data out of the staging registers, so we perform a
|
||||||
|
@ -48,7 +40,7 @@ pub trait AttenuatorInterface {
|
||||||
|
|
||||||
fn reset(&mut self) -> Result<(), Error>;
|
fn reset(&mut self) -> Result<(), Error>;
|
||||||
|
|
||||||
fn latch(&mut self, channel: Channel) -> Result<(), Error>;
|
fn latch(&mut self, channel: DdsChannel) -> Result<(), Error>;
|
||||||
fn read_all(&mut self, channels: &mut [u8; 4]) -> Result<(), Error>;
|
fn read_all(&mut self, channels: &mut [u8; 4]) -> Result<(), Error>;
|
||||||
fn write_all(&mut self, channels: &[u8; 4]) -> Result<(), Error>;
|
fn write_all(&mut self, channels: &[u8; 4]) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,6 @@ pub enum Error {
|
||||||
Qspi,
|
Qspi,
|
||||||
Bounds,
|
Bounds,
|
||||||
InvalidAddress,
|
InvalidAddress,
|
||||||
|
InvalidChannel,
|
||||||
|
Adc,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,20 @@ use ad9959;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod attenuators;
|
pub mod attenuators;
|
||||||
|
mod rf_power;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
use super::hal;
|
use super::hal;
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use attenuators::{AttenuatorInterface, Channel};
|
use attenuators::AttenuatorInterface;
|
||||||
|
use types::{DdsChannel, InputChannel};
|
||||||
|
use rf_power::PowerMeasurementInterface;
|
||||||
|
|
||||||
use embedded_hal::blocking::spi::Transfer;
|
use embedded_hal::{
|
||||||
|
blocking::spi::Transfer,
|
||||||
|
adc::OneShot
|
||||||
|
};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const OSC_EN_N_PIN: u8 = 8 + 7;
|
const OSC_EN_N_PIN: u8 = 8 + 7;
|
||||||
|
@ -62,7 +69,11 @@ pub struct PounderDevices<DELAY> {
|
||||||
DELAY,
|
DELAY,
|
||||||
hal::gpio::gpiog::PG7<hal::gpio::Output<hal::gpio::PushPull>>>,
|
hal::gpio::gpiog::PG7<hal::gpio::Output<hal::gpio::PushPull>>>,
|
||||||
mcp23017: mcp23017::MCP23017<hal::i2c::I2c<hal::stm32::I2C1>>,
|
mcp23017: mcp23017::MCP23017<hal::i2c::I2c<hal::stm32::I2C1>>,
|
||||||
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>
|
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>,
|
||||||
|
adc1: hal::adc::Adc<hal::stm32::ADC1, hal::adc::Enabled>,
|
||||||
|
adc2: hal::adc::Adc<hal::stm32::ADC2, hal::adc::Enabled>,
|
||||||
|
adc1_in_p: hal::gpio::gpiof::PF11<hal::gpio::Analog>,
|
||||||
|
adc2_in_p: hal::gpio::gpiof::PF14<hal::gpio::Analog>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DELAY> PounderDevices<DELAY>
|
impl<DELAY> PounderDevices<DELAY>
|
||||||
|
@ -74,11 +85,20 @@ where
|
||||||
DELAY,
|
DELAY,
|
||||||
hal::gpio::gpiog::PG7<
|
hal::gpio::gpiog::PG7<
|
||||||
hal::gpio::Output<hal::gpio::PushPull>>>,
|
hal::gpio::Output<hal::gpio::PushPull>>>,
|
||||||
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>) -> Result<Self, Error> {
|
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1>,
|
||||||
|
adc1: hal::adc::Adc<hal::stm32::ADC1, hal::adc::Enabled>,
|
||||||
|
adc2: hal::adc::Adc<hal::stm32::ADC2, hal::adc::Enabled>,
|
||||||
|
adc1_in_p: hal::gpio::gpiof::PF11<hal::gpio::Analog>,
|
||||||
|
adc2_in_p: hal::gpio::gpiof::PF14<hal::gpio::Analog>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let mut devices = Self {
|
let mut devices = Self {
|
||||||
mcp23017,
|
mcp23017,
|
||||||
ad9959,
|
ad9959,
|
||||||
attenuator_spi
|
attenuator_spi,
|
||||||
|
adc1,
|
||||||
|
adc2,
|
||||||
|
adc1_in_p,
|
||||||
|
adc2_in_p,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Configure power-on-default state for pounder. All LEDs are on, on-board oscillator
|
// Configure power-on-default state for pounder. All LEDs are on, on-board oscillator
|
||||||
|
@ -117,12 +137,12 @@ impl<DELAY> AttenuatorInterface for PounderDevices<DELAY>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn latch(&mut self, channel: Channel) -> Result<(), Error> {
|
fn latch(&mut self, channel: DdsChannel) -> Result<(), Error> {
|
||||||
let pin = match channel {
|
let pin = match channel {
|
||||||
Channel::One => ATT_LE0_PIN,
|
DdsChannel::Zero => ATT_LE0_PIN,
|
||||||
Channel::Two => ATT_LE1_PIN,
|
DdsChannel::One => ATT_LE1_PIN,
|
||||||
Channel::Three => ATT_LE2_PIN,
|
DdsChannel::Two => ATT_LE2_PIN,
|
||||||
Channel::Four => ATT_LE3_PIN,
|
DdsChannel::Three => ATT_LE3_PIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.mcp23017.digital_write(pin, 1).map_err(|_| Error::I2c)?;
|
self.mcp23017.digital_write(pin, 1).map_err(|_| Error::I2c)?;
|
||||||
|
@ -146,3 +166,21 @@ impl<DELAY> AttenuatorInterface for PounderDevices<DELAY>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<DELAY> PowerMeasurementInterface for PounderDevices<DELAY> {
|
||||||
|
fn sample_converter(&mut self, channel: InputChannel) -> Result<f32, Error> {
|
||||||
|
let adc_scale = match channel {
|
||||||
|
InputChannel::Zero => {
|
||||||
|
let adc_reading: u32 = self.adc1.read(&mut self.adc1_in_p).map_err(|_| Error::Adc)?;
|
||||||
|
adc_reading as f32 / self.adc1.max_sample() as f32
|
||||||
|
},
|
||||||
|
InputChannel::One => {
|
||||||
|
let adc_reading: u32 = self.adc2.read(&mut self.adc2_in_p).map_err(|_| Error::Adc)?;
|
||||||
|
adc_reading as f32 / self.adc2.max_sample() as f32
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert analog percentage to voltage.
|
||||||
|
Ok(adc_scale * 3.3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
use super::Error;
|
||||||
|
use super::InputChannel;
|
||||||
|
|
||||||
|
pub trait PowerMeasurementInterface {
|
||||||
|
fn sample_converter(&mut self, channel: InputChannel) -> Result<f32, Error>;
|
||||||
|
|
||||||
|
fn measure_power(&mut self, channel: InputChannel) -> Result<f32, Error> {
|
||||||
|
let analog_measurement = self.sample_converter(channel)?;
|
||||||
|
|
||||||
|
// The AD8363 with VSET connected to VOUT provides an output voltage of 52mV / dB.
|
||||||
|
Ok(analog_measurement / 0.052)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum DdsChannel {
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum InputChannel {
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
}
|
Loading…
Reference in New Issue