From 6c7202bed2bdc6a1ca00fb5f9740a5458dce3f9a Mon Sep 17 00:00:00 2001 From: Naxdy Date: Tue, 5 Mar 2024 08:11:49 +0100 Subject: [PATCH] working flash and gc controller --- Cargo.lock | 10 +++++++ Cargo.toml | 1 + src/flash_mem.rs | 36 +++++++++++++++++++++++++ src/gcc_hid.rs | 69 +++++++++++++++++++++++------------------------- src/main.rs | 46 ++++++++++++++++++++------------ 5 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 src/flash_mem.rs diff --git a/Cargo.lock b/Cargo.lock index d9956d6..4a3b932 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -269,6 +269,7 @@ dependencies = [ "panic-halt", "panic-probe", "rp2040-boot2", + "rp2040-flash", "rp2040-hal", "usb-device", "usbd-human-interface-device", @@ -451,6 +452,15 @@ dependencies = [ "crc-any", ] +[[package]] +name = "rp2040-flash" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2007f9701924b88cbffc172cdf09e01b9c03ecd0b2f59bc6eea5283982855438" +dependencies = [ + "rp2040-hal", +] + [[package]] name = "rp2040-hal" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index f6a372e..b9a0b9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] rp2040-hal = { version = "0.9.2", features = ["rt", "critical-section-impl"] } +rp2040-flash = "0.4.0" usbd-human-interface-device = { version = "0.4.5", features = ["defmt"] } usb-device = "0.2" cortex-m = "0.7.7" diff --git a/src/flash_mem.rs b/src/flash_mem.rs new file mode 100644 index 0000000..b89a19e --- /dev/null +++ b/src/flash_mem.rs @@ -0,0 +1,36 @@ +use core::slice::from_raw_parts; + +use defmt::info; +use rp2040_flash::flash::{flash_range_erase, flash_range_program}; + +const XIP_BASE: u32 = 0x10000000; +const FLASH_PAGE_SIZE: usize = 1usize << 8; +const FLASH_SECTOR_SIZE: u32 = 1u32 << 12; +const FLASH_BLOCK_SIZE: u32 = 1u32 << 16; +const FLASH_BLOCK_ERASE_CMD: u8 = 0xd8; + +const FLASH_TARGET_OFFSET: u32 = 256 * 1024; + +pub fn read_from_flash() -> u8 { + let flash_target_contents = (XIP_BASE + FLASH_TARGET_OFFSET) as *const u8; + + let d = unsafe { from_raw_parts(flash_target_contents, FLASH_PAGE_SIZE) }; + + d[0] +} + +pub unsafe fn write_to_flash(b: u8) { + let mut data = [0u8; FLASH_PAGE_SIZE]; + data[0] = b; + info!("About to write with XIP_BASE: 0x{:x}", XIP_BASE); + info!("FLASH_PAGE_SIZE is {}", FLASH_PAGE_SIZE); + info!("FLASH_SECTOR_SIZE is {}", FLASH_SECTOR_SIZE); + info!("FLASH_BLOCK_SIZE is {}", FLASH_BLOCK_SIZE); + info!("FLASH_BLOCK_ERASE_CMD is 0x{:x}", FLASH_BLOCK_ERASE_CMD); + info!("FLASH_TARGET_OFFSET is {}", FLASH_TARGET_OFFSET); + + flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE, true); + info!("Erased flash"); + flash_range_program(FLASH_TARGET_OFFSET, &data, true); + info!("Wrote to flash"); +} diff --git a/src/gcc_hid.rs b/src/gcc_hid.rs index 8730d4a..cd990c0 100644 --- a/src/gcc_hid.rs +++ b/src/gcc_hid.rs @@ -7,7 +7,7 @@ use usbd_human_interface_device::{ descriptor::InterfaceProtocol, device::DeviceClass, interface::{ - InBytes8, Interface, InterfaceBuilder, InterfaceConfig, OutNone, ReportSingle, + InBytes64, InBytes8, Interface, InterfaceBuilder, InterfaceConfig, OutNone, ReportSingle, UsbAllocatable, }, UsbHidError, @@ -73,69 +73,69 @@ pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[ ]; #[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] -#[packed_struct(endian = "msb", size_bytes = "1")] +#[packed_struct(bit_numbering = "lsb0", size_bytes = "1")] pub struct Buttons1 { - #[packed_field(size_bits = "1")] + #[packed_field(bits = "0")] pub button_a: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "1")] pub button_b: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "2")] pub button_x: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "3")] pub button_y: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "4")] pub dpad_left: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "5")] pub dpad_right: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "6")] pub dpad_down: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "7")] pub dpad_up: bool, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] -#[packed_struct(endian = "msb", size_bytes = "1")] +#[packed_struct(bit_numbering = "lsb0", size_bytes = "1")] pub struct Buttons2 { - #[packed_field(size_bits = "1")] + #[packed_field(bits = "0")] pub button_start: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "1")] pub button_z: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "2")] pub button_r: bool, - #[packed_field(size_bits = "1")] + #[packed_field(bits = "3")] pub button_l: bool, - #[packed_field(size_bits = "4")] + #[packed_field(bits = "4..=7")] pub blank1: Integer>, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] -#[packed_struct(endian = "msb", size_bytes = "8")] +#[packed_struct(bit_numbering = "msb0", size_bytes = "8")] pub struct GcReport { - #[packed_field(size_bits = "8")] + #[packed_field(bits = "0..=7")] pub buttons_1: Buttons1, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "8..=15")] pub buttons_2: Buttons2, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "16..=23")] pub stick_x: u8, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "24..=31")] pub stick_y: u8, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "32..=39")] pub cstick_x: u8, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "40..=47")] pub cstick_y: u8, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "48..=55")] pub trigger_l: u8, - #[packed_field(size_bits = "8")] + #[packed_field(bits = "56..=63")] pub trigger_r: u8, } pub struct GcConfig<'a> { - interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>, + interface: InterfaceConfig<'a, InBytes64, OutNone, ReportSingle>, } impl<'a> GcConfig<'a> { #[must_use] - pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self { + pub fn new(interface: InterfaceConfig<'a, InBytes64, OutNone, ReportSingle>) -> Self { Self { interface } } } @@ -146,7 +146,7 @@ impl<'a> Default for GcConfig<'a> { let i = unwrap!(unwrap!(InterfaceBuilder::new(GCC_REPORT_DESCRIPTOR)) .boot_device(InterfaceProtocol::None) .description("NaxGCC") - .in_endpoint(10.millis())); + .in_endpoint(1.millis())); Self::new(i.without_out_endpoint().build()) } @@ -163,27 +163,25 @@ impl<'a, B: UsbBus + 'a> UsbAllocatable<'a, B> for GcConfig<'a> { } pub struct GcController<'a, B: UsbBus> { - interface: Interface<'a, B, InBytes8, OutNone, ReportSingle>, + interface: Interface<'a, B, InBytes64, OutNone, ReportSingle>, } impl<'a, B: UsbBus> GcController<'a, B> { pub fn write_report(&mut self, report: &GcReport) -> Result<(), UsbHidError> { let report = get_gcinput_hid_report(report); // print report as binary + info!("Report: {:08b}", report); self.interface .write_report(&report) .map(|_| ()) - .map_err(|e| { - error!("Found an error: {:?}", e); - UsbHidError::from(e) - }) + .map_err(|e| UsbHidError::from(e)) } } impl<'a, B: UsbBus> DeviceClass<'a> for GcController<'a, B> { - type I = Interface<'a, B, InBytes8, OutNone, ReportSingle>; + type I = Interface<'a, B, InBytes64, OutNone, ReportSingle>; fn interface(&mut self) -> &mut Self::I { &mut self.interface @@ -202,11 +200,10 @@ fn get_gcinput_hid_report(input_state: &GcReport) -> [u8; 37] { let mut buffer = [0u8; 37]; buffer[0] = 0x21; + buffer[1] |= 0x14; let data = input_state.pack().expect("Failed to pack GC input data"); - info!("Packed data: {:08b}", data); - if unsafe { !GC_FIRST } { buffer[1] |= 0x04; buffer[10] |= 0x04; diff --git a/src/main.rs b/src/main.rs index b296edd..8cf1fa3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ #![no_std] #![no_main] +mod flash_mem; mod gcc_hid; use core::fmt::Write; @@ -19,6 +20,7 @@ use fugit::ExtU32; // Ensure we halt the program on panic (if we don't mention this crate it won't // be linked) use defmt_rtt as _; +use packed_struct::PackedStruct; use panic_halt as _; // Alias for our HAL crate @@ -33,14 +35,20 @@ use hal::{ }; // Some traits we need -use embedded_hal::{blocking::delay::DelayMs, digital::v2::OutputPin, timer::CountDown}; +use embedded_hal::{ + blocking::delay::DelayMs, + digital::v2::{InputPin, OutputPin}, + timer::CountDown, +}; use rp2040_hal::Clock; use usb_device::{ bus::UsbBusAllocator, - device::{UsbDeviceBuilder, UsbVidPid}, + device::{UsbDeviceBuilder, UsbDeviceState, UsbVidPid}, }; use usbd_human_interface_device::{usb_class::UsbHidClassBuilder, UsbHidError}; +use crate::flash_mem::{read_from_flash, write_to_flash}; + /// The linker will place this boot block at the start of our program image. We /// need this to help the ROM bootloader get our code up and running. /// Note: This boot block is not necessary when using a rp-hal based BSP @@ -84,7 +92,7 @@ fn main() -> ! { let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); let mut poll_timer = timer.count_down(); - poll_timer.start(10.millis()); + poll_timer.start(1.millis()); // The single-cycle I/O block controls our GPIO pins let sio = hal::Sio::new(pac.SIO); @@ -124,23 +132,26 @@ fn main() -> ! { .max_packet_size_0(64) .build(); - let mut uart = UartPeripheral::new( - pac.UART0, - ( - pins.gpio0.into_mode::(), - pins.gpio1.into_mode(), - ), - &mut pac.RESETS, - ) - .enable(UartConfig::default(), clocks.peripheral_clock.freq()) - .unwrap(); + gcc_state.stick_x = 0; + gcc_state.stick_y = 0; + gcc_state.trigger_l = 21; + gcc_state.cstick_x = 127; + gcc_state.cstick_y = 127; - gcc_state.buttons_1.button_a = true; + let btn_pin = pins.gpio15.into_pull_up_input(); + + unsafe { + let some_byte: u8 = 0xAB; + info!("Byte to be written is {:02X}", some_byte); + write_to_flash(some_byte); + let r = read_from_flash(); + info!("Byte read from flash is {:02X}", r); + } + + info!("Initialized"); // Configure GPIO25 as an output let mut led_pin = pins.gpio25.into_push_pull_output(); - info!("Bleg"); - let _ = uart.write_str("FLAR"); loop { if poll_timer.wait().is_ok() { match gcc.device().write_report(&gcc_state) { @@ -153,7 +164,8 @@ fn main() -> ! { } } } - if usb_dev.poll(&mut [&mut gcc]) {} + + gcc_state.buttons_2.button_start = btn_pin.is_low().unwrap(); } }