From cbaa4f4ca92ac861e149eeaa56f294369b88837b Mon Sep 17 00:00:00 2001 From: Naxdy Date: Mon, 18 Mar 2024 10:36:47 +0100 Subject: [PATCH] add button mapping, implement SPI, use patched embassy --- .gitignore | 3 +- Cargo.lock | 123 ++++++++++-------------------------------------- Cargo.toml | 32 ++++++++++--- flake.lock | 36 ++++++++++---- flake.nix | 29 ++++++------ src/gcc_hid.rs | 55 ++++++++++++++++------ src/input.rs | 124 ++++++++++++++++++++++++++++++++++++------------- src/main.rs | 65 +++++++++++++++++++++++--- 8 files changed, 289 insertions(+), 178 deletions(-) diff --git a/.gitignore b/.gitignore index 0a44818..bf7fc90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /result -/.direnv \ No newline at end of file +/.direnv +/lib \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 146524f..e077a95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" dependencies = [ - "rustc_version 0.2.3", + "rustc_version", ] [[package]] @@ -310,12 +310,10 @@ checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "embassy-embedded-hal" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca4a9380d03e61063067b8239f67d2fa9f108ede7c46b4273804f6b79e59a1d" dependencies = [ "defmt", "embassy-futures", - "embassy-sync 0.5.0", + "embassy-sync", "embassy-time", "embedded-hal 0.2.7", "embedded-hal 1.0.0", @@ -328,8 +326,6 @@ dependencies = [ [[package]] name = "embassy-executor" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec648daedd2143466eff4b3e8002024f9f6c1de4ab7666bb679688752624c925" dependencies = [ "cortex-m", "critical-section", @@ -342,9 +338,7 @@ dependencies = [ [[package]] name = "embassy-executor-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad454accf80050e9cf7a51e994132ba0e56286b31f9317b68703897c328c59b5" +version = "0.4.0" dependencies = [ "darling", "proc-macro2", @@ -355,14 +349,13 @@ dependencies = [ [[package]] name = "embassy-futures" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" +dependencies = [ + "defmt", +] [[package]] name = "embassy-hal-internal" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ec47cf8bab914018d4bd2b4f0aaeb46e4f52ab1e7985df88aeef2c6eda5aed" dependencies = [ "cortex-m", "critical-section", @@ -373,25 +366,19 @@ dependencies = [ [[package]] name = "embassy-net-driver" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" [[package]] name = "embassy-net-driver-channel" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "584ab4da7e5612efaa7d55ee76161d9549adf788eab48d49362eddbf322f9933" dependencies = [ "embassy-futures", "embassy-net-driver", - "embassy-sync 0.3.0", + "embassy-sync", ] [[package]] name = "embassy-rp" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438f170cbd97d4a870e8d57e1738ee815255028ad31dd409d891e2bf797dc531" dependencies = [ "atomic-polyfill", "cfg-if", @@ -403,7 +390,7 @@ dependencies = [ "embassy-embedded-hal", "embassy-futures", "embassy-hal-internal", - "embassy-sync 0.5.0", + "embassy-sync", "embassy-time", "embassy-time-driver", "embassy-usb-driver", @@ -425,37 +412,21 @@ dependencies = [ "rp2040-boot2", ] -[[package]] -name = "embassy-sync" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0525b466ca3ace30b57f2db868a35215dfaecd038d8668cb2db03feb7c069a0" -dependencies = [ - "cfg-if", - "critical-section", - "futures-util", - "heapless 0.7.17", -] - [[package]] name = "embassy-sync" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" dependencies = [ "cfg-if", "critical-section", "defmt", "embedded-io-async", "futures-util", - "heapless 0.8.0", + "heapless", ] [[package]] name = "embassy-time" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c844070d9f80dc66ee739299183312baee2e1cdeb6e90b4ea2af44f4676da5" dependencies = [ "cfg-if", "critical-section", @@ -467,14 +438,12 @@ dependencies = [ "embedded-hal 1.0.0", "embedded-hal-async", "futures-util", - "heapless 0.8.0", + "heapless", ] [[package]] name = "embassy-time-driver" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" dependencies = [ "document-features", ] @@ -482,21 +451,17 @@ dependencies = [ [[package]] name = "embassy-time-queue-driver" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" [[package]] name = "embassy-usb" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1587e58ed8f7e0215246e6bb8d7ef4837db682e209e5ef7410a81c500dc949e5" dependencies = [ "defmt", "embassy-futures", "embassy-net-driver-channel", - "embassy-sync 0.5.0", + "embassy-sync", "embassy-usb-driver", - "heapless 0.8.0", + "heapless", "ssmarshal", "usbd-hid", ] @@ -504,8 +469,6 @@ dependencies = [ [[package]] name = "embassy-usb-driver" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" dependencies = [ "defmt", ] @@ -761,15 +724,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hash32" version = "0.3.1" @@ -785,26 +739,13 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -[[package]] -name = "heapless" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" -dependencies = [ - "atomic-polyfill", - "hash32 0.2.1", - "rustc_version 0.4.0", - "spin", - "stable_deref_trait", -] - [[package]] name = "heapless" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ - "hash32 0.3.1", + "hash32", "stable_deref_trait", ] @@ -938,7 +879,7 @@ dependencies = [ "embassy-executor", "embassy-futures", "embassy-rp", - "embassy-sync 0.5.0", + "embassy-sync", "embassy-time", "embassy-usb", "fixed", @@ -947,6 +888,7 @@ dependencies = [ "packed_struct", "panic-probe", "portable-atomic", + "rand", "static_cell", ] @@ -1200,6 +1142,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -1286,16 +1237,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.22", + "semver", ] [[package]] @@ -1319,12 +1261,6 @@ dependencies = [ "semver-parser", ] -[[package]] -name = "semver" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" - [[package]] name = "semver-parser" version = "0.7.0" @@ -1363,15 +1299,6 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "ssmarshal" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 1720616..9755d54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,13 @@ edition = "2021" embassy-time = { version = "0.3.0", features = [ "defmt", "defmt-timestamp-uptime", -] } -embassy-embedded-hal = { version = "0.1.0", features = ["defmt"] } -embassy-sync = { version = "0.5.0", features = ["defmt"] } +], path = "lib/embassy-rs/embassy-time" } +embassy-embedded-hal = { version = "0.1.0", features = [ + "defmt", +], path = "lib/embassy-rs/embassy-embedded-hal" } +embassy-sync = { version = "0.5.0", features = [ + "defmt", +], path = "lib/embassy-rs/embassy-sync" } embassy-executor = { version = "0.5.0", features = [ "task-arena-size-32768", "arch-cortex-m", @@ -19,15 +23,19 @@ embassy-executor = { version = "0.5.0", features = [ "executor-interrupt", "defmt", "integrated-timers", -] } +], path = "lib/embassy-rs/embassy-executor" } embassy-rp = { version = "0.1.0", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", -] } -embassy-usb = { version = "0.1.0", features = ["defmt"] } -embassy-futures = { version = "0.1.0" } +], path = "lib/embassy-rs/embassy-rp" } +embassy-usb = { version = "0.1.0", features = [ + "defmt", +], path = "lib/embassy-rs/embassy-usb" } +embassy-futures = { version = "0.1.0", features = [ + "defmt", +], path = "lib/embassy-rs/embassy-futures" } defmt = "0.3" defmt-rtt = "0.4" fixed = "1.23.1" @@ -41,6 +49,7 @@ cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } packed_struct = { version = "0.10.1", default_features = false } format_no_std = "1.0.2" +rand = { version = "0.8.5", default-features = false } # cargo build/run [profile.dev] @@ -93,3 +102,12 @@ debug-assertions = false incremental = false lto = 'fat' opt-level = 3 + +# [patch.crates-io] +# embassy-rp = { path = "lib/embassy-rs/embassy-rp" } +# embassy-time = { path = "lib/embassy-rs/embassy-time" } +# embassy-embedded-hal = { path = "lib/embassy-rs/embassy-embedded-hal" } +# embassy-usb = { path = "lib/embassy-rs/embassy-usb" } +# embassy-sync = { path = "lib/embassy-rs/embassy-sync" } +# embassy-executor = { path = "lib/embassy-rs/embassy-executor" } +# embassy-futures = { path = "lib/embassy-rs/embassy-futures" } diff --git a/flake.lock b/flake.lock index 131a342..9aab42d 100644 --- a/flake.lock +++ b/flake.lock @@ -1,15 +1,32 @@ { "nodes": { + "embassy-rs-patched": { + "flake": false, + "locked": { + "lastModified": 1710754402, + "narHash": "sha256-HyTw5VQXlSqz9UOq0Dc6G/NWNzQOPXf3PNWffMkfLC4=", + "owner": "Naxdy", + "repo": "embassy", + "rev": "2ee4657727b9679998d941de00b43e1754f570bf", + "type": "github" + }, + "original": { + "owner": "Naxdy", + "ref": "naxgcc-fw", + "repo": "embassy", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1709126324, - "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -58,11 +75,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1709309926, - "narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=", + "lastModified": 1710283656, + "narHash": "sha256-nI+AOy4uK6jLGBi9nsbHjL1EdSIzoo8oa+9oeVhbyFc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", + "rev": "51063ed4f2343a59fdeebb279bb81d87d453942b", "type": "github" }, "original": { @@ -90,6 +107,7 @@ }, "root": { "inputs": { + "embassy-rs-patched": "embassy-rs-patched", "flake-utils": "flake-utils", "naersk": "naersk", "nixpkgs": "nixpkgs", @@ -102,11 +120,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1709431943, - "narHash": "sha256-CqTcEJGITB3rfSuAcWC1QZnbVnIipXmIDbZHfxsAy80=", + "lastModified": 1710382258, + "narHash": "sha256-2FW1q+o34VBweYQiEkRaSEkNMq3ecrn83VzETeGiVbY=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "362184acf4a991f27fc222864e94a2e81b3c3c9f", + "rev": "8ce81e71ab04a7e906fae62da086d6ee5d6cfc21", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index b900aff..715afcd 100644 --- a/flake.nix +++ b/flake.nix @@ -8,6 +8,11 @@ flake-utils.url = "github:numtide/flake-utils"; + embassy-rs-patched = { + url = "github:Naxdy/embassy?ref=naxgcc-fw"; + flake = false; + }; + naersk = { url = "github:nmattia/naersk"; inputs.nixpkgs.follows = "nixpkgs"; @@ -20,6 +25,7 @@ , rust-overlay , flake-utils , naersk + , embassy-rs-patched }: (flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { @@ -30,7 +36,7 @@ config.allowUnsupportedSystem = true; }; - rustToolchain = pkgs.rust-bin.nightly.latest.default.override { + rustToolchain = pkgs.rust-bin.stable.latest.default.override { extensions = [ "rust-src" ]; @@ -46,14 +52,11 @@ CARGO_BUILD_TARGET = "thumbv6m-none-eabi"; - # RUSTFLAGS = [ - # "-Clinker=flip-link" - # "-Clink-arg=--nmagic" - # "-Clink-arg=-Tlink.x" - # "-Clink-arg=-Tdefmt.x" - # "-Cinline-threshold=5" - # "-Cno-vectorize-loops" - # ]; + prepCmd = '' + mkdir -p lib + rm lib/embassy-rs || true + ln -s "${embassy-rs-patched}" lib/embassy-rs + ''; in { packages.default = self.packages.${system}.naxgcc-fw-uf2; @@ -67,9 +70,7 @@ pname = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.name; version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version; - nativeBuildInputs = [ - pkgs.flip-link - ]; + prePatch = prepCmd; src = self; @@ -83,13 +84,15 @@ devShells.default = pkgs.mkShell { nativeBuildInputs = builtins.attrValues { inherit rustToolchain; - inherit (pkgs) gcc-arm-embedded flip-link elf2uf2-rs picotool probe-rs cargo-expand; + inherit (pkgs) gcc-arm-embedded elf2uf2-rs picotool probe-rs cargo-expand; }; CARGO_TARGET_THUMBV6M_NONE_EABI_RUNNER = "probe-rs run --chip RP2040 --protocol swd"; DEFMT_LOG = "debug"; inherit CARGO_BUILD_TARGET; + + shellHook = prepCmd; }; })); } diff --git a/src/gcc_hid.rs b/src/gcc_hid.rs index 1aec104..4a89147 100644 --- a/src/gcc_hid.rs +++ b/src/gcc_hid.rs @@ -8,7 +8,7 @@ use embassy_futures::{ use embassy_rp::{peripherals::USB, usb::Driver}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::signal::Signal; -use embassy_time::Duration; +use embassy_time::{Duration, Instant}; use embassy_usb::{ class::hid::{HidReaderWriter, ReportId, RequestHandler, State}, control::OutResponse, @@ -17,7 +17,7 @@ use embassy_usb::{ use packed_struct::{derive::PackedStruct, PackedStruct}; use portable_atomic::Ordering; -use crate::input::GCC_STATE; +use crate::input::GCC_SIGNAL; #[rustfmt::skip] pub const GCC_REPORT_DESCRIPTOR: &[u8] = &[ @@ -235,19 +235,43 @@ impl Handler for MyDeviceHandler { } #[embassy_executor::task] -pub async fn usb_transfer_loop(driver: Driver<'static, USB>) { - debug!("Start of config"); +pub async fn usb_transfer_loop(driver: Driver<'static, USB>, raw_serial: [u8; 8]) { + let mut serial_buffer = [0u8; 64]; + + let serial = { + let s = format_no_std::show( + &mut serial_buffer, + format_args!( + "{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}", + raw_serial[0], + raw_serial[1], + raw_serial[2], + raw_serial[3], + raw_serial[4], + raw_serial[5], + raw_serial[6], + raw_serial[7] + ), + ) + .unwrap(); + + info!("Detected flash with unique serial number {}", s); + + s + }; + + trace!("Start of config"); let mut usb_config = embassy_usb::Config::new(0x057e, 0x0337); usb_config.manufacturer = Some("Naxdy"); usb_config.product = Some("NaxGCC"); - usb_config.serial_number = Some("Fleeb"); + usb_config.serial_number = Some(serial); usb_config.max_power = 100; usb_config.max_packet_size_0 = 64; usb_config.device_class = 0; usb_config.device_protocol = 0; - usb_config.self_powered = false; + usb_config.self_powered = true; usb_config.device_sub_class = 0; - usb_config.supports_remote_wakeup = false; + usb_config.supports_remote_wakeup = true; let mut device_descriptor = [0; 256]; let mut config_descriptor = [0; 256]; @@ -275,8 +299,9 @@ pub async fn usb_transfer_loop(driver: Driver<'static, USB>) { let hid_config = embassy_usb::class::hid::Config { report_descriptor: GCC_REPORT_DESCRIPTOR, request_handler: Some(&request_handler), - poll_ms: 1, - max_packet_size: 64, + poll_ms: 8, + max_packet_size_in: 37, + max_packet_size_out: 5, }; let hid = HidReaderWriter::<_, 5, 37>::new(&mut builder, &mut state, hid_config); @@ -294,15 +319,19 @@ pub async fn usb_transfer_loop(driver: Driver<'static, USB>) { let (mut reader, mut writer) = hid.split(); debug!("In here"); - let mut timer = embassy_time::Ticker::every(Duration::from_millis(1)); + let mut lasttime = Instant::now(); let in_fut = async { loop { - let state = unsafe { GCC_STATE.clone() }; + let state = GCC_SIGNAL.wait().await; let report = get_gcinput_hid_report(&state); match writer.write(&report).await { Ok(()) => { trace!("Report Written: {:08b}", report); + let currtime = Instant::now(); + let polltime = currtime.duration_since(lasttime); + trace!("Report written in {}us", polltime.as_micros()); + lasttime = currtime; } Err(e) => warn!("Failed to send report: {:?}", e), } @@ -311,10 +340,10 @@ pub async fn usb_transfer_loop(driver: Driver<'static, USB>) { let out_fut = async { loop { - debug!("Readery loop"); + trace!("Readery loop"); let mut buf = [0u8; 5]; match reader.read(&mut buf).await { - Ok(e) => { + Ok(_e) => { debug!("READ SOMETHIN: {:08b}", buf) } Err(e) => { diff --git a/src/input.rs b/src/input.rs index 94d5d22..de0acb4 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,39 +1,101 @@ use defmt::{debug, info}; -use embassy_rp::{gpio::Input, peripherals::PIN_15, Peripherals}; - -use crate::gcc_hid::{Buttons1, Buttons2, GcReport}; - -pub static mut GCC_STATE: GcReport = GcReport { - buttons_1: Buttons1 { - button_a: false, - button_b: false, - button_x: false, - button_y: false, - dpad_left: false, - dpad_right: false, - dpad_down: false, - dpad_up: false, +use embassy_rp::{ + clocks::RoscRng, + flash::{Async, Flash, ERASE_SIZE}, + gpio::{Input, Output, Pin}, + peripherals::{ + DMA_CH0, FLASH, PIN_10, PIN_11, PIN_15, PIN_16, PIN_17, PIN_18, PIN_19, PIN_20, PIN_21, + PIN_22, PIN_23, PIN_24, PIN_25, PIN_29, PIN_5, PIN_8, PIN_9, SPI0, }, - buttons_2: Buttons2 { - button_start: false, - button_z: false, - button_r: false, - button_l: false, - blank1: 0, - }, - stick_x: 0, - stick_y: 0, - cstick_x: 0, - cstick_y: 0, - trigger_l: 0, - trigger_r: 0, + spi::Spi, }; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal}; +use rand::RngCore; + +use crate::{gcc_hid::GcReport, ADDR_OFFSET, FLASH_SIZE}; + +pub static GCC_SIGNAL: Signal = Signal::new(); + +#[derive(PartialEq, Eq)] +enum Stick { + ControlStick, + CStick, +} + +#[derive(PartialEq, Eq)] +enum StickAxis { + XAxis, + YAxis, +} + +fn read_ext_adc<'a, Acs: Pin, Ccs: Pin>( + which_stick: Stick, + which_axis: StickAxis, + spi: &mut Spi<'a, SPI0, embassy_rp::spi::Blocking>, + spi_acs: &mut Output<'a, Acs>, + spi_ccs: &mut Output<'a, Ccs>, +) -> u16 { + let mut buf = [0b11010000; 3]; + + if which_axis == StickAxis::YAxis { + buf = [0b11110000; 3]; + } + + if which_stick == Stick::CStick { + spi_acs.set_low(); + } else { + spi_ccs.set_low(); + } + + spi.blocking_transfer_in_place(&mut buf).unwrap(); + + let temp_value = + (((buf[0] & 0b00000111) as u16) << 9) | (buf[1] as u16) << 1 | (buf[2] as u16) >> 7; + + if which_stick == Stick::ControlStick { + spi_acs.set_high(); + } else { + spi_ccs.set_high(); + } + + return temp_value; +} #[embassy_executor::task] -pub async fn input_loop(btn_z: Input<'static, PIN_15>) -> ! { +pub async fn input_loop( + mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>, + btn_z: Input<'static, PIN_20>, + btn_a: Input<'static, PIN_17>, + btn_b: Input<'static, PIN_16>, + btn_dright: Input<'static, PIN_11>, + btn_dup: Input<'static, PIN_9>, + btn_ddown: Input<'static, PIN_10>, + btn_dleft: Input<'static, PIN_8>, + btn_l: Input<'static, PIN_22>, + btn_r: Input<'static, PIN_21>, + btn_x: Input<'static, PIN_18>, + btn_y: Input<'static, PIN_19>, + btn_start: Input<'static, PIN_5>, + btn_rumble: Input<'static, PIN_25>, + btn_brake: Input<'static, PIN_29>, + mut spi: Spi<'static, SPI0, embassy_rp::spi::Blocking>, + mut spi_acs: Output<'static, PIN_24>, + mut spi_ccs: Output<'static, PIN_23>, +) -> ! { + let mut gcc_state = GcReport::default(); + + let mut rng = RoscRng; + + let mut uid = [0u8; 1]; + flash.blocking_read(ADDR_OFFSET, &mut uid).unwrap(); + + debug!("Read from flash: {:02X}", uid); + loop { - unsafe { - GCC_STATE.buttons_2.button_z = btn_z.is_low(); - } + gcc_state.buttons_1.button_a = btn_z.is_low(); + gcc_state.stick_x = rng.next_u32() as u8; + gcc_state.stick_y = rng.next_u32() as u8; + + GCC_SIGNAL.signal(gcc_state); } } diff --git a/src/main.rs b/src/main.rs index 33d4a5d..6de22be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,16 +7,17 @@ mod gcc_hid; mod input; -use defmt::info; -use embassy_executor::{Executor, Spawner}; +use defmt::{debug, info}; +use embassy_executor::Executor; use embassy_rp::{ bind_interrupts, + flash::{Async, Flash, ERASE_SIZE}, gpio::{self, Input}, multicore::{spawn_core1, Stack}, peripherals::USB, + spi::{self, Spi}, usb::{Driver, InterruptHandler}, }; -use embassy_time::Timer; use gcc_hid::usb_transfer_loop; use gpio::{Level, Output}; use input::input_loop; @@ -27,27 +28,79 @@ static mut CORE1_STACK: Stack<4096> = Stack::new(); static EXECUTOR0: StaticCell = StaticCell::new(); static EXECUTOR1: StaticCell = StaticCell::new(); +const FLASH_SIZE: usize = 2 * 1024 * 1024; +const ADDR_OFFSET: u32 = 0x100000; + bind_interrupts!(struct Irqs { USBCTRL_IRQ => InterruptHandler; }); #[cortex_m_rt::entry] fn main() -> ! { + info!("Initializing"); + let p = embassy_rp::init(Default::default()); let driver = Driver::new(p.USB, Irqs); - info!("Initializing"); + let mut flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH0); + + let mut uid = [0u8; 8]; + flash.blocking_unique_id(&mut uid).unwrap(); + + flash + .blocking_erase(ADDR_OFFSET, ADDR_OFFSET + ERASE_SIZE as u32) + .unwrap(); + + flash.blocking_write(ADDR_OFFSET, &[0xAB]).unwrap(); + + debug!("Read unique id: {:02X}", uid); spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { let executor1 = EXECUTOR1.init(Executor::new()); - executor1.run(|spawner| spawner.spawn(usb_transfer_loop(driver)).unwrap()); + executor1.run(|spawner| spawner.spawn(usb_transfer_loop(driver, uid)).unwrap()); }); let executor0 = EXECUTOR0.init(Executor::new()); + info!("Initialized."); + + let mosi = p.PIN_7; + let miso = p.PIN_4; + let spi_clk = p.PIN_6; + + let p_acs = p.PIN_24; + let p_ccs = p.PIN_23; + + let mut spi_cfg = spi::Config::default(); + spi_cfg.frequency = 3000 * 1000; + + let spi = Spi::new_blocking(p.SPI0, spi_clk, mosi, miso, spi_cfg); + + let spi_acs = Output::new(p_acs, Level::High); // active low + let spi_ccs = Output::new(p_ccs, Level::High); // active low + executor0.run(|spawner| { spawner - .spawn(input_loop(Input::new(p.PIN_15, gpio::Pull::Up))) + .spawn(input_loop( + flash, + Input::new(p.PIN_20, gpio::Pull::Up), + Input::new(p.PIN_17, gpio::Pull::Up), + Input::new(p.PIN_16, gpio::Pull::Up), + Input::new(p.PIN_11, gpio::Pull::Up), + Input::new(p.PIN_9, gpio::Pull::Up), + Input::new(p.PIN_10, gpio::Pull::Up), + Input::new(p.PIN_8, gpio::Pull::Up), + Input::new(p.PIN_22, gpio::Pull::Up), + Input::new(p.PIN_21, gpio::Pull::Up), + Input::new(p.PIN_18, gpio::Pull::Up), + Input::new(p.PIN_19, gpio::Pull::Up), + Input::new(p.PIN_5, gpio::Pull::Up), + Input::new(p.PIN_25, gpio::Pull::Up), + Input::new(p.PIN_29, gpio::Pull::Up), + spi, + spi_acs, + spi_ccs, + )) .unwrap() }); }