Fix some stuff and add clock output

This commit is contained in:
2025-11-28 23:53:37 +01:00
parent 6cf860fb34
commit 657c06e978

View File

@@ -7,6 +7,7 @@
//! GP15..GP22 => D0..D7
//! GP26 => CE
//! GP27 => OE
//! GP28 => Clock
mod serial;
@@ -26,11 +27,12 @@ use embassy_rp::{
flash::{self, FLASH_BASE, Flash},
gpio::{Drive, Level, Output, SlewRate},
multicore::{Stack, spawn_core1},
pac::SIO,
peripherals::{FLASH, PIO0, USB},
pio::{self, Direction, Pio, ShiftConfig, ShiftDirection, StateMachine, program::pio_asm},
pio::{self, Pio, ShiftConfig, ShiftDirection, StateMachine, program::pio_asm},
usb::{self, Driver},
};
use embassy_time::Timer;
use embassy_time::{Duration, Ticker, Timer};
use embassy_usb::{
UsbDevice,
class::cdc_acm::{self, CdcAcmClass},
@@ -40,9 +42,6 @@ use static_cell::{ConstStaticCell, StaticCell};
use crate::serial::{Link, PacketBuilder};
const ADDRESS_PINS: u8 = 15;
const DATA_PINS: u8 = 8;
const ROM_SIZE: usize = 32 * 1024;
const FLASH_SIZE: usize = 2 * 1024 * 1024;
@@ -64,7 +63,8 @@ async fn main(spawner: Spawner) -> ! {
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() };
let mut led = Output::new(p.PIN_25, Level::High);
let clock = Output::new(p.PIN_28, Level::Low);
let mut flash = Flash::<_, _, FLASH_SIZE>::new_blocking(p.FLASH);
@@ -76,27 +76,16 @@ async fn main(spawner: Spawner) -> ! {
let data = pio_asm!(".wrap_target", "out pins, 8", ".wrap");
// OR CE and OE and set 4 pindirs
let output_enable = pio_asm!(
".origin 0",
".side_set 4 pindirs",
"mov pc, pins side 0xf",
"mov pc, pins side 0x0",
"mov pc, pins side 0x0",
"mov pc, pins side 0x0"
);
// report pin activity to the cpu
let report_data = pio_asm!(
"wait_oe:",
"mov y, pins", // read all pins
"mov osr, y", // move into the osr so we can shift them out
"out null, 26", // skipp all pins until CE
"out x, 2", // put CE and OE into x
"jmp x--, wait_oe", // if any of CE and OE are set go back to the start
"mov isr, y", // put the address into the isr
"push",
".wrap_target",
"mov x, pins", // read all pins
"jmp x!=y wait_oe", // if any pins have changed, restart and check oe again
".wrap"
".side_set 4 opt pindirs",
"loop:",
"in NULL, 32",
"in pins, 2",
"mov x, isr",
"jmp !x low",
"high:",
"jmp loop side 0x0",
"low:",
"jmp loop side 0xf",
);
let Pio {
@@ -104,7 +93,6 @@ async fn main(spawner: Spawner) -> ! {
mut sm0,
mut sm1,
mut sm2,
mut sm3,
..
} = Pio::new(p.PIO0, Irqs);
let output_enable = common.load_program(&output_enable.program);
@@ -158,44 +146,13 @@ async fn main(spawner: Spawner) -> ! {
ce_pin.set_schmitt(true);
let mut oe_pin = common.make_pio_pin(p.PIN_27);
oe_pin.set_schmitt(true);
let led_pin = common.make_pio_pin(p.PIN_25);
let address_pins = [
&address_pins[0],
&address_pins[1],
&address_pins[2],
&address_pins[3],
&address_pins[4],
&address_pins[5],
&address_pins[6],
&address_pins[7],
&address_pins[8],
&address_pins[9],
&address_pins[10],
&address_pins[11],
&address_pins[12],
&address_pins[13],
&address_pins[14],
data_pins[0],
data_pins[1],
data_pins[2],
data_pins[3],
data_pins[4],
data_pins[5],
data_pins[6],
data_pins[7],
&common.make_pio_pin(p.PIN_23),
&common.make_pio_pin(p.PIN_24),
&led_pin,
&ce_pin,
&oe_pin,
];
// configure data pio
let mut cfg = pio::Config::default();
cfg.use_program(&common.load_program(&data.program), &[]);
cfg.set_out_pins(&data_pins[..]);
cfg.shift_out = ShiftConfig {
threshold: DATA_PINS,
threshold: u8::try_from(data_pins.len()).unwrap_or(32),
direction: ShiftDirection::default(),
auto_fill: true,
};
@@ -212,30 +169,12 @@ async fn main(spawner: Spawner) -> ! {
sm2.set_config(&cfg);
sm2.set_enable(true);
// configure address pio
let mut cfg = pio::Config::default();
cfg.use_program(&common.load_program(&report_data.program), &[]);
cfg.set_in_pins(&address_pins[..]);
cfg.shift_in = ShiftConfig {
threshold: ADDRESS_PINS,
direction: ShiftDirection::default(),
auto_fill: true,
};
sm3.set_pin_dirs(Direction::In, &address_pins[..]);
sm3.set_pin_dirs(Direction::Out, &[&led_pin]);
sm3.set_config(&cfg);
sm3.set_enable(true);
spawn_core1(
p.CORE1,
unsafe { &mut *addr_of_mut!(CORE1_STACK) },
move || core1_loop(sm0, sm3),
move || core1_loop(sm0),
);
// 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 = {
@@ -270,8 +209,9 @@ async fn main(spawner: Spawner) -> ! {
let usb = builder.build();
spawner.must_spawn(usb_task(usb));
spawner.must_spawn(clock_task(clock));
let mut led = Output::new(led, Level::Low);
led.set_low();
loop {
'outer: {
@@ -319,17 +259,17 @@ 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>,
) -> ! {
fn core1_loop<const N: usize>(mut data_sm: StateMachine<'_, impl pio::Instance, N>) -> ! {
let mut last_address = 0;
loop {
let address = loop {
if let Some(address) = address_sm.rx().try_pull() {
break address;
}
};
let address = SIO.gpio_in(0).read();
let address = (address & 0x7fff) as u16;
let address2 = SIO.gpio_in(0).read();
let address2 = (address2 & 0x7fff) as u16;
if address != address2 || address == last_address {
continue;
}
last_address = address;
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));
@@ -342,16 +282,11 @@ async fn usb_task(mut usb: UsbDevice<'static, Driver<'static, USB>>) -> ! {
}
#[task]
async fn pio_task(
mut data_sm: StateMachine<'static, PIO0, 0>,
mut address_sm: StateMachine<'static, PIO0, 3>,
) -> ! {
async fn clock_task(mut clock: Output<'static>) -> ! {
let mut ticker = Ticker::every(Duration::from_millis(250));
loop {
let address = address_sm.rx().wait_pull().await;
let address = (address & 0x7fff) as u16;
let data = ROM_DATA[usize::from(address)].load(Ordering::SeqCst);
defmt::trace!("replying with {:#04x} @ {:#06x}", data, address);
data_sm.tx().try_push(u32::from(data));
clock.toggle();
ticker.next().await;
}
}