#![no_std]
#![no_main]
use core::sync::atomic::{AtomicBool, Ordering};
use daisy_embassy::audio::{Idle, Interface};
use daisy_embassy::sdram::FmcDevice;
use daisy_embassy::{audio::HALF_DMA_BUFFER_LENGTH, hal, new_daisy_board, sdram::SDRAM_SIZE};
use defmt::{debug, info, unwrap};
use embassy_executor::{InterruptExecutor, Spawner};
use embassy_stm32::fmc::Fmc;
use embassy_stm32::interrupt;
use embassy_stm32::interrupt::{InterruptExt, Priority};
use embassy_stm32::peripherals::FMC;
use embassy_stm32::{exti::ExtiInput, gpio::Pull};
use embassy_time::{Delay, Timer};
use stm32_fmc::Sdram;
use {defmt_rtt as _, panic_probe as _};
const LOOPER_LENGTH: usize = 960_000;
const SILENCE: u32 = u32::MAX / 2;
static RECORD: AtomicBool = AtomicBool::new(false);
static AUDIO_EXECUTOR: InterruptExecutor = InterruptExecutor::new();
#[interrupt]
unsafe fn SAI1() {
AUDIO_EXECUTOR.on_interrupt()
}
#[embassy_executor::task]
async fn run_audio(
interface: Interface<'static, Idle>,
mut sdram: Sdram<Fmc<'static, FMC>, FmcDevice>,
) {
let mut delay = Delay;
let ram_slice = unsafe {
let ram_ptr: *mut u32 = sdram.init(&mut delay) as *mut _;
core::slice::from_raw_parts_mut(ram_ptr, SDRAM_SIZE / core::mem::size_of::<u32>())
};
let loop_buffer = &mut ram_slice[..LOOPER_LENGTH];
for smp in loop_buffer.iter_mut() {
*smp = SILENCE;
}
const BL: usize = HALF_DMA_BUFFER_LENGTH;
let mut rp = 0;
let mut pp = 0;
let mut interface = unwrap!(interface.start_interface().await);
unwrap!(
interface
.start_callback(|input, output| {
if RECORD.load(Ordering::SeqCst) {
let remain = BL.min(LOOPER_LENGTH - rp);
loop_buffer[rp..(rp + remain)].copy_from_slice(input);
rp += BL;
if rp >= LOOPER_LENGTH {
rp = 0;
RECORD.store(false, Ordering::SeqCst);
info!("finished recording");
}
}
let remain = BL.min(LOOPER_LENGTH - pp);
let frac = BL - remain;
output.copy_from_slice(&loop_buffer[pp..(pp + remain)]);
if frac > 0 {
output[remain..BL].copy_from_slice(&loop_buffer[0..frac]);
}
pp += BL;
if pp >= LOOPER_LENGTH {
pp -= LOOPER_LENGTH;
info!("loop!!");
}
})
.await
);
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
debug!("====program start====");
let config = daisy_embassy::default_rcc();
let p = hal::init(config);
let mut c = cortex_m::Peripherals::take().unwrap();
let board = new_daisy_board!(p);
let interface = board
.audio_peripherals
.prepare_interface(Default::default())
.await;
let sdram = board.sdram.build(&mut c.MPU, &mut c.SCB);
#[cfg(any(feature = "seed", feature = "seed_1_1", feature = "seed_1_2"))]
let mut record_pin = ExtiInput::new(board.pins.d16, p.EXTI3, Pull::Up);
#[cfg(feature = "patch_sm")]
let mut record_pin = ExtiInput::new(board.pins.b7, p.EXTI8, Pull::Up);
let record_fut = async {
loop {
record_pin.wait_for_falling_edge().await;
RECORD.store(true, Ordering::SeqCst);
info!("record!!");
Timer::after_millis(15).await; }
};
interrupt::SAI1.set_priority(Priority::P6);
let spawner = AUDIO_EXECUTOR.start(interrupt::SAI1);
defmt::unwrap!(spawner.spawn(run_audio(interface, sdram)));
record_fut.await;
}