make rom faster

This commit is contained in:
2025-11-23 17:12:27 +01:00
parent 53d35464f5
commit 6cf860fb34
10 changed files with 318 additions and 29 deletions

View File

@@ -12,23 +12,25 @@ mod serial;
use core::{
mem::MaybeUninit,
ptr::addr_of_mut,
sync::atomic::{AtomicU8, Ordering},
task::Poll,
};
use defmt_rtt as _;
use embassy_executor::{InterruptExecutor, Spawner, task};
use embassy_futures::{poll_once, yield_now};
use embassy_executor::{Spawner, task};
use embassy_futures::poll_once;
use embassy_rp::{
bind_interrupts,
clocks::ClockConfig,
flash::{self, FLASH_BASE, Flash},
gpio::{Drive, Level, Output, SlewRate},
interrupt::{self, InterruptExt, Priority},
multicore::{Stack, spawn_core1},
peripherals::{FLASH, PIO0, USB},
pio::{self, Direction, Pio, ShiftConfig, ShiftDirection, StateMachine, program::pio_asm},
usb::{self, Driver},
};
use embassy_time::Timer;
use embassy_usb::{
UsbDevice,
class::cdc_acm::{self, CdcAcmClass},
@@ -45,6 +47,7 @@ const ROM_SIZE: usize = 32 * 1024;
const FLASH_SIZE: usize = 2 * 1024 * 1024;
static ROM_DATA: [AtomicU8; ROM_SIZE] = [const { AtomicU8::new(0) }; ROM_SIZE];
static mut CORE1_STACK: Stack<4096> = Stack::new();
#[unsafe(link_section = ".romdata")]
#[used]
@@ -55,17 +58,10 @@ bind_interrupts!(struct Irqs {
USBCTRL_IRQ => usb::InterruptHandler<USB>;
});
static EXECUTOR_HIGH: InterruptExecutor = InterruptExecutor::new();
#[embassy_rp::interrupt]
unsafe fn SWI_IRQ_0() {
unsafe { EXECUTOR_HIGH.on_interrupt() }
}
#[embassy_executor::main]
async fn main(spawner: Spawner) -> ! {
let config =
embassy_rp::config::Config::new(defmt::unwrap!(ClockConfig::system_freq(133_000_000)));
embassy_rp::config::Config::new(defmt::unwrap!(ClockConfig::system_freq(200_000_000)));
let p = embassy_rp::init(config);
let led = unsafe { p.PIN_25.clone_unchecked() };
@@ -230,6 +226,16 @@ async fn main(spawner: Spawner) -> ! {
sm3.set_config(&cfg);
sm3.set_enable(true);
spawn_core1(
p.CORE1,
unsafe { &mut *addr_of_mut!(CORE1_STACK) },
move || core1_loop(sm0, sm3),
);
// enable the rx not empty interrupt for sm3 on interrupt line 0
// let pio = PIO0;
// pio.irqs(0).inte().modify(|m| m.set_sm3_rxnempty(true));
let driver = Driver::new(p.USB, Irqs);
let config = {
@@ -263,13 +269,6 @@ async fn main(spawner: Spawner) -> ! {
let usb = builder.build();
interrupt::PIO0_IRQ_0.set_priority(Priority::P0);
interrupt::SWI_IRQ_0.set_priority(Priority::P1);
interrupt::USBCTRL_IRQ.set_priority(Priority::P3);
let int_spawner = EXECUTOR_HIGH.start(interrupt::SWI_IRQ_0);
int_spawner.must_spawn(pio_task(sm0, sm3));
spawner.must_spawn(usb_task(usb));
let mut led = Output::new(led, Level::Low);
@@ -279,7 +278,7 @@ async fn main(spawner: Spawner) -> ! {
led.set_low();
class.wait_connection().await;
while !class.rts() {
yield_now().await;
Timer::after_micros(1).await;
}
defmt::info!("USB Connected");
led.set_high();
@@ -298,7 +297,7 @@ async fn main(spawner: Spawner) -> ! {
break 'outer;
}
Poll::Pending => {
yield_now().await;
Timer::after_micros(1).await;
continue;
}
};
@@ -320,6 +319,23 @@ async fn main(spawner: Spawner) -> ! {
}
}
fn core1_loop<const N1: usize, const N2: usize>(
mut data_sm: StateMachine<'_, impl pio::Instance, N1>,
mut address_sm: StateMachine<'_, impl pio::Instance, N2>,
) -> ! {
loop {
let address = loop {
if let Some(address) = address_sm.rx().try_pull() {
break address;
}
};
let address = (address & 0x7fff) as u16;
let data = ROM_DATA[usize::from(address)].load(Ordering::Relaxed);
defmt::debug!("replying with {:#04x} @ {:#06x}", data, address);
data_sm.tx().push(u32::from(data));
}
}
#[task]
async fn usb_task(mut usb: UsbDevice<'static, Driver<'static, USB>>) -> ! {
usb.run().await