working flash and gc controller

This commit is contained in:
Naxdy 2024-03-05 08:11:49 +01:00
parent 33234c6257
commit 6c7202bed2
No known key found for this signature in database
GPG key ID: C0437AAE9755550F
5 changed files with 109 additions and 53 deletions

10
Cargo.lock generated
View file

@ -269,6 +269,7 @@ dependencies = [
"panic-halt", "panic-halt",
"panic-probe", "panic-probe",
"rp2040-boot2", "rp2040-boot2",
"rp2040-flash",
"rp2040-hal", "rp2040-hal",
"usb-device", "usb-device",
"usbd-human-interface-device", "usbd-human-interface-device",
@ -451,6 +452,15 @@ dependencies = [
"crc-any", "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]] [[package]]
name = "rp2040-hal" name = "rp2040-hal"
version = "0.9.2" version = "0.9.2"

View file

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
rp2040-hal = { version = "0.9.2", features = ["rt", "critical-section-impl"] } 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"] } usbd-human-interface-device = { version = "0.4.5", features = ["defmt"] }
usb-device = "0.2" usb-device = "0.2"
cortex-m = "0.7.7" cortex-m = "0.7.7"

36
src/flash_mem.rs Normal file
View file

@ -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");
}

View file

@ -7,7 +7,7 @@ use usbd_human_interface_device::{
descriptor::InterfaceProtocol, descriptor::InterfaceProtocol,
device::DeviceClass, device::DeviceClass,
interface::{ interface::{
InBytes8, Interface, InterfaceBuilder, InterfaceConfig, OutNone, ReportSingle, InBytes64, InBytes8, Interface, InterfaceBuilder, InterfaceConfig, OutNone, ReportSingle,
UsbAllocatable, UsbAllocatable,
}, },
UsbHidError, UsbHidError,
@ -73,69 +73,69 @@ pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[
]; ];
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] #[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 { pub struct Buttons1 {
#[packed_field(size_bits = "1")] #[packed_field(bits = "0")]
pub button_a: bool, pub button_a: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "1")]
pub button_b: bool, pub button_b: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "2")]
pub button_x: bool, pub button_x: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "3")]
pub button_y: bool, pub button_y: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "4")]
pub dpad_left: bool, pub dpad_left: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "5")]
pub dpad_right: bool, pub dpad_right: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "6")]
pub dpad_down: bool, pub dpad_down: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "7")]
pub dpad_up: bool, pub dpad_up: bool,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] #[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 { pub struct Buttons2 {
#[packed_field(size_bits = "1")] #[packed_field(bits = "0")]
pub button_start: bool, pub button_start: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "1")]
pub button_z: bool, pub button_z: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "2")]
pub button_r: bool, pub button_r: bool,
#[packed_field(size_bits = "1")] #[packed_field(bits = "3")]
pub button_l: bool, pub button_l: bool,
#[packed_field(size_bits = "4")] #[packed_field(bits = "4..=7")]
pub blank1: Integer<u8, packed_bits::Bits<4>>, pub blank1: Integer<u8, packed_bits::Bits<4>>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PackedStruct)] #[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 { pub struct GcReport {
#[packed_field(size_bits = "8")] #[packed_field(bits = "0..=7")]
pub buttons_1: Buttons1, pub buttons_1: Buttons1,
#[packed_field(size_bits = "8")] #[packed_field(bits = "8..=15")]
pub buttons_2: Buttons2, pub buttons_2: Buttons2,
#[packed_field(size_bits = "8")] #[packed_field(bits = "16..=23")]
pub stick_x: u8, pub stick_x: u8,
#[packed_field(size_bits = "8")] #[packed_field(bits = "24..=31")]
pub stick_y: u8, pub stick_y: u8,
#[packed_field(size_bits = "8")] #[packed_field(bits = "32..=39")]
pub cstick_x: u8, pub cstick_x: u8,
#[packed_field(size_bits = "8")] #[packed_field(bits = "40..=47")]
pub cstick_y: u8, pub cstick_y: u8,
#[packed_field(size_bits = "8")] #[packed_field(bits = "48..=55")]
pub trigger_l: u8, pub trigger_l: u8,
#[packed_field(size_bits = "8")] #[packed_field(bits = "56..=63")]
pub trigger_r: u8, pub trigger_r: u8,
} }
pub struct GcConfig<'a> { pub struct GcConfig<'a> {
interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>, interface: InterfaceConfig<'a, InBytes64, OutNone, ReportSingle>,
} }
impl<'a> GcConfig<'a> { impl<'a> GcConfig<'a> {
#[must_use] #[must_use]
pub fn new(interface: InterfaceConfig<'a, InBytes8, OutNone, ReportSingle>) -> Self { pub fn new(interface: InterfaceConfig<'a, InBytes64, OutNone, ReportSingle>) -> Self {
Self { interface } Self { interface }
} }
} }
@ -146,7 +146,7 @@ impl<'a> Default for GcConfig<'a> {
let i = unwrap!(unwrap!(InterfaceBuilder::new(GCC_REPORT_DESCRIPTOR)) let i = unwrap!(unwrap!(InterfaceBuilder::new(GCC_REPORT_DESCRIPTOR))
.boot_device(InterfaceProtocol::None) .boot_device(InterfaceProtocol::None)
.description("NaxGCC") .description("NaxGCC")
.in_endpoint(10.millis())); .in_endpoint(1.millis()));
Self::new(i.without_out_endpoint().build()) 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> { 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> { impl<'a, B: UsbBus> GcController<'a, B> {
pub fn write_report(&mut self, report: &GcReport) -> Result<(), UsbHidError> { pub fn write_report(&mut self, report: &GcReport) -> Result<(), UsbHidError> {
let report = get_gcinput_hid_report(report); let report = get_gcinput_hid_report(report);
// print report as binary // print report as binary
info!("Report: {:08b}", report); info!("Report: {:08b}", report);
self.interface self.interface
.write_report(&report) .write_report(&report)
.map(|_| ()) .map(|_| ())
.map_err(|e| { .map_err(|e| UsbHidError::from(e))
error!("Found an error: {:?}", e);
UsbHidError::from(e)
})
} }
} }
impl<'a, B: UsbBus> DeviceClass<'a> for GcController<'a, B> { 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 { fn interface(&mut self) -> &mut Self::I {
&mut self.interface &mut self.interface
@ -202,11 +200,10 @@ fn get_gcinput_hid_report(input_state: &GcReport) -> [u8; 37] {
let mut buffer = [0u8; 37]; let mut buffer = [0u8; 37];
buffer[0] = 0x21; buffer[0] = 0x21;
buffer[1] |= 0x14;
let data = input_state.pack().expect("Failed to pack GC input data"); let data = input_state.pack().expect("Failed to pack GC input data");
info!("Packed data: {:08b}", data);
if unsafe { !GC_FIRST } { if unsafe { !GC_FIRST } {
buffer[1] |= 0x04; buffer[1] |= 0x04;
buffer[10] |= 0x04; buffer[10] |= 0x04;

View file

@ -8,6 +8,7 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
mod flash_mem;
mod gcc_hid; mod gcc_hid;
use core::fmt::Write; 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 // Ensure we halt the program on panic (if we don't mention this crate it won't
// be linked) // be linked)
use defmt_rtt as _; use defmt_rtt as _;
use packed_struct::PackedStruct;
use panic_halt as _; use panic_halt as _;
// Alias for our HAL crate // Alias for our HAL crate
@ -33,14 +35,20 @@ use hal::{
}; };
// Some traits we need // 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 rp2040_hal::Clock;
use usb_device::{ use usb_device::{
bus::UsbBusAllocator, bus::UsbBusAllocator,
device::{UsbDeviceBuilder, UsbVidPid}, device::{UsbDeviceBuilder, UsbDeviceState, UsbVidPid},
}; };
use usbd_human_interface_device::{usb_class::UsbHidClassBuilder, UsbHidError}; 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 /// 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. /// 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 /// 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 timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);
let mut poll_timer = timer.count_down(); 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 // The single-cycle I/O block controls our GPIO pins
let sio = hal::Sio::new(pac.SIO); let sio = hal::Sio::new(pac.SIO);
@ -124,23 +132,26 @@ fn main() -> ! {
.max_packet_size_0(64) .max_packet_size_0(64)
.build(); .build();
let mut uart = UartPeripheral::new( gcc_state.stick_x = 0;
pac.UART0, gcc_state.stick_y = 0;
( gcc_state.trigger_l = 21;
pins.gpio0.into_mode::<FunctionUart>(), gcc_state.cstick_x = 127;
pins.gpio1.into_mode(), gcc_state.cstick_y = 127;
),
&mut pac.RESETS,
)
.enable(UartConfig::default(), clocks.peripheral_clock.freq())
.unwrap();
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 // Configure GPIO25 as an output
let mut led_pin = pins.gpio25.into_push_pull_output(); let mut led_pin = pins.gpio25.into_push_pull_output();
info!("Bleg");
let _ = uart.write_str("FLAR");
loop { loop {
if poll_timer.wait().is_ok() { if poll_timer.wait().is_ok() {
match gcc.device().write_report(&gcc_state) { match gcc.device().write_report(&gcc_state) {
@ -153,7 +164,8 @@ fn main() -> ! {
} }
} }
} }
if usb_dev.poll(&mut [&mut gcc]) {} if usb_dev.poll(&mut [&mut gcc]) {}
gcc_state.buttons_2.button_start = btn_pin.is_low().unwrap();
} }
} }