Adding input power measurement support

This commit is contained in:
Ryan Summers 2020-04-29 13:00:29 +02:00
parent 6f7bb0569c
commit 6792ab5469
7 changed files with 112 additions and 26 deletions

View File

@ -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"]

View File

@ -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();

View File

@ -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>;
}

View File

@ -6,4 +6,6 @@ pub enum Error {
Qspi,
Bounds,
InvalidAddress,
InvalidChannel,
Adc,
}

View File

@ -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)
}
}

13
src/pounder/rf_power.rs Normal file
View File

@ -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)
}
}

16
src/pounder/types.rs Normal file
View File

@ -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,
}