Fixing pounder timestamps after manual testing
This commit is contained in:
parent
72d14adfbf
commit
352884ea06
|
@ -172,6 +172,17 @@ impl<I: Interface> Ad9959<I> {
|
|||
|
||||
// Set the clock frequency to configure the device as necessary.
|
||||
ad9959.configure_system_clock(clock_frequency, multiplier)?;
|
||||
|
||||
// Latch the new clock configuration.
|
||||
io_update.set_high().or(Err(Error::Pin))?;
|
||||
|
||||
// Delay for at least 1 SYNC_CLK period for the update to occur. The SYNC_CLK is guaranteed
|
||||
// to be at least 250KHz (1/4 of 1MHz minimum REF_CLK). We use 5uS instead of 4uS to
|
||||
// guarantee conformance with datasheet requirements.
|
||||
delay.delay_us(5);
|
||||
|
||||
io_update.set_low().or(Err(Error::Pin))?;
|
||||
|
||||
Ok(ad9959)
|
||||
}
|
||||
|
||||
|
@ -195,7 +206,7 @@ impl<I: Interface> Ad9959<I> {
|
|||
///
|
||||
/// Returns:
|
||||
/// The actual frequency configured for the internal system clock.
|
||||
pub fn configure_system_clock(
|
||||
fn configure_system_clock(
|
||||
&mut self,
|
||||
reference_clock_frequency: f32,
|
||||
multiplier: u8,
|
||||
|
|
|
@ -7,3 +7,12 @@ pub const ADC_DAC_SCK_MHZ_MAX: u32 = 50;
|
|||
|
||||
/// The optimal counting frequency of the hardware timers used for timestamping and sampling.
|
||||
pub const TIMER_FREQUENCY_MHZ: u32 = 100;
|
||||
|
||||
/// The DDS reference clock frequency in MHz.
|
||||
pub const DDS_REF_CLK_MHZ: u32 = 100;
|
||||
|
||||
/// The multiplier used for the DDS reference clock PLL.
|
||||
pub const DDS_MULTIPLIER: u8 = 5;
|
||||
|
||||
/// The rate of the DDS SYNC_CLK in MHz is always 1/4 that of the internal PLL clock.
|
||||
pub const DDS_SYNC_CLK_MHZ: u32 = DDS_REF_CLK_MHZ * DDS_MULTIPLIER as u32 / 4;
|
||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -527,7 +527,7 @@ const APP: () = {
|
|||
delay.delay_ms(2u8);
|
||||
let (pounder_devices, dds_output) = if pounder_pgood.is_high().unwrap()
|
||||
{
|
||||
let mut ad9959 = {
|
||||
let ad9959 = {
|
||||
let qspi_interface = {
|
||||
// Instantiate the QUADSPI pins and peripheral interface.
|
||||
let qspi_pins = {
|
||||
|
@ -580,8 +580,8 @@ const APP: () = {
|
|||
&mut io_update,
|
||||
&mut delay,
|
||||
ad9959::Mode::FourBitSerial,
|
||||
100_000_000_f32,
|
||||
5,
|
||||
design_parameters::DDS_REF_CLK_MHZ as f32 * 1_000_000_f32,
|
||||
design_parameters::DDS_MULTIPLIER,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -660,7 +660,6 @@ const APP: () = {
|
|||
|
||||
let pounder_devices = pounder::PounderDevices::new(
|
||||
io_expander,
|
||||
&mut ad9959,
|
||||
spi,
|
||||
adc1,
|
||||
adc2,
|
||||
|
@ -686,8 +685,8 @@ const APP: () = {
|
|||
);
|
||||
|
||||
// IO_Update should be latched for 4 SYNC_CLK cycles after the QSPI profile
|
||||
// write. With pounder SYNC_CLK running at 100MHz (1/4 of the pounder reference
|
||||
// clock of 400MHz), this corresponds to 40ns. To accomodate rounding errors, we
|
||||
// write. With pounder SYNC_CLK running at 125MHz (1/4 of the pounder reference
|
||||
// clock of 500MHz), this corresponds to 32ns. To accomodate rounding errors, we
|
||||
// use 50ns instead.
|
||||
//
|
||||
// Profile writes are always 16 bytes, with 2 cycles required per byte, coming
|
||||
|
@ -859,8 +858,21 @@ const APP: () = {
|
|||
let tim8 =
|
||||
dp.TIM8.timer(1.khz(), ccdr.peripheral.TIM8, &ccdr.clocks);
|
||||
let mut timestamp_timer = timers::PounderTimestampTimer::new(tim8);
|
||||
|
||||
// Pounder is configured to generate a 400MHz reference clock, so a 125MHz sync-clock is
|
||||
// output. As a result, dividing the 125MHz sync-clk provides a 31.25MHz tick rate for
|
||||
// the timestamp timer. 31.25MHz corresponds with a 32ns tick rate.
|
||||
timestamp_timer.set_external_clock(timers::Prescaler::Div4);
|
||||
timestamp_timer.set_period(128);
|
||||
timestamp_timer.start();
|
||||
|
||||
// We want the pounder timestamp timer to overflow once per batch.
|
||||
let tick_ratio = design_parameters::DDS_SYNC_CLK_MHZ as f32
|
||||
/ design_parameters::TIMER_FREQUENCY_MHZ as f32;
|
||||
let period = (tick_ratio
|
||||
* ADC_SAMPLE_TICKS as f32
|
||||
* SAMPLE_BUFFER_SIZE as f32) as u32
|
||||
/ 4;
|
||||
timestamp_timer.set_period((period - 1).try_into().unwrap());
|
||||
let tim8_channels = timestamp_timer.channels();
|
||||
|
||||
pounder::timestamp::Timestamper::new(
|
||||
|
|
|
@ -275,7 +275,6 @@ impl PounderDevices {
|
|||
/// Construct and initialize pounder-specific hardware.
|
||||
///
|
||||
/// Args:
|
||||
/// * `ad9959` - The DDS driver for the pounder hardware.
|
||||
/// * `attenuator_spi` - A SPI interface to control digital attenuators.
|
||||
/// * `adc1` - The ADC1 peripheral for measuring power.
|
||||
/// * `adc2` - The ADC2 peripheral for measuring power.
|
||||
|
@ -283,7 +282,6 @@ impl PounderDevices {
|
|||
/// * `adc2_in_p` - The input channel for the RF power measurement on IN1.
|
||||
pub fn new(
|
||||
mcp23017: mcp23017::MCP23017<hal::i2c::I2c<hal::stm32::I2C1>>,
|
||||
ad9959: &mut ad9959::Ad9959<QspiInterface>,
|
||||
attenuator_spi: hal::spi::Spi<hal::stm32::SPI1, hal::spi::Enabled, u8>,
|
||||
adc1: hal::adc::Adc<hal::stm32::ADC1, hal::adc::Enabled>,
|
||||
adc2: hal::adc::Adc<hal::stm32::ADC2, hal::adc::Enabled>,
|
||||
|
@ -315,14 +313,10 @@ impl PounderDevices {
|
|||
.write_gpio(mcp23017::Port::GPIOB, 1 << 5)
|
||||
.map_err(|_| Error::I2c)?;
|
||||
|
||||
// Select the on-board clock with a 4x prescaler (400MHz).
|
||||
devices
|
||||
.mcp23017
|
||||
.digital_write(EXT_CLK_SEL_PIN, false)
|
||||
.map_err(|_| Error::I2c)?;
|
||||
ad9959
|
||||
.configure_system_clock(100_000_000f32, 4)
|
||||
.map_err(|_| Error::Dds)?;
|
||||
|
||||
Ok(devices)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ pub enum TriggerSource {
|
|||
}
|
||||
|
||||
pub enum Prescaler {
|
||||
Div1 = 0b00,
|
||||
Div2 = 0b01,
|
||||
Div4 = 0b10,
|
||||
Div8 = 0b11,
|
||||
}
|
||||
|
@ -100,17 +102,17 @@ macro_rules! timer_channels {
|
|||
let regs = unsafe { &*hal::stm32::$TY::ptr() };
|
||||
regs.smcr.modify(|_, w| w.etps().bits(prescaler as u8).ece().set_bit());
|
||||
|
||||
// Use a DIV4 prescaler.
|
||||
|
||||
// Clear any other prescaler configuration.
|
||||
regs.psc.write(|w| w.psc().bits(0));
|
||||
}
|
||||
|
||||
/// Start the timer.
|
||||
#[allow(dead_code)]
|
||||
pub fn start(mut self) {
|
||||
pub fn start(&mut self) {
|
||||
// Force a refresh of the frequency settings.
|
||||
self.timer.apply_freq();
|
||||
|
||||
self.timer.reset_counter();
|
||||
|
||||
self.timer.resume();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue