Fixed panic on slow display updates

Cleaned up encoder code
This commit is contained in:
Sebastian 2023-08-27 12:20:01 +02:00
parent eaee903172
commit a63f187211
2 changed files with 46 additions and 23 deletions

View File

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

View File

@ -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<TIM4, ChannelBuilder<TIM4, 2>>;
@ -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<f32>; 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::<f32>::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);
}