2024-03-12 00:08:34 +01:00
|
|
|
//! This example test the RP Pico on board LED.
|
2024-03-03 16:31:37 +01:00
|
|
|
//!
|
2024-03-12 00:08:34 +01:00
|
|
|
//! It does not work with the RP Pico W board. See wifi_blinky.rs.
|
2024-03-03 16:31:37 +01:00
|
|
|
|
|
|
|
#![no_std]
|
|
|
|
#![no_main]
|
2024-03-27 19:34:14 +01:00
|
|
|
mod config;
|
2024-03-22 21:38:10 +01:00
|
|
|
mod filter;
|
2024-03-04 00:39:12 +01:00
|
|
|
mod gcc_hid;
|
2024-03-27 21:20:25 +01:00
|
|
|
mod helpers;
|
2024-03-11 17:17:40 +01:00
|
|
|
mod input;
|
2024-04-03 19:44:02 +00:00
|
|
|
mod input_filter;
|
2024-03-19 21:06:18 +01:00
|
|
|
mod stick;
|
2024-03-04 00:39:12 +01:00
|
|
|
|
2024-03-29 16:07:44 +01:00
|
|
|
use config::config_task;
|
2024-03-27 18:11:23 +01:00
|
|
|
use defmt::{debug, info};
|
2024-03-18 10:36:47 +01:00
|
|
|
use embassy_executor::Executor;
|
2024-03-12 00:08:34 +01:00
|
|
|
use embassy_rp::{
|
|
|
|
bind_interrupts,
|
2024-03-26 23:09:38 +01:00
|
|
|
flash::{Async, Flash},
|
2024-03-28 18:12:02 +01:00
|
|
|
gpio::{self, AnyPin, Input},
|
2024-03-12 00:08:34 +01:00
|
|
|
multicore::{spawn_core1, Stack},
|
2024-04-03 17:17:21 +02:00
|
|
|
peripherals::USB,
|
2024-03-18 10:36:47 +01:00
|
|
|
spi::{self, Spi},
|
2024-03-12 00:08:34 +01:00
|
|
|
usb::{Driver, InterruptHandler},
|
2024-03-04 00:39:12 +01:00
|
|
|
};
|
2024-03-28 22:43:44 +01:00
|
|
|
use gcc_hid::usb_transfer_task;
|
2024-03-12 00:08:34 +01:00
|
|
|
use gpio::{Level, Output};
|
2024-03-27 18:11:23 +01:00
|
|
|
|
2024-03-28 22:43:44 +01:00
|
|
|
use input::{update_button_state_task, update_stick_states_task};
|
2024-03-12 00:08:34 +01:00
|
|
|
use static_cell::StaticCell;
|
2024-03-28 22:43:44 +01:00
|
|
|
|
2024-04-02 22:17:50 +02:00
|
|
|
use crate::config::enter_config_mode_task;
|
|
|
|
use crate::gcc_hid::rumble_task;
|
2024-04-01 21:06:41 +02:00
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
use {defmt_rtt as _, panic_probe as _};
|
2024-03-03 16:31:37 +01:00
|
|
|
|
2024-03-11 17:17:40 +01:00
|
|
|
static mut CORE1_STACK: Stack<4096> = Stack::new();
|
2024-03-12 00:08:34 +01:00
|
|
|
static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
|
|
|
|
static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
|
2024-03-05 08:11:49 +01:00
|
|
|
|
2024-03-18 10:36:47 +01:00
|
|
|
const FLASH_SIZE: usize = 2 * 1024 * 1024;
|
|
|
|
const ADDR_OFFSET: u32 = 0x100000;
|
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
bind_interrupts!(struct Irqs {
|
|
|
|
USBCTRL_IRQ => InterruptHandler<USB>;
|
|
|
|
});
|
2024-03-11 19:41:34 +01:00
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
#[cortex_m_rt::entry]
|
2024-03-03 16:31:37 +01:00
|
|
|
fn main() -> ! {
|
2024-03-18 10:36:47 +01:00
|
|
|
info!("Initializing");
|
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
let p = embassy_rp::init(Default::default());
|
2024-03-03 16:31:37 +01:00
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
let driver = Driver::new(p.USB, Irqs);
|
2024-03-03 16:31:37 +01:00
|
|
|
|
2024-03-28 22:43:44 +01:00
|
|
|
// reading and writing from flash has to be done on the main thread, else funny things happen.
|
|
|
|
|
2024-04-03 14:33:23 +02:00
|
|
|
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();
|
2024-03-18 10:36:47 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2024-03-28 18:12:02 +01:00
|
|
|
let spi_acs = Output::new(AnyPin::from(p_acs), Level::High); // active low
|
|
|
|
let spi_ccs = Output::new(AnyPin::from(p_ccs), Level::High); // active low
|
2024-03-18 10:36:47 +01:00
|
|
|
|
2024-03-28 22:43:44 +01:00
|
|
|
spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
|
|
|
|
let executor1 = EXECUTOR1.init(Executor::new());
|
|
|
|
debug!("Mana");
|
|
|
|
executor1.run(|spawner| {
|
2024-04-03 14:33:23 +02:00
|
|
|
spawner.spawn(usb_transfer_task(uid, driver)).unwrap();
|
2024-04-02 22:17:50 +02:00
|
|
|
spawner.spawn(enter_config_mode_task()).unwrap();
|
2024-04-03 16:16:55 +02:00
|
|
|
spawner
|
|
|
|
.spawn(rumble_task(p.PIN_25, p.PIN_29, p.PWM_CH4, p.PWM_CH6))
|
|
|
|
.unwrap();
|
2024-04-01 21:06:41 +02:00
|
|
|
// spawner.spawn(input_integrity_benchmark()).unwrap();
|
2024-03-28 22:43:44 +01:00
|
|
|
spawner
|
|
|
|
.spawn(update_button_state_task(
|
|
|
|
Input::new(AnyPin::from(p.PIN_20), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_17), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_16), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_11), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_9), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_10), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_8), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_22), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_21), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_18), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_19), gpio::Pull::Up),
|
|
|
|
Input::new(AnyPin::from(p.PIN_5), gpio::Pull::Up),
|
|
|
|
))
|
|
|
|
.unwrap()
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-03-30 13:20:35 +01:00
|
|
|
let executor0 = EXECUTOR0.init(Executor::new());
|
|
|
|
info!("Initialized.");
|
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
executor0.run(|spawner| {
|
2024-03-29 19:54:52 +01:00
|
|
|
// Config task has to run on core0 because it reads and writes to flash.
|
2024-04-03 14:33:23 +02:00
|
|
|
spawner.spawn(config_task(flash)).unwrap();
|
2024-03-29 19:54:52 +01:00
|
|
|
|
2024-03-12 00:08:34 +01:00
|
|
|
spawner
|
2024-04-03 14:33:23 +02:00
|
|
|
.spawn(update_stick_states_task(spi, spi_acs, spi_ccs))
|
2024-03-30 13:20:35 +01:00
|
|
|
.unwrap();
|
2024-03-11 17:17:40 +01:00
|
|
|
});
|
2024-03-03 16:31:37 +01:00
|
|
|
}
|