Working with USB HID Joystick
Signed-off-by: fly <merspieler@alwaysdata.com>
This commit is contained in:
parent
2e4fad6b4f
commit
15b21f6f32
2 changed files with 33 additions and 51 deletions
8
firmware/Cargo.lock
generated
8
firmware/Cargo.lock
generated
|
@ -305,9 +305,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -338,9 +338,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
|
|
|
@ -8,19 +8,20 @@ use panic_halt as _;
|
|||
|
||||
use cortex_m_rt::entry;
|
||||
use cortex_m::asm::delay;
|
||||
use stm32f1xx_hal::{adc, pac, prelude::*, timer::{Channel, Tim2NoRemap, Timer}, gpio::{Analog}};
|
||||
use stm32f1xx_hal::{adc, pac, prelude::*, timer::{Channel, Tim2NoRemap}, gpio::{Analog, Pin}};
|
||||
|
||||
use stm32f1xx_hal::usb::{Peripheral, UsbBus};
|
||||
use usb_device::prelude::*;
|
||||
use usbd_human_interface_device::device::consumer::MultipleConsumerReport;
|
||||
use usbd_human_interface_device::device::joystick::JoystickReport;
|
||||
use usbd_human_interface_device::prelude::*;
|
||||
use usbd_human_interface_device::page::Consumer;
|
||||
|
||||
struct MyPins { pa1: Pin<'A', 1, Analog>, pa2: Pin<'A', 2, Analog> }
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
// ====================== general setup =================
|
||||
// Acquire peripherals
|
||||
let cp = cortex_m::Peripherals::take().unwrap();
|
||||
// let cp = cortex_m::Peripherals::take().unwrap();
|
||||
let p = pac::Peripherals::take().unwrap();
|
||||
let mut flash = p.FLASH.constrain();
|
||||
let rcc = p.RCC.constrain();
|
||||
|
@ -50,12 +51,12 @@ fn main() -> ! {
|
|||
let usb_bus = UsbBus::new(usb);
|
||||
|
||||
let mut consumer = UsbHidClassBuilder::new()
|
||||
.add_device(usbd_human_interface_device::device::consumer::ConsumerControlConfig::default())
|
||||
.add_device(usbd_human_interface_device::device::joystick::JoystickConfig::default())
|
||||
.build(&usb_bus);
|
||||
|
||||
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
||||
.manufacturer("FLC Meow")
|
||||
.product("Serial port")
|
||||
.product("Pedestal box")
|
||||
.serial_number("01189998819991197253")
|
||||
.build();
|
||||
|
||||
|
@ -64,38 +65,30 @@ fn main() -> ! {
|
|||
let mut adc1 = adc::Adc::adc1(p.ADC1, clocks);
|
||||
|
||||
// ====================== Pin setup =================
|
||||
let input_pins: [&dyn ErasedPin<Analog>; 2] = [
|
||||
&gpioa.pa1.into_analog(&mut gpioa.crl),
|
||||
&gpioa.pa2.into_analog(&mut gpioa.crl)
|
||||
];
|
||||
let mut input_pins = MyPins {
|
||||
pa1: gpioa.pa1.into_analog(&mut gpioa.crl),
|
||||
pa2: gpioa.pa2.into_analog(&mut gpioa.crl)
|
||||
};
|
||||
|
||||
let mut last = get_report(&input_pins);
|
||||
let mut last = get_report(&mut input_pins, &mut adc1);
|
||||
|
||||
// ====================== PWM setup =================
|
||||
let mut afio = p.AFIO.constrain();
|
||||
let c1 = gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl);
|
||||
let mut pwm = p.TIM2.pwm_hz::<Tim2NoRemap, _, _>(c1, &mut afio.mapr, 1.kHz(), &clocks);
|
||||
pwm.enable(Channel::C1);
|
||||
let pwm_max = pwm.get_max_duty() as u16; //48000 in our case
|
||||
|
||||
// ====================== Timer setup =================
|
||||
let timer = Timer::new(pwm, &mut clocks);
|
||||
let mut input_count_down = timer.count_down();
|
||||
input_count_down.start(50.millis());
|
||||
// let pwm_max = pwm.get_max_duty() as u16; //48000 in our case
|
||||
|
||||
loop {
|
||||
//Poll the every 10ms
|
||||
if input_count_down.wait().is_ok() {
|
||||
let report = get_report(&input_pins);
|
||||
if report != last {
|
||||
match consumer.device().write_report(&report) {
|
||||
Err(UsbError::WouldBlock) => {}
|
||||
Ok(_) => {
|
||||
last = report;
|
||||
}
|
||||
Err(e) => {
|
||||
core::panic!("Failed to write consumer report: {:?}", e)
|
||||
}
|
||||
let report = get_report(&mut input_pins, &mut adc1);
|
||||
if report != last {
|
||||
match consumer.device().write_report(&report) {
|
||||
Err(UsbHidError::WouldBlock) => {}
|
||||
Ok(_) => {
|
||||
last = report;
|
||||
}
|
||||
Err(e) => {
|
||||
core::panic!("Failed to write consumer report: {:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,25 +107,14 @@ fn main() -> ! {
|
|||
}
|
||||
}
|
||||
fn get_report(
|
||||
pins: &[&dyn InputPin<Error = core::convert::Infallible>; 2],
|
||||
) -> MultipleConsumerReport {
|
||||
#[rustfmt::skip]
|
||||
let pins = [
|
||||
// pins[0].is_low().unwrap() { Consumer::PlayPause } else { Consumer::Unassigned },
|
||||
// pins[1].is_low().unwrap() { Consumer::ScanPreviousTrack } else { Consumer::Unassigned },
|
||||
];
|
||||
pins: &mut MyPins,
|
||||
adc1: &mut adc::Adc<pac::ADC1>,
|
||||
) -> JoystickReport {
|
||||
|
||||
let mut report = MultipleConsumerReport {
|
||||
codes: [Consumer::Unassigned; 4],
|
||||
};
|
||||
let integLT: u16 = adc1.read(&mut pins.pa1).unwrap();
|
||||
let floodLT: u16 = adc1.read(&mut pins.pa2).unwrap();
|
||||
let buttons: u8 = 0;
|
||||
|
||||
let mut it = pins.iter().filter(|&&c| c != Consumer::Unassigned);
|
||||
for c in report.codes.iter_mut() {
|
||||
if let Some(&code) = it.next() {
|
||||
*c = code;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let report = JoystickReport {x: (integLT / 16) as i8, y: (floodLT / 16) as i8, buttons};
|
||||
report
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue