diff --git a/Cargo.toml b/Cargo.toml index a8e8a59..9b630fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ microfft = "0.5.1" st7735-lcd = "0.9.0" embedded-graphics = "0.8.0" colorous = { version="1.0.12", default-features = false} +profont = "0.7.0" +ufmt = "0.2.0" [features] diff --git a/src/main.rs b/src/main.rs index f321711..6f5ad79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,6 @@ mod app { use core::mem; - use embedded_hal::blocking::spi::transfer; use num::Complex; use stm32f4xx_hal::{ adc::{ @@ -56,8 +55,16 @@ mod app { use crate::filters; use crate::si5153; + use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::*; + use embedded_graphics::primitives::rectangle::Rectangle; + use embedded_graphics::primitives::{Line, PrimitiveStyle}; + use embedded_graphics::text::Text; + use profont::PROFONT_14_POINT; + + use core::fmt::Write; + use st7735_lcd::{Orientation, ST7735}; type AudioPwm = PwmHz>; @@ -321,7 +328,7 @@ mod app { ) } - #[task(priority = 0, local = [disp, row_pos, row_buffer, row_buffer_count, max_mag, encoder, last_encoder_pos, carrier_freq, pll, i2c])] + #[task(priority = 0, local = [disp, row_pos, row_buffer, row_buffer_count, encoder, last_encoder_pos, carrier_freq, pll, i2c])] async fn update_display(cx: update_display::Context, mut row: [Complex; 128]) { let buffers_per_row = 4; @@ -336,21 +343,15 @@ mod app { if *cx.local.row_buffer_count > buffers_per_row { *cx.local.row_buffer_count = 0; - for samp in cx.local.row_buffer.iter() { - let mag = (samp.re.pow(2) as f32 + samp.im.pow(2) as f32).sqrt() as f32; - *cx.local.max_mag = if mag > *cx.local.max_mag { - mag - } else { - *cx.local.max_mag - }; - } - let gradient = colorous::TURBO; for idx in 0..128 { - let norm_intens = (cx.local.row_buffer[idx].re.pow(2) - + cx.local.row_buffer[idx].im.pow(2)) - / *cx.local.max_mag; + let intens: f32 = + cx.local.row_buffer[idx].re.pow(2) + cx.local.row_buffer[idx].im.pow(2); + + let log_intens = intens.log10() / 2.0 * 10.0; + let norm_intens = (log_intens + 18.0) / 18.0; + let color = gradient.eval_continuous(norm_intens as f64); let x = if idx < 64 { 64 + idx } else { idx - 64 }; @@ -365,16 +366,22 @@ mod app { } *cx.local.row_pos = (*cx.local.row_pos + 1) % 100; - *cx.local.max_mag *= 0.999; + Line::new( + Point::new(32, 28 + *cx.local.row_pos as i32), + Point::new(159, 28 + *cx.local.row_pos as i32), + ) + .into_styled(PrimitiveStyle::with_stroke(Rgb565::BLACK, 1)) + .draw(cx.local.disp) + .unwrap(); defmt::info!("Position is {}", cx.local.row_pos); } let encoder_pos = cx.local.encoder.count(); - let diff = encoder_pos.wrapping_sub(*cx.local.last_encoder_pos) as i32; + let diff = encoder_pos.wrapping_sub(*cx.local.last_encoder_pos) as i32 / 4; - if diff != 0 { - *cx.local.carrier_freq = (*cx.local.carrier_freq as i32 + diff * 100 / 4) as u32; + if diff >= 1 || diff <= -1 { + *cx.local.carrier_freq = (*cx.local.carrier_freq as i32 + diff * 100) as u32; cx.local .pll .set_pll_freq(cx.local.i2c, si5153::PLL::A, *cx.local.carrier_freq * 100); @@ -388,10 +395,22 @@ mod app { si5153::Multisynth::MS1, *cx.local.carrier_freq, ); + + Rectangle::new(Point::new(0, 0), Size::new(160, 28)) + .into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK)) + .draw(cx.local.disp) + .unwrap(); + + let mut freq_txt = arrayvec::ArrayString::<11>::new(); + write!(freq_txt, "{}", cx.local.carrier_freq).unwrap(); + let text_style = MonoTextStyle::new(&PROFONT_14_POINT, Rgb565::WHITE); + Text::new(&freq_txt, Point::new(8, 16), text_style) + .draw(cx.local.disp) + .unwrap(); + + *cx.local.last_encoder_pos = encoder_pos; } 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])] @@ -416,7 +435,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) * 5.0; + samples[idx] = Complex::new(q_sample as f32 / 4096.0, i_sample as f32 / 4096.0); } let mut fft_input = [Complex::::default(); 128]; @@ -437,8 +456,10 @@ mod app { *buffer = Some(audio_buffer); }); - update_display::spawn(fft_input).unwrap(); - + match update_display::spawn(fft_input) { + Ok(_) => {} + Err(_) => defmt::warn!("Skipping display update."), + } *cx.local.iq_buffer = Some(buffer); }