First audio out experiments

This commit is contained in:
Sebastian 2023-08-11 17:35:48 +02:00
parent 54c7ef4b33
commit b26dda4a2a
1 changed files with 35 additions and 36 deletions

View File

@ -61,9 +61,6 @@ mod app {
type AudioPwm = PwmHz<TIM4, ChannelBuilder<TIM4, 2>>;
#[shared]
struct Shared {}
#[local]
struct Local {
pll: si5153::Si5153<I2c<I2C1>>,
@ -88,8 +85,6 @@ mod app {
stm32f4xx_hal::dma::MemoryToPeripheral,
&'static mut [u16; 256],
>,
audio_buffer: Option<&'static mut [u16; 256]>,
phase: f32,
audio_max_duty: u16,
disp_led: gpioa::PA10<Output<PushPull>>,
@ -99,6 +94,11 @@ mod app {
max_mag: f32,
}
#[shared]
struct Shared {
audio_buffer: Option<&'static mut [u16; 256]>,
}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
let rcc = cx.device.RCC.constrain();
@ -263,7 +263,9 @@ mod app {
let _bias_pwm = cx.device.TIM3.pwm_hz(bias_pin, 64.kHz(), &clocks);
(
Shared {},
Shared {
audio_buffer: Some(audio_buff2),
},
Local {
i2c,
pll,
@ -280,8 +282,6 @@ mod app {
iq_buffer: Some(iq_buff2),
pwm_transfer,
audio_buffer: Some(audio_buff2),
phase: 0.0,
audio_max_duty,
disp_led,
@ -296,7 +296,7 @@ mod app {
#[task(priority = 0, local = [disp, col_pos, max_mag])]
async fn update_display(cx: update_display::Context, col: [Complex<f32>; 128]) {
for samp in col {
let mag = (samp.re.pow(2) + samp.im.pow(2)) / 5.0 as f32;
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 {
@ -324,8 +324,8 @@ mod app {
defmt::info!("Position is {}", cx.local.col_pos);
}
#[task(binds = DMA2_STREAM0, local = [adc_transfer, iq_buffer, board_led, i_offset, q_offset, usb_filter])]
fn dma2_stream0(cx: dma2_stream0::Context) {
#[task(binds = DMA2_STREAM0, local = [adc_transfer, iq_buffer, board_led, i_offset, q_offset, usb_filter, audio_max_duty], shared = [audio_buffer])]
fn dma2_stream0(mut cx: dma2_stream0::Context) {
let (buffer, _) = cx
.local
.adc_transfer
@ -351,10 +351,20 @@ mod app {
let mut fft_input = [Complex::<f32>::default(); 128];
for idx in 0..samples.len() / 2 {
let filtered = cx.local.usb_filter.compute(samples[idx]);
fft_input[idx] = filtered;
}
let usb_filter = cx.local.usb_filter;
let audio_max_duty = *cx.local.audio_max_duty;
cx.shared.audio_buffer.lock(|buffer| {
let audio_buffer = buffer.take().unwrap();
for idx in 0..samples.len() / 2 {
let filtered = usb_filter.compute(samples[idx]);
fft_input[idx] = filtered;
audio_buffer[idx] = (filtered.re * (audio_max_duty as f32)) as u16;
}
*buffer = Some(audio_buffer);
});
let spectrum = cfft_128(&mut fft_input);
@ -363,28 +373,17 @@ mod app {
*cx.local.iq_buffer = Some(buffer);
}
#[task(binds = DMA1_STREAM7, local = [pwm_transfer, audio_buffer, phase, audio_max_duty])]
fn dma1_stream7(cx: dma1_stream7::Context) {
let (mut buffer, _) = cx
.local
.pwm_transfer
.next_transfer(cx.local.audio_buffer.take().unwrap())
.unwrap();
#[task(binds = DMA1_STREAM7, local = [pwm_transfer], shared = [audio_buffer])]
fn dma1_stream7(mut cx: dma1_stream7::Context) {
let pwm_transfer = cx.local.pwm_transfer;
cx.shared.audio_buffer.lock(|next_buffer| {
let (last_buffer, _) = pwm_transfer
.next_transfer(next_buffer.take().unwrap())
.unwrap();
defmt::info!("PWM transfer complete");
defmt::info!("PWM transfer complete");
let phase_inc = core::f32::consts::PI * 2.0 / 8000.0 * 440.0;
for i in 0..buffer.len() {
*cx.local.phase += phase_inc;
if *cx.local.phase > 2.0 * core::f32::consts::PI {
*cx.local.phase -= 2.0 * core::f32::consts::PI;
}
buffer[i] =
((cx.local.phase.sin() + 1.0) * (*cx.local.audio_max_duty as f32) / 4.0) as u16;
}
*cx.local.audio_buffer = Some(buffer);
*next_buffer = Some(last_buffer);
});
}
}