Fix some stuff and add clock output
This commit is contained in:
131
src/main.rs
131
src/main.rs
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user