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]
|
||||
git = "https://github.com/quartiq/stm32h7xx-hal.git"
|
||||
branch = "feature/quad-spi"
|
||||
features = ["stm32h743v", "rt"]
|
||||
features = ["stm32h743v", "rt", "unproven"]
|
||||
|
||||
[features]
|
||||
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());
|
||||
|
||||
let mut delay = hal::delay::Delay::new(cp.SYST, clocks.clocks);
|
||||
|
||||
let gpioa = dp.GPIOA.split(&mut clocks.ahb4);
|
||||
let gpiob = dp.GPIOB.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 delay = {
|
||||
let asm_delay = {
|
||||
let frequency_hz = clocks.clocks.c_ck().0;
|
||||
asm_delay::AsmDelay::new(asm_delay::bitrate::Hertz (frequency_hz))
|
||||
};
|
||||
|
@ -299,7 +301,7 @@ const APP: () = {
|
|||
ad9959::Ad9959::new(qspi_interface,
|
||||
&mut reset_pin,
|
||||
io_update,
|
||||
delay,
|
||||
asm_delay,
|
||||
ad9959::Mode::FourBitSerial,
|
||||
100_000_000).unwrap()
|
||||
};
|
||||
|
@ -325,7 +327,30 @@ const APP: () = {
|
|||
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();
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
use super::error::Error;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Channel {
|
||||
One = 0,
|
||||
Two = 1,
|
||||
Three = 2,
|
||||
Four = 3,
|
||||
}
|
||||
use super::DdsChannel;
|
||||
|
||||
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 {
|
||||
return Err(Error::Bounds);
|
||||
}
|
||||
|
@ -31,7 +23,7 @@ pub trait AttenuatorInterface {
|
|||
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];
|
||||
|
||||
// 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 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 write_all(&mut self, channels: &[u8; 4]) -> Result<(), Error>;
|
||||
}
|
||||
|
|
|
@ -6,4 +6,6 @@ pub enum Error {
|
|||
Qspi,
|
||||
Bounds,
|
||||
InvalidAddress,
|
||||
InvalidChannel,
|
||||
Adc,
|
||||
}
|
||||
|
|
|
@ -3,13 +3,20 @@ use ad9959;
|
|||
|
||||
pub mod error;
|
||||
pub mod attenuators;
|
||||
mod rf_power;
|
||||
pub mod types;
|
||||
|
||||
use super::hal;
|
||||
|
||||
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)]
|
||||
const OSC_EN_N_PIN: u8 = 8 + 7;
|
||||
|
@ -62,7 +69,11 @@ pub struct PounderDevices<DELAY> {
|
|||
DELAY,
|
||||
hal::gpio::gpiog::PG7<hal::gpio::Output<hal::gpio::PushPull>>>,
|
||||
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>
|
||||
|
@ -74,11 +85,20 @@ where
|
|||
DELAY,
|
||||
hal::gpio::gpiog::PG7<
|
||||
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 {
|
||||
mcp23017,
|
||||
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
|
||||
|
@ -117,12 +137,12 @@ impl<DELAY> AttenuatorInterface for PounderDevices<DELAY>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn latch(&mut self, channel: Channel) -> Result<(), Error> {
|
||||
fn latch(&mut self, channel: DdsChannel) -> Result<(), Error> {
|
||||
let pin = match channel {
|
||||
Channel::One => ATT_LE0_PIN,
|
||||
Channel::Two => ATT_LE1_PIN,
|
||||
Channel::Three => ATT_LE2_PIN,
|
||||
Channel::Four => ATT_LE3_PIN,
|
||||
DdsChannel::Zero => ATT_LE0_PIN,
|
||||
DdsChannel::One => ATT_LE1_PIN,
|
||||
DdsChannel::Two => ATT_LE2_PIN,
|
||||
DdsChannel::Three => ATT_LE3_PIN,
|
||||
};
|
||||
|
||||
self.mcp23017.digital_write(pin, 1).map_err(|_| Error::I2c)?;
|
||||
|
@ -146,3 +166,21 @@ impl<DELAY> AttenuatorInterface for PounderDevices<DELAY>
|
|||
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