Adding WIP QSPI streaming
This commit is contained in:
parent
66c917b576
commit
db182b923d
@ -59,9 +59,8 @@ features = ["stm32h743v"]
|
||||
|
||||
[dependencies.stm32h7xx-hal]
|
||||
features = ["stm32h743v", "rt", "unproven"]
|
||||
|
||||
[patch.crates-io]
|
||||
stm32h7xx-hal = { git = "https://github.com/quartiq/stm32h7xx-hal.git", branch = "feature/pounder-support" }
|
||||
git = "https://github.com/quartiq/stm32h7xx-hal.git"
|
||||
branch = "feature/pounder-support"
|
||||
|
||||
[features]
|
||||
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]
|
||||
|
@ -376,9 +376,6 @@ where
|
||||
// Latch the configuration and restore the previous CSR. Note that the re-enable of the
|
||||
// channel happens immediately, so the CSR update does not need to be latched.
|
||||
self.latch_configuration()?;
|
||||
self.interface
|
||||
.write(Register::CSR as u8, &csr)
|
||||
.map_err(|_| Error::Interface)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -571,4 +568,69 @@ where
|
||||
Ok(tuning_word as f64 * self.system_clock_frequency()
|
||||
/ (1u64 << 32) as f64)
|
||||
}
|
||||
|
||||
pub fn write_profile(&mut self, channel: Channel, freq: f64, turns: f32, amplitude: f32) -> Result<(), Error> {
|
||||
// The function for channel frequency is `f_out = FTW * f_s / 2^32`, where FTW is the
|
||||
// frequency tuning word and f_s is the system clock rate.
|
||||
let tuning_word: u32 =
|
||||
((freq as f64 / self.system_clock_frequency())
|
||||
* 1u64.wrapping_shl(32) as f64) as u32;
|
||||
|
||||
let phase_offset: u16 = (turns * (1 << 14) as f32) as u16 & 0x3FFFu16;
|
||||
|
||||
let amplitude_control: u16 = (amplitude * (1 << 10) as f32) as u16;
|
||||
let mut acr: [u8; 3] = [0; 3];
|
||||
|
||||
// Enable the amplitude multiplier for the channel if required. The amplitude control has
|
||||
// full-scale at 0x3FF (amplitude of 1), so the multiplier should be disabled whenever
|
||||
// full-scale is used.
|
||||
if amplitude_control < (1 << 10) {
|
||||
let masked_control = amplitude_control & 0x3FF;
|
||||
acr[1] = masked_control.to_be_bytes()[0];
|
||||
acr[2] = masked_control.to_be_bytes()[1];
|
||||
|
||||
// Enable the amplitude multiplier
|
||||
acr[1].set_bit(4, true);
|
||||
}
|
||||
|
||||
self.modify_channel_closure(channel, |interface| {
|
||||
let mut data: [u8; 11] = [0; 11];
|
||||
data[0..2].copy_from_slice(&phase_offset.to_be_bytes());
|
||||
data[2] = Register::CFTW0 as u8;
|
||||
data[3..7].copy_from_slice(&tuning_word.to_be_bytes());
|
||||
data[7] = Register::ACR as u8;
|
||||
data[8..11].copy_from_slice(&acr);
|
||||
interface.write(Register::CPOW0 as u8, &data).map_err(|_| Error::Interface)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn modify_channel_closure<F>(&mut self, channel: Channel, f: F) -> Result<(), Error>
|
||||
where
|
||||
F: FnOnce(&mut INTERFACE) -> Result<(), Error>,
|
||||
{
|
||||
// Disable all other outputs so that we can update the configuration register of only the
|
||||
// specified channel.
|
||||
let mut csr: [u8; 1] = [0];
|
||||
self.interface
|
||||
.read(Register::CSR as u8, &mut csr)
|
||||
.map_err(|_| Error::Interface)?;
|
||||
|
||||
let mut new_csr = csr;
|
||||
new_csr[0].set_bits(4..8, 0);
|
||||
new_csr[0].set_bit(4 + channel as usize, true);
|
||||
|
||||
self.interface
|
||||
.write(Register::CSR as u8, &new_csr)
|
||||
.map_err(|_| Error::Interface)?;
|
||||
|
||||
let result = f(&mut self.interface);
|
||||
|
||||
// Latch the configuration and restore the previous CSR. Note that the re-enable of the
|
||||
// channel happens immediately, so the CSR update does not need to be latched.
|
||||
self.latch_configuration()?;
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
@ -91,11 +91,11 @@ def main():
|
||||
|
||||
# A sample configuration for an output channel.
|
||||
channel_config = {
|
||||
'attenuation': 31.5,
|
||||
'attenuation': 0.0,
|
||||
'parameters': {
|
||||
'phase_offset': 0.5,
|
||||
'frequency': 100.0e6,
|
||||
'amplitude': 0.2,
|
||||
'amplitude': 1.0,
|
||||
'enabled': True,
|
||||
}
|
||||
}
|
||||
|
34
src/main.rs
34
src/main.rs
@ -187,8 +187,7 @@ const APP: () = {
|
||||
'static,
|
||||
'static,
|
||||
'static,
|
||||
ethernet::EthernetDMA<'static>,
|
||||
>,
|
||||
ethernet::EthernetDMA<'static>>,
|
||||
eth_mac: ethernet::EthernetMAC,
|
||||
mac_addr: net::wire::EthernetAddress,
|
||||
|
||||
@ -654,7 +653,7 @@ const APP: () = {
|
||||
);
|
||||
|
||||
// Configure timer 2 to trigger conversions for the ADC
|
||||
let mut timer2 = dp.TIM2.timer(500.khz(), &mut clocks);
|
||||
let mut timer2 = dp.TIM2.timer(50.khz(), &mut clocks);
|
||||
timer2.configure_channel(hal::timer::Channel::One, 0.25);
|
||||
timer2.configure_channel(hal::timer::Channel::Two, 0.75);
|
||||
|
||||
@ -746,6 +745,35 @@ const APP: () = {
|
||||
// TODO: Replace with reference to CPU clock from CCDR.
|
||||
next_ms += 400_000.cycles();
|
||||
|
||||
match c.resources.pounder {
|
||||
Some(pounder) => {
|
||||
|
||||
let state = pounder::ChannelState {
|
||||
parameters: pounder::DdsChannelState {
|
||||
phase_offset: 0.0,
|
||||
frequency: 100_000_000.0,
|
||||
amplitude: 1.0,
|
||||
enabled: true,
|
||||
},
|
||||
attenuation: 10.0,
|
||||
};
|
||||
|
||||
let state1 = pounder::ChannelState {
|
||||
parameters: pounder::DdsChannelState {
|
||||
phase_offset: 0.5,
|
||||
frequency: 50_000_000.0,
|
||||
amplitude: 1.0,
|
||||
enabled: true,
|
||||
},
|
||||
attenuation: 10.0,
|
||||
};
|
||||
|
||||
pounder.set_channel_state(pounder::Channel::Out0, state).unwrap();
|
||||
pounder.set_channel_state(pounder::Channel::Out1, state1).unwrap();
|
||||
},
|
||||
_ => panic!("Failed"),
|
||||
}
|
||||
|
||||
loop {
|
||||
let tick = Instant::now() > next_ms;
|
||||
|
||||
|
@ -474,15 +474,8 @@ where
|
||||
channel: Channel,
|
||||
state: ChannelState,
|
||||
) -> Result<(), Error> {
|
||||
self.ad9959
|
||||
.set_frequency(channel.into(), state.parameters.frequency)
|
||||
.map_err(|_| Error::Dds)?;
|
||||
self.ad9959
|
||||
.set_phase(channel.into(), state.parameters.phase_offset)
|
||||
.map_err(|_| Error::Dds)?;
|
||||
self.ad9959
|
||||
.set_amplitude(channel.into(), state.parameters.amplitude)
|
||||
.map_err(|_| Error::Dds)?;
|
||||
self.ad9959.write_profile(channel.into(), state.parameters.frequency,
|
||||
state.parameters.phase_offset, state.parameters.amplitude).map_err(|_| Error::Dds)?;
|
||||
|
||||
if state.parameters.enabled {
|
||||
self.ad9959
|
||||
|
Loading…
Reference in New Issue
Block a user