Added basic tuning via encoder
This commit is contained in:
parent
4878a1a771
commit
35ad5dcb9f
57
src/main.rs
57
src/main.rs
|
@ -69,8 +69,8 @@ mod app {
|
|||
board_led: gpioc::PC13<Output<PushPull>>,
|
||||
rx_en: gpioa::PA7<Output<PushPull>>,
|
||||
//mic_in: gpio::Pin<'A', 4, Analog>,
|
||||
i_in: gpio::Pin<'A', 1, Analog>,
|
||||
q_in: gpio::Pin<'A', 0, Analog>,
|
||||
i_in: gpio::Pin<'A', 2, Analog>,
|
||||
q_in: gpio::Pin<'A', 3, Analog>,
|
||||
i_offset: f32,
|
||||
q_offset: f32,
|
||||
audio_pwm: AudioPwm,
|
||||
|
@ -93,6 +93,10 @@ mod app {
|
|||
disp: ST7735<Spi<SPI1>, gpio::Pin<'A', 12, Output>, gpio::Pin<'A', 11, Output>>,
|
||||
col_pos: u16,
|
||||
max_mag: f32,
|
||||
|
||||
encoder: qei::Qei<TIM2>,
|
||||
last_encoder_pos: u32,
|
||||
carrier_freq: u32,
|
||||
}
|
||||
|
||||
#[shared]
|
||||
|
@ -125,14 +129,12 @@ mod app {
|
|||
|
||||
let board_led = gpioc.pc13.into_push_pull_output();
|
||||
|
||||
/*
|
||||
let enc_a = gpioa.pa5.into_input();
|
||||
let enc_b = gpiob.pb3.into_input();
|
||||
let enc_a = gpioa.pa0.into_input();
|
||||
let enc_b = gpioa.pa1.into_input();
|
||||
|
||||
let encoder = qei::Qei::new(cx.device.TIM2, (enc_a, enc_b));
|
||||
|
||||
defmt::info!("Encoder Setup done");
|
||||
*/
|
||||
|
||||
let scl = gpiob.pb6.into_alternate_open_drain();
|
||||
let sda = gpiob.pb7.into_alternate_open_drain();
|
||||
|
@ -152,8 +154,8 @@ mod app {
|
|||
let freq = 7_100_000;
|
||||
*/
|
||||
|
||||
let phase = 36;
|
||||
let freq = 14_125_000;
|
||||
let phase = 100;
|
||||
let freq = 7_100_000;
|
||||
|
||||
pll.init(&mut i2c, 25_000_000, freq * phase, freq * phase);
|
||||
pll.set_ms_source(&mut i2c, si5153::Multisynth::MS0, si5153::PLL::A);
|
||||
|
@ -201,8 +203,8 @@ mod app {
|
|||
|
||||
defmt::info!("Display setup done");
|
||||
|
||||
let i_in = gpioa.pa1.into_analog();
|
||||
let q_in = gpioa.pa0.into_analog();
|
||||
let i_in = gpioa.pa2.into_analog();
|
||||
let q_in = gpioa.pa3.into_analog();
|
||||
|
||||
let adc_config = AdcConfig::default()
|
||||
.dma(Dma::Continuous)
|
||||
|
@ -307,11 +309,15 @@ mod app {
|
|||
disp,
|
||||
col_pos: 0,
|
||||
max_mag: 0.0,
|
||||
|
||||
encoder,
|
||||
last_encoder_pos: 0,
|
||||
carrier_freq: 7_100_000,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[task(priority = 0, local = [disp, col_pos, max_mag])]
|
||||
#[task(priority = 0, local = [disp, col_pos, max_mag, encoder, last_encoder_pos, carrier_freq, pll, i2c])]
|
||||
async fn update_display(cx: update_display::Context, col: [Complex<f32>; 128]) {
|
||||
for samp in col {
|
||||
let mag = (samp.re.pow(2) as f32 + samp.im.pow(2) as f32).sqrt() as f32;
|
||||
|
@ -341,6 +347,29 @@ mod app {
|
|||
*cx.local.max_mag *= 0.999;
|
||||
|
||||
defmt::info!("Position is {}", cx.local.col_pos);
|
||||
|
||||
let encoder_pos = cx.local.encoder.count();
|
||||
let diff = encoder_pos.wrapping_sub(*cx.local.last_encoder_pos) as i32;
|
||||
|
||||
if diff != 0 {
|
||||
*cx.local.carrier_freq = (*cx.local.carrier_freq as i32 + diff * 100 / 4) as u32;
|
||||
cx.local
|
||||
.pll
|
||||
.set_pll_freq(cx.local.i2c, si5153::PLL::A, *cx.local.carrier_freq * 100);
|
||||
cx.local.pll.set_ms_freq(
|
||||
cx.local.i2c,
|
||||
si5153::Multisynth::MS0,
|
||||
*cx.local.carrier_freq,
|
||||
);
|
||||
cx.local.pll.set_ms_freq(
|
||||
cx.local.i2c,
|
||||
si5153::Multisynth::MS1,
|
||||
*cx.local.carrier_freq,
|
||||
);
|
||||
}
|
||||
defmt::info!("Carrier freq is {}", cx.local.carrier_freq);
|
||||
|
||||
*cx.local.last_encoder_pos = encoder_pos;
|
||||
}
|
||||
|
||||
#[task(binds = DMA2_STREAM0, local = [adc_transfer, iq_buffer, board_led, i_offset, q_offset, usb_filter, audio_max_duty], shared = [audio_buffer])]
|
||||
|
@ -365,7 +394,7 @@ mod app {
|
|||
let i_sample = (i_raw as f32) - *cx.local.i_offset;
|
||||
let q_sample = (q_raw as f32) - *cx.local.q_offset;
|
||||
|
||||
samples[idx] = Complex::new(q_sample as f32 / 4096.0, i_sample as f32 / 4096.0);
|
||||
samples[idx] = Complex::new(q_sample as f32 / 4096.0, i_sample as f32 / 4096.0) * 5.0;
|
||||
}
|
||||
|
||||
let mut fft_input = [Complex::<f32>::default(); 128];
|
||||
|
@ -376,8 +405,8 @@ mod app {
|
|||
cx.shared.audio_buffer.lock(|buffer| {
|
||||
let audio_buffer = buffer.take().unwrap();
|
||||
for idx in 0..samples.len() {
|
||||
//let filtered = usb_filter.compute(samples[idx]);
|
||||
let filtered = usb_filter.compute(Complex::new(samples[idx].im, samples[idx].re));
|
||||
let filtered = usb_filter.compute(samples[idx]);
|
||||
//let filtered = usb_filter.compute(Complex::new(samples[idx].im, samples[idx].re));
|
||||
fft_input[idx] = samples[idx];
|
||||
|
||||
audio_buffer[idx] = ((filtered.re * (audio_max_duty as f32)) * 3.0f32) as u16;
|
||||
|
|
|
@ -57,6 +57,7 @@ pub struct PllParams {
|
|||
pub struct Si5153<I2C> {
|
||||
// Marker that makes sure we always get the same I2C
|
||||
i2c: PhantomData<I2C>,
|
||||
freq_xtal: u32,
|
||||
pll_freqs: [u32; 2],
|
||||
outputs: u8,
|
||||
ms_srcs: [PLL; 3],
|
||||
|
@ -69,6 +70,7 @@ where
|
|||
pub fn new(_i2c: &I2C) -> Self {
|
||||
Si5153 {
|
||||
i2c: PhantomData,
|
||||
freq_xtal: 0,
|
||||
pll_freqs: [0, 0],
|
||||
outputs: 0,
|
||||
ms_srcs: [PLL::A, PLL::A, PLL::A],
|
||||
|
@ -76,6 +78,8 @@ where
|
|||
}
|
||||
|
||||
pub fn init(&mut self, i2c: &mut I2C, freq_xtal: u32, freq_a: u32, freq_b: u32) {
|
||||
self.freq_xtal = freq_xtal;
|
||||
|
||||
self.pll_freqs[PLL::A as usize] = freq_a;
|
||||
self.pll_freqs[PLL::B as usize] = freq_b;
|
||||
|
||||
|
@ -83,34 +87,38 @@ where
|
|||
self.write_byte_reg(i2c, CLK_ENABLE_CONTROL, self.outputs); // Disable all outputs
|
||||
self.write_byte_reg(i2c, XTAL_LOAD_CAP, 0xD2); //crystal load capacitor = 10pF
|
||||
|
||||
self.set_pll_freq(i2c, PLL::A, freq_a);
|
||||
self.set_pll_freq(i2c, PLL::B, freq_b);
|
||||
|
||||
for ms in [Multisynth::MS0, Multisynth::MS1, Multisynth::MS2].iter() {
|
||||
self.ms_srcs[*ms as usize] = PLL::A;
|
||||
self.write_byte_reg(i2c, ms.ctrl_address(), 0x0F); // MSi as Source, PLLA to MSi, 8 mA output
|
||||
self.write_byte_reg(i2c, ms.phoff_address(), 0); // Phase offset to 0.
|
||||
}
|
||||
|
||||
for pll in [PLL::A, PLL::B].iter() {
|
||||
let fdiv = self.pll_freqs[*pll as usize] / freq_xtal;
|
||||
let rm = self.pll_freqs[*pll as usize] % freq_xtal;
|
||||
|
||||
let gcd = num::integer::gcd(rm, freq_xtal);
|
||||
|
||||
let c = if gcd < 0x0FFFFF { gcd } else { 0x0FFFFF };
|
||||
let a = fdiv;
|
||||
let b = ((rm as u64) * (c as u64) / (freq_xtal as u64)) as u32;
|
||||
|
||||
let params = PllParams {
|
||||
p1: 128 * a + (128 * b / c) - 512,
|
||||
p2: 128 * b - c * (128 * b / c),
|
||||
p3: c,
|
||||
};
|
||||
|
||||
self.write_params(i2c, pll.base_address(), ¶ms)
|
||||
}
|
||||
|
||||
self.write_byte_reg(i2c, PLL_RESET, 0xA0); // Reset both PLLs
|
||||
}
|
||||
|
||||
pub fn set_pll_freq(&mut self, i2c: &mut I2C, pll: PLL, freq: u32) {
|
||||
let fdiv = freq / self.freq_xtal;
|
||||
let rm = freq % self.freq_xtal;
|
||||
|
||||
let gcd = num::integer::gcd(rm, self.freq_xtal);
|
||||
|
||||
let c = if gcd < 0x0FFFFF { gcd } else { 0x0FFFFF };
|
||||
let a = fdiv;
|
||||
let b = ((rm as u64) * (c as u64) / (self.freq_xtal as u64)) as u32;
|
||||
|
||||
let params = PllParams {
|
||||
p1: 128 * a + (128 * b / c) - 512,
|
||||
p2: 128 * b - c * (128 * b / c),
|
||||
p3: c,
|
||||
};
|
||||
|
||||
self.write_params(i2c, pll.base_address(), ¶ms);
|
||||
self.pll_freqs[pll as usize] = freq;
|
||||
}
|
||||
|
||||
pub fn enable_ms_output(&mut self, i2c: &mut I2C, synth: Multisynth) {
|
||||
self.outputs &= !(1 << (synth as u8));
|
||||
self.write_byte_reg(i2c, CLK_ENABLE_CONTROL, self.outputs);
|
||||
|
|
Loading…
Reference in New Issue