Chaged to 24 HID buttons
This commit is contained in:
parent
30e640625a
commit
8c952f26ed
@ -1,10 +1,10 @@
|
|||||||
//! Project: CMtec CMDR Keyboard 42
|
//! Project: CMtec CMDR joystick 24
|
||||||
//! Date: 2023-07-01
|
//! Date: 2023-08-01
|
||||||
//! Author: Christoffer Martinsson
|
//! Author: Christoffer Martinsson
|
||||||
//! Email: cm@cmtec.se
|
//! Email: cm@cmtec.se
|
||||||
//! License: Please refer to LICENSE in root directory
|
//! License: Please refer to LICENSE in root directory
|
||||||
|
|
||||||
use crate::NUMBER_OF_KEYS;
|
use crate::NUMBER_OF_BUTTONS;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub enum ButtonType {
|
pub enum ButtonType {
|
||||||
@ -24,31 +24,35 @@ pub enum ButtonType {
|
|||||||
B14 = 13,
|
B14 = 13,
|
||||||
B15 = 14,
|
B15 = 14,
|
||||||
B16 = 15,
|
B16 = 15,
|
||||||
FnL = 16,
|
B17 = 16,
|
||||||
FnR = 17,
|
B18 = 17,
|
||||||
ModeL = 18,
|
B19 = 18,
|
||||||
ModeR = 19,
|
B20 = 19,
|
||||||
Hat1U = 20,
|
FnL = 20,
|
||||||
Hat1R = 21,
|
FnR = 21,
|
||||||
Hat1D = 22,
|
ModeL = 22,
|
||||||
Hat1L = 23,
|
ModeR = 23,
|
||||||
Hat1B = 24,
|
Hat1U = 24,
|
||||||
Hat2U = 25,
|
Hat1R = 25,
|
||||||
Hat2R = 26,
|
Hat1D = 26,
|
||||||
Hat2D = 27,
|
Hat1L = 27,
|
||||||
Hat2L = 28,
|
Hat1B = 28,
|
||||||
Hat2B = 29,
|
Hat2U = 29,
|
||||||
Hat3U = 30,
|
Hat2R = 30,
|
||||||
Hat3R = 31,
|
Hat2D = 31,
|
||||||
Hat3D = 32,
|
Hat2L = 32,
|
||||||
Hat3L = 33,
|
Hat2B = 33,
|
||||||
Hat3B = 34,
|
Hat3U = 34,
|
||||||
Hat4U = 35,
|
Hat3R = 35,
|
||||||
Hat4R = 36,
|
Hat3D = 36,
|
||||||
Hat4D = 37,
|
Hat3L = 37,
|
||||||
Hat4L = 38,
|
Hat3B = 38,
|
||||||
Hat4B = 39,
|
Hat4U = 39,
|
||||||
NoEventIndicated = 40,
|
Hat4R = 40,
|
||||||
|
Hat4D = 41,
|
||||||
|
Hat4L = 42,
|
||||||
|
Hat4B = 43,
|
||||||
|
NoEventIndicated = 44,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button index map:
|
// Button index map:
|
||||||
@ -56,16 +60,19 @@ pub enum ButtonType {
|
|||||||
// | 0 | 1 | | 2 | 3 | (4)
|
// | 0 | 1 | | 2 | 3 | (4)
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
// | | 5 | 6 | 7 | | 12 | 11 | 10 | |
|
// | | 5 | 6 | 7 | | 12 | 11 | 10 | |
|
||||||
// | | (9) (14)
|
// | |
|
||||||
// | | 8 | | 13 | |
|
// | | 8 | | 13 | |
|
||||||
|
// | | 9 | | 14 | |
|
||||||
// | X1/Y1 X2/Y2 |
|
// | X1/Y1 X2/Y2 |
|
||||||
// | | 16 | | 21 | |
|
// | | 16 | | 21 | |
|
||||||
// | | 17 | 15 | 18 || 22 | 20 | 23 | |
|
// | | 17 | 15 | 18 || 22 | 20 | 23 | |
|
||||||
// | | 19 | | 24 | |
|
// | | 19 | | 24 | |
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
//
|
//
|
||||||
/// Button map to HID key (three Function layers)
|
/// Button map to HID key (four function layers)
|
||||||
pub const MAP: [[ButtonType; NUMBER_OF_KEYS]; 4] = [
|
/// Please make sure to set FnL, FnR, ModeL and ModeR at the same position for all layers
|
||||||
|
/// alt. only set these at function layer 0 and set NoEventIndicated in layer 1-3.
|
||||||
|
pub const MAP: [[ButtonType; NUMBER_OF_BUTTONS]; 4] = [
|
||||||
[
|
[
|
||||||
// Function layer 0
|
// Function layer 0
|
||||||
// HID Key // Button Index
|
// HID Key // Button Index
|
||||||
@ -74,17 +81,17 @@ pub const MAP: [[ButtonType; NUMBER_OF_KEYS]; 4] = [
|
|||||||
ButtonType::B1, // 1
|
ButtonType::B1, // 1
|
||||||
ButtonType::B5, // 2
|
ButtonType::B5, // 2
|
||||||
ButtonType::FnR, // 3
|
ButtonType::FnR, // 3
|
||||||
ButtonType::NoEventIndicated, // 4
|
ButtonType::NoEventIndicated, // 4 Not connected to any button
|
||||||
ButtonType::B2, // 5
|
ButtonType::B2, // 5
|
||||||
ButtonType::B3, // 6
|
ButtonType::B3, // 6
|
||||||
ButtonType::ModeL, // 7
|
ButtonType::ModeL, // 7
|
||||||
ButtonType::B4, // 8
|
ButtonType::B4, // 8
|
||||||
ButtonType::NoEventIndicated, // 9
|
ButtonType::B17, // 9
|
||||||
ButtonType::B6, // 10
|
ButtonType::B6, // 10
|
||||||
ButtonType::B7, // 11
|
ButtonType::B7, // 11
|
||||||
ButtonType::ModeR, // 12
|
ButtonType::ModeR, // 12
|
||||||
ButtonType::B8, // 13
|
ButtonType::B8, // 13
|
||||||
ButtonType::NoEventIndicated, // 14
|
ButtonType::B18, // 14
|
||||||
ButtonType::Hat1B, // 15
|
ButtonType::Hat1B, // 15
|
||||||
ButtonType::Hat1U, // 16
|
ButtonType::Hat1U, // 16
|
||||||
ButtonType::Hat1L, // 17
|
ButtonType::Hat1L, // 17
|
||||||
@ -97,24 +104,24 @@ pub const MAP: [[ButtonType; NUMBER_OF_KEYS]; 4] = [
|
|||||||
ButtonType::Hat2D, // 24
|
ButtonType::Hat2D, // 24
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// Function layer left
|
// Function layer 1 (left Fn button pressed)
|
||||||
// HID Key // Button Index
|
// HID Key // Button Index
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
ButtonType::FnL, // 0
|
ButtonType::FnL, // 0
|
||||||
ButtonType::B9, // 1
|
ButtonType::B9, // 1
|
||||||
ButtonType::B5, // 2
|
ButtonType::B5, // 2
|
||||||
ButtonType::FnR, // 3
|
ButtonType::FnR, // 3
|
||||||
ButtonType::NoEventIndicated, // 4
|
ButtonType::NoEventIndicated, // 4 Not connected to any button
|
||||||
ButtonType::B10, // 5
|
ButtonType::B10, // 5
|
||||||
ButtonType::B11, // 6
|
ButtonType::B11, // 6
|
||||||
ButtonType::ModeL, // 7
|
ButtonType::ModeL, // 7
|
||||||
ButtonType::B12, // 8
|
ButtonType::B12, // 8
|
||||||
ButtonType::NoEventIndicated, // 9
|
ButtonType::B19, // 9
|
||||||
ButtonType::B6, // 10
|
ButtonType::B6, // 10
|
||||||
ButtonType::B7, // 11
|
ButtonType::B7, // 11
|
||||||
ButtonType::ModeR, // 12
|
ButtonType::ModeR, // 12
|
||||||
ButtonType::B8, // 13
|
ButtonType::B8, // 13
|
||||||
ButtonType::NoEventIndicated, // 14
|
ButtonType::B18, // 14
|
||||||
ButtonType::Hat3B, // 15
|
ButtonType::Hat3B, // 15
|
||||||
ButtonType::Hat3U, // 16
|
ButtonType::Hat3U, // 16
|
||||||
ButtonType::Hat3L, // 17
|
ButtonType::Hat3L, // 17
|
||||||
@ -127,24 +134,24 @@ pub const MAP: [[ButtonType; NUMBER_OF_KEYS]; 4] = [
|
|||||||
ButtonType::Hat2D, // 24
|
ButtonType::Hat2D, // 24
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// Function layer right
|
// Function layer 2 (right Fn button pressed)
|
||||||
// HID Key // Button Index
|
// HID Key // Button Index
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
ButtonType::FnL, // 0
|
ButtonType::FnL, // 0
|
||||||
ButtonType::B1, // 1
|
ButtonType::B1, // 1
|
||||||
ButtonType::B13, // 2
|
ButtonType::B13, // 2
|
||||||
ButtonType::FnR, // 3
|
ButtonType::FnR, // 3
|
||||||
ButtonType::NoEventIndicated, // 4
|
ButtonType::NoEventIndicated, // 4 Not connected to any button
|
||||||
ButtonType::B2, // 5
|
ButtonType::B2, // 5
|
||||||
ButtonType::B3, // 6
|
ButtonType::B3, // 6
|
||||||
ButtonType::ModeL, // 7
|
ButtonType::ModeL, // 7
|
||||||
ButtonType::B4, // 8
|
ButtonType::B4, // 8
|
||||||
ButtonType::NoEventIndicated, // 9
|
ButtonType::B17, // 9
|
||||||
ButtonType::B14, // 10
|
ButtonType::B14, // 10
|
||||||
ButtonType::B15, // 11
|
ButtonType::B15, // 11
|
||||||
ButtonType::ModeR, // 12
|
ButtonType::ModeR, // 12
|
||||||
ButtonType::B16, // 13
|
ButtonType::B16, // 13
|
||||||
ButtonType::NoEventIndicated, // 14
|
ButtonType::B20, // 14
|
||||||
ButtonType::Hat1B, // 15
|
ButtonType::Hat1B, // 15
|
||||||
ButtonType::Hat1U, // 16
|
ButtonType::Hat1U, // 16
|
||||||
ButtonType::Hat1L, // 17
|
ButtonType::Hat1L, // 17
|
||||||
@ -157,24 +164,24 @@ pub const MAP: [[ButtonType; NUMBER_OF_KEYS]; 4] = [
|
|||||||
ButtonType::Hat4D, // 24
|
ButtonType::Hat4D, // 24
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// Function layer left + right
|
// Function layer 3 (left + right Fn button pressed)
|
||||||
// HID Key // Button Index
|
// HID Key // Button Index
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
ButtonType::FnL, // 0
|
ButtonType::FnL, // 0
|
||||||
ButtonType::B9, // 1
|
ButtonType::B9, // 1
|
||||||
ButtonType::B13, // 2
|
ButtonType::B13, // 2
|
||||||
ButtonType::FnR, // 3
|
ButtonType::FnR, // 3
|
||||||
ButtonType::NoEventIndicated, // 4
|
ButtonType::NoEventIndicated, // 4 Not connected to any button
|
||||||
ButtonType::B10, // 5
|
ButtonType::B10, // 5
|
||||||
ButtonType::B11, // 6
|
ButtonType::B11, // 6
|
||||||
ButtonType::ModeL, // 7
|
ButtonType::ModeL, // 7
|
||||||
ButtonType::B12, // 8
|
ButtonType::B12, // 8
|
||||||
ButtonType::NoEventIndicated, // 9
|
ButtonType::B19, // 9
|
||||||
ButtonType::B14, // 10
|
ButtonType::B14, // 10
|
||||||
ButtonType::B15, // 11
|
ButtonType::B15, // 11
|
||||||
ButtonType::ModeR, // 12
|
ButtonType::ModeR, // 12
|
||||||
ButtonType::B16, // 13
|
ButtonType::B16, // 13
|
||||||
ButtonType::NoEventIndicated, // 14
|
ButtonType::B20, // 14
|
||||||
ButtonType::Hat3B, // 15
|
ButtonType::Hat3B, // 15
|
||||||
ButtonType::Hat3U, // 16
|
ButtonType::Hat3U, // 16
|
||||||
ButtonType::Hat3L, // 17
|
ButtonType::Hat3L, // 17
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//! Project: CMtec CMDR Keyboard 42
|
//! Project: CMtec CMDR joystick 24
|
||||||
//! Date: 2023-07-01
|
//! Date: 2023-08-01
|
||||||
//! Author: Christoffer Martinsson
|
//! Author: Christoffer Martinsson
|
||||||
//! Email: cm@cmtec.se
|
//! Email: cm@cmtec.se
|
||||||
//! License: Please refer to LICENSE in root directory
|
//! License: Please refer to LICENSE in root directory
|
||||||
@ -46,9 +46,9 @@ use waveshare_rp2040_zero::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Public constants
|
// Public constants
|
||||||
pub const KEY_ROWS: usize = 5;
|
pub const BUTTON_ROWS: usize = 5;
|
||||||
pub const KEY_COLS: usize = 5;
|
pub const BUTTON_COLS: usize = 5;
|
||||||
pub const NUMBER_OF_KEYS: usize = KEY_ROWS * KEY_COLS;
|
pub const NUMBER_OF_BUTTONS: usize = BUTTON_ROWS * BUTTON_COLS;
|
||||||
|
|
||||||
pub const AXIS_MIN: u16 = 0;
|
pub const AXIS_MIN: u16 = 0;
|
||||||
pub const AXIS_MAX: u16 = 4095;
|
pub const AXIS_MAX: u16 = 4095;
|
||||||
@ -67,7 +67,7 @@ pub const SENSITIVITY: i32 = (0.01 * ((1 << I32_FRAC_BITS) as f32)) as i32;
|
|||||||
|
|
||||||
// Public types
|
// Public types
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
pub struct JoystickButton {
|
pub struct Button {
|
||||||
pub pressed: bool,
|
pub pressed: bool,
|
||||||
pub previous_pressed: bool,
|
pub previous_pressed: bool,
|
||||||
pub fn_mode: u8,
|
pub fn_mode: u8,
|
||||||
@ -138,13 +138,15 @@ fn main() -> ! {
|
|||||||
let mut adc = Adc::new(pac.ADC, &mut pac.RESETS);
|
let mut adc = Adc::new(pac.ADC, &mut pac.RESETS);
|
||||||
|
|
||||||
// Configure ADC input pins
|
// Configure ADC input pins
|
||||||
|
// Have not figured out hov to store the adc pins in an array yet
|
||||||
|
// TODO: Find a way to store adc pins in an array
|
||||||
let mut adc_pin_left_x = pins.gp26.into_floating_input();
|
let mut adc_pin_left_x = pins.gp26.into_floating_input();
|
||||||
let mut adc_pin_left_y = pins.gp27.into_floating_input();
|
let mut adc_pin_left_y = pins.gp27.into_floating_input();
|
||||||
let mut adc_pin_right_x = pins.gp28.into_floating_input();
|
let mut adc_pin_right_x = pins.gp28.into_floating_input();
|
||||||
let mut adc_pin_right_y = pins.gp29.into_floating_input();
|
let mut adc_pin_right_y = pins.gp29.into_floating_input();
|
||||||
|
|
||||||
// Setting up array with pins connected to button rows
|
// Setting up array with pins connected to button rows
|
||||||
let button_matrix_row_pins: &[&dyn InputPin<Error = Infallible>; KEY_ROWS] = &[
|
let button_matrix_row_pins: &[&dyn InputPin<Error = Infallible>; BUTTON_ROWS] = &[
|
||||||
&pins.gp9.into_pull_up_input(),
|
&pins.gp9.into_pull_up_input(),
|
||||||
&pins.gp10.into_pull_up_input(),
|
&pins.gp10.into_pull_up_input(),
|
||||||
&pins.gp11.into_pull_up_input(),
|
&pins.gp11.into_pull_up_input(),
|
||||||
@ -153,7 +155,7 @@ fn main() -> ! {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Setting up array with pins connected to button columns
|
// Setting up array with pins connected to button columns
|
||||||
let button_matrix_col_pins: &mut [&mut dyn OutputPin<Error = Infallible>; KEY_COLS] = &mut [
|
let button_matrix_col_pins: &mut [&mut dyn OutputPin<Error = Infallible>; BUTTON_COLS] = &mut [
|
||||||
&mut pins.gp4.into_push_pull_output(),
|
&mut pins.gp4.into_push_pull_output(),
|
||||||
&mut pins.gp5.into_push_pull_output(),
|
&mut pins.gp5.into_push_pull_output(),
|
||||||
&mut pins.gp6.into_push_pull_output(),
|
&mut pins.gp6.into_push_pull_output(),
|
||||||
@ -161,10 +163,13 @@ fn main() -> ! {
|
|||||||
&mut pins.gp8.into_push_pull_output(),
|
&mut pins.gp8.into_push_pull_output(),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create button matrix object that scans all the PCB buttons
|
// Create button matrix object that scans all buttons
|
||||||
let mut button_matrix: ButtonMatrix<KEY_ROWS, KEY_COLS, NUMBER_OF_KEYS> =
|
let mut button_matrix: ButtonMatrix<BUTTON_ROWS, BUTTON_COLS, NUMBER_OF_BUTTONS> =
|
||||||
ButtonMatrix::new(button_matrix_row_pins, button_matrix_col_pins, 5);
|
ButtonMatrix::new(button_matrix_row_pins, button_matrix_col_pins, 5);
|
||||||
|
|
||||||
|
// Initialize button matrix
|
||||||
|
button_matrix.init_pins();
|
||||||
|
|
||||||
// Configure USB
|
// Configure USB
|
||||||
let usb_bus = UsbBusAllocator::new(waveshare_rp2040_zero::hal::usb::UsbBus::new(
|
let usb_bus = UsbBusAllocator::new(waveshare_rp2040_zero::hal::usb::UsbBus::new(
|
||||||
pac.USBCTRL_REGS,
|
pac.USBCTRL_REGS,
|
||||||
@ -193,9 +198,6 @@ fn main() -> ! {
|
|||||||
clocks.peripheral_clock.freq(),
|
clocks.peripheral_clock.freq(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create joystick button array
|
|
||||||
let mut buttons: [JoystickButton; NUMBER_OF_KEYS] = [JoystickButton::default(); NUMBER_OF_KEYS];
|
|
||||||
|
|
||||||
// Create timers/delays
|
// Create timers/delays
|
||||||
let timer = Timer::new(pac.TIMER, &mut pac.RESETS);
|
let timer = Timer::new(pac.TIMER, &mut pac.RESETS);
|
||||||
let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
||||||
@ -203,8 +205,8 @@ fn main() -> ! {
|
|||||||
let mut usb_hid_report_count_down = timer.count_down();
|
let mut usb_hid_report_count_down = timer.count_down();
|
||||||
usb_hid_report_count_down.start(10.millis());
|
usb_hid_report_count_down.start(10.millis());
|
||||||
|
|
||||||
let mut usb_tick_count_down = timer.count_down();
|
let mut scan_count_down = timer.count_down();
|
||||||
usb_tick_count_down.start(1.millis());
|
scan_count_down.start(1.millis());
|
||||||
|
|
||||||
let mut status_led_count_down = timer.count_down();
|
let mut status_led_count_down = timer.count_down();
|
||||||
status_led_count_down.start(250.millis());
|
status_led_count_down.start(250.millis());
|
||||||
@ -212,8 +214,9 @@ fn main() -> ! {
|
|||||||
// Create variable to track modes
|
// Create variable to track modes
|
||||||
let mut fn_mode: u8 = 0;
|
let mut fn_mode: u8 = 0;
|
||||||
|
|
||||||
// Create joystick axis array
|
// Create joystick button/axis array
|
||||||
let mut axis: [GimbalAxis; NBR_OF_GIMBAL_AXIS] = [Default::default(); NBR_OF_GIMBAL_AXIS];
|
let mut axis: [GimbalAxis; NBR_OF_GIMBAL_AXIS] = [Default::default(); NBR_OF_GIMBAL_AXIS];
|
||||||
|
let mut buttons: [Button; NUMBER_OF_BUTTONS] = [Button::default(); NUMBER_OF_BUTTONS];
|
||||||
|
|
||||||
// Set up left gimbal Y axis as full range without return to center spring
|
// Set up left gimbal Y axis as full range without return to center spring
|
||||||
axis[GIMBAL_AXIS_LEFT_Y].idle_value = AXIS_MIN;
|
axis[GIMBAL_AXIS_LEFT_Y].idle_value = AXIS_MIN;
|
||||||
@ -221,6 +224,7 @@ fn main() -> ! {
|
|||||||
axis[GIMBAL_AXIS_LEFT_Y].expo = 0.0;
|
axis[GIMBAL_AXIS_LEFT_Y].expo = 0.0;
|
||||||
|
|
||||||
// Create dynamic smoother array for gimbal axis
|
// Create dynamic smoother array for gimbal axis
|
||||||
|
// TODO: Find a way to store dynamic smoother in the axis struct
|
||||||
let mut smoother: [DynamicSmootherEcoI32; NBR_OF_GIMBAL_AXIS] = [
|
let mut smoother: [DynamicSmootherEcoI32; NBR_OF_GIMBAL_AXIS] = [
|
||||||
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
||||||
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
||||||
@ -228,9 +232,6 @@ fn main() -> ! {
|
|||||||
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
DynamicSmootherEcoI32::new(BASE_FREQ, SAMPLE_FREQ, SENSITIVITY),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Initialize button matrix
|
|
||||||
button_matrix.init_pins();
|
|
||||||
|
|
||||||
// Scan matrix to get initial state
|
// Scan matrix to get initial state
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
button_matrix.scan_matrix(&mut delay);
|
button_matrix.scan_matrix(&mut delay);
|
||||||
@ -261,7 +262,7 @@ fn main() -> ! {
|
|||||||
match usb_hid_joystick.device().write_report(&get_joystick_report(
|
match usb_hid_joystick.device().write_report(&get_joystick_report(
|
||||||
&mut buttons,
|
&mut buttons,
|
||||||
&mut axis,
|
&mut axis,
|
||||||
fn_mode,
|
&fn_mode,
|
||||||
)) {
|
)) {
|
||||||
Err(UsbHidError::WouldBlock) => {}
|
Err(UsbHidError::WouldBlock) => {}
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
@ -272,16 +273,17 @@ fn main() -> ! {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if usb_tick_count_down.wait().is_ok() {
|
if scan_count_down.wait().is_ok() {
|
||||||
button_matrix.scan_matrix(&mut delay);
|
button_matrix.scan_matrix(&mut delay);
|
||||||
|
|
||||||
// Read ADC values and smooth them
|
// Have not figured out hov to store the adc pins in an array yet
|
||||||
|
// so we have to read them one by one
|
||||||
|
// TODO: Find a way to store adc pins in an array
|
||||||
smoother[GIMBAL_AXIS_LEFT_X].tick(adc.read(&mut adc_pin_left_x).unwrap());
|
smoother[GIMBAL_AXIS_LEFT_X].tick(adc.read(&mut adc_pin_left_x).unwrap());
|
||||||
smoother[GIMBAL_AXIS_LEFT_Y].tick(adc.read(&mut adc_pin_left_y).unwrap());
|
smoother[GIMBAL_AXIS_LEFT_Y].tick(adc.read(&mut adc_pin_left_y).unwrap());
|
||||||
smoother[GIMBAL_AXIS_RIGHT_X].tick(adc.read(&mut adc_pin_right_x).unwrap());
|
smoother[GIMBAL_AXIS_RIGHT_X].tick(adc.read(&mut adc_pin_right_x).unwrap());
|
||||||
smoother[GIMBAL_AXIS_RIGHT_Y].tick(adc.read(&mut adc_pin_right_y).unwrap());
|
smoother[GIMBAL_AXIS_RIGHT_Y].tick(adc.read(&mut adc_pin_right_y).unwrap());
|
||||||
|
|
||||||
// Update axis values
|
|
||||||
for (index, item) in axis.iter_mut().enumerate() {
|
for (index, item) in axis.iter_mut().enumerate() {
|
||||||
item.value = calculate_axis_value(
|
item.value = calculate_axis_value(
|
||||||
smoother[index].value() as u16,
|
smoother[index].value() as u16,
|
||||||
@ -301,8 +303,7 @@ fn main() -> ! {
|
|||||||
/// Update status LED colour based on function layer and capslock
|
/// Update status LED colour based on function layer and capslock
|
||||||
///
|
///
|
||||||
/// Normal = green (NORMAL)
|
/// Normal = green (NORMAL)
|
||||||
/// GUI lock = blue (GUI LOCK)
|
/// Left Alt mode = blue (GUI LOCK)
|
||||||
/// Capslock active = flashing red (WARNING)
|
|
||||||
/// Error = steady red (ERROR)
|
/// Error = steady red (ERROR)
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -328,7 +329,7 @@ where
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `pressed_keys` - Array of pressed keys
|
/// * `pressed_keys` - Array of pressed keys
|
||||||
fn get_mode(pressed_keys: [bool; NUMBER_OF_KEYS]) -> u8 {
|
fn get_mode(pressed_keys: [bool; NUMBER_OF_BUTTONS]) -> u8 {
|
||||||
// Check how many Fn keys are pressed
|
// Check how many Fn keys are pressed
|
||||||
let mut fn_mode: u8 = 0;
|
let mut fn_mode: u8 = 0;
|
||||||
let mut fn_l_active: bool = false;
|
let mut fn_l_active: bool = false;
|
||||||
@ -381,9 +382,9 @@ fn get_mode(pressed_keys: [bool; NUMBER_OF_KEYS]) -> u8 {
|
|||||||
/// * `alt_l_mode` - Is left alt mode active
|
/// * `alt_l_mode` - Is left alt mode active
|
||||||
/// * `alt_r_mode` - Is right alt mode active
|
/// * `alt_r_mode` - Is right alt mode active
|
||||||
fn get_joystick_report(
|
fn get_joystick_report(
|
||||||
matrix_keys: &mut [JoystickButton; NUMBER_OF_KEYS],
|
matrix_keys: &mut [Button; NUMBER_OF_BUTTONS],
|
||||||
axis: &mut [GimbalAxis; 4],
|
axis: &mut [GimbalAxis; 4],
|
||||||
fn_mode: u8,
|
fn_mode: &u8,
|
||||||
) -> JoystickReport {
|
) -> JoystickReport {
|
||||||
let mut x: u16 = axis[GIMBAL_AXIS_RIGHT_X].value;
|
let mut x: u16 = axis[GIMBAL_AXIS_RIGHT_X].value;
|
||||||
let mut y: u16 = axis[GIMBAL_AXIS_RIGHT_Y].value;
|
let mut y: u16 = axis[GIMBAL_AXIS_RIGHT_Y].value;
|
||||||
@ -392,14 +393,15 @@ fn get_joystick_report(
|
|||||||
let mut ry: u16 = AXIS_CENTER;
|
let mut ry: u16 = AXIS_CENTER;
|
||||||
let mut rz: u16 = axis[GIMBAL_AXIS_LEFT_Y].value;
|
let mut rz: u16 = axis[GIMBAL_AXIS_LEFT_Y].value;
|
||||||
|
|
||||||
// Update Fn mode for all axis
|
// Update Fn mode for all axis that are in idle position
|
||||||
|
// This is to avoid the Fn mode switching when moving the gimbal
|
||||||
for item in axis.iter_mut() {
|
for item in axis.iter_mut() {
|
||||||
if item.value == item.idle_value {
|
if item.value == item.idle_value {
|
||||||
item.fn_mode = fn_mode & 0x0F;
|
item.fn_mode = fn_mode & 0x0F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left Alt mode active
|
// Left Alt mode active (bit 4)
|
||||||
// Full range of left gimbal gives half range of joystick axis (center to max)
|
// Full range of left gimbal gives half range of joystick axis (center to max)
|
||||||
// Left Fn mode = reversed range (center to min)
|
// Left Fn mode = reversed range (center to min)
|
||||||
if fn_mode & 0x10 == 0x10
|
if fn_mode & 0x10 == 0x10
|
||||||
@ -424,7 +426,7 @@ fn get_joystick_report(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right Alt mode active
|
// Right Alt mode active (bit 5)
|
||||||
// Right gimbal control third joystick axis when right Fn mode is active
|
// Right gimbal control third joystick axis when right Fn mode is active
|
||||||
if fn_mode & 0x20 == 0x20
|
if fn_mode & 0x20 == 0x20
|
||||||
&& (axis[GIMBAL_AXIS_RIGHT_X].fn_mode == 2 || axis[GIMBAL_AXIS_RIGHT_X].fn_mode == 3)
|
&& (axis[GIMBAL_AXIS_RIGHT_X].fn_mode == 2 || axis[GIMBAL_AXIS_RIGHT_X].fn_mode == 3)
|
||||||
@ -439,12 +441,12 @@ fn get_joystick_report(
|
|||||||
ry = axis[GIMBAL_AXIS_RIGHT_Y].value;
|
ry = axis[GIMBAL_AXIS_RIGHT_Y].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set fn mode for pressed button
|
// Set fn mode for all keys taht are in idle position
|
||||||
|
// This is to avoid the Fn mode switching when using a button
|
||||||
for key in matrix_keys.iter_mut() {
|
for key in matrix_keys.iter_mut() {
|
||||||
if key.pressed != key.previous_pressed && key.pressed {
|
if !key.pressed {
|
||||||
key.fn_mode = fn_mode & 0x0F;
|
key.fn_mode = fn_mode & 0x0F;
|
||||||
}
|
}
|
||||||
key.previous_pressed = key.pressed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate array for all four hat switches with following structure:
|
// Generate array for all four hat switches with following structure:
|
||||||
@ -458,8 +460,10 @@ fn get_joystick_report(
|
|||||||
let mut hats: [u8; 4] = [0; 4];
|
let mut hats: [u8; 4] = [0; 4];
|
||||||
for (index, key) in matrix_keys.iter_mut().enumerate() {
|
for (index, key) in matrix_keys.iter_mut().enumerate() {
|
||||||
if key.pressed
|
if key.pressed
|
||||||
&& layout::MAP[fn_mode as usize][index] as usize >= layout::ButtonType::Hat1U as usize
|
&& layout::MAP[(fn_mode & 0x0F) as usize][index] as usize
|
||||||
&& layout::MAP[fn_mode as usize][index] as usize <= layout::ButtonType::Hat4B as usize
|
>= layout::ButtonType::Hat1U as usize
|
||||||
|
&& layout::MAP[(fn_mode & 0x0F) as usize][index] as usize
|
||||||
|
<= layout::ButtonType::Hat4B as usize
|
||||||
{
|
{
|
||||||
hats[(index - layout::ButtonType::Hat1U as usize) / 4] |= 1
|
hats[(index - layout::ButtonType::Hat1U as usize) / 4] |= 1
|
||||||
<< ((index - layout::ButtonType::Hat1U as usize)
|
<< ((index - layout::ButtonType::Hat1U as usize)
|
||||||
@ -473,19 +477,21 @@ fn get_joystick_report(
|
|||||||
let (hat3, hat_button3) = format_hat_value(hats[2]);
|
let (hat3, hat_button3) = format_hat_value(hats[2]);
|
||||||
let (hat4, hat_button4) = format_hat_value(hats[3]);
|
let (hat4, hat_button4) = format_hat_value(hats[3]);
|
||||||
|
|
||||||
// Update button state for joystick button 17-20 according to hat button 1-4
|
// Update button state for joystick button 21-24 according to hat button 1-4
|
||||||
let mut buttons: u32 = (hat_button1 as u32) << 16
|
let mut buttons: u32 = (hat_button1 as u32) << 20
|
||||||
| ((hat_button2 as u32) << 17)
|
| ((hat_button2 as u32) << 21)
|
||||||
| ((hat_button3 as u32) << 18)
|
| ((hat_button3 as u32) << 22)
|
||||||
| ((hat_button4 as u32) << 19);
|
| ((hat_button4 as u32) << 23);
|
||||||
|
|
||||||
// Update button state for joystick button 1-16
|
// Update button state for joystick button 1-20
|
||||||
for (index, key) in matrix_keys.iter_mut().enumerate() {
|
for (index, key) in matrix_keys.iter_mut().enumerate() {
|
||||||
if key.pressed
|
if key.pressed
|
||||||
&& layout::MAP[fn_mode as usize][index] as usize >= layout::ButtonType::B1 as usize
|
&& layout::MAP[(fn_mode & 0x0F) as usize][index] as usize
|
||||||
&& layout::MAP[fn_mode as usize][index] as usize <= layout::ButtonType::B16 as usize
|
>= layout::ButtonType::B1 as usize
|
||||||
|
&& layout::MAP[(fn_mode & 0x0F) as usize][index] as usize
|
||||||
|
<= layout::ButtonType::B20 as usize
|
||||||
{
|
{
|
||||||
buttons |= 1 << layout::MAP[fn_mode as usize][index] as usize;
|
buttons |= 1 << layout::MAP[(fn_mode & 0x0F) as usize][index] as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
//!HID joystick
|
//! Project: CMtec CMDR joystick 24
|
||||||
|
//! Date: 2023-08-01
|
||||||
|
//! Author: Christoffer Martinsson
|
||||||
|
//! Email: cm@cmtec.se
|
||||||
|
//! License: Please refer to LICENSE in root directory
|
||||||
|
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use fugit::ExtU32;
|
use fugit::ExtU32;
|
||||||
use usb_device::bus::UsbBus;
|
use usb_device::bus::UsbBus;
|
||||||
@ -63,7 +68,7 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Based on example device from https://github.com/dlkj/usbd-human-interface-device/blob/main/src/device/joystick.rs
|
// Based on example device from https://github.com/dlkj/usbd-human-interface-device/blob/main/src/device/joystick.rs
|
||||||
// Updated to 6pc 12bit axis, 20pc buttons and 4pc hat switches
|
// Updated to 6pc 12bit axis, 24pc buttons and 4pc hat switches
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const JOYSTICK_DESCRIPTOR: &[u8] = &[
|
pub const JOYSTICK_DESCRIPTOR: &[u8] = &[
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
@ -85,15 +90,12 @@ pub const JOYSTICK_DESCRIPTOR: &[u8] = &[
|
|||||||
0xc0, // End Collection
|
0xc0, // End Collection
|
||||||
0x05, 0x09, // Usage Page (Button)
|
0x05, 0x09, // Usage Page (Button)
|
||||||
0x19, 0x01, // Usage Minimum (1)
|
0x19, 0x01, // Usage Minimum (1)
|
||||||
0x29, 0x14, // Usage Maximum (20)
|
0x29, 0x18, // Usage Maximum (24)
|
||||||
0x15, 0x00, // Logical Minimum (0)
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
0x25, 0x01, // Logical Maximum (1)
|
0x25, 0x01, // Logical Maximum (1)
|
||||||
0x75, 0x01, // Report Size (1)
|
0x75, 0x01, // Report Size (1)
|
||||||
0x95, 0x14, // Report Count (20)
|
0x95, 0x18, // Report Count (24)
|
||||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||||
0x75, 0x01, // Report Size (1) PADDING
|
|
||||||
0x95, 0x04, // Report Count (4) PADDING
|
|
||||||
0x81, 0x03, // Input (Const, Variable, Absolute) PADDING
|
|
||||||
0x15, 0x00, // Logical Minimum (0)
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
0x25, 0x07, // Logical Maximum (7)
|
0x25, 0x07, // Logical Maximum (7)
|
||||||
0x35, 0x00, // Physical Minimum (0)
|
0x35, 0x00, // Physical Minimum (0)
|
||||||
@ -118,7 +120,7 @@ pub struct JoystickReport {
|
|||||||
pub rx: u16, // 12bit
|
pub rx: u16, // 12bit
|
||||||
pub ry: u16, // 12bit
|
pub ry: u16, // 12bit
|
||||||
pub rz: u16, // 12bit
|
pub rz: u16, // 12bit
|
||||||
pub buttons: u32, // 20bit
|
pub buttons: u32, // 24bit
|
||||||
pub hat1: u8, // 4bit
|
pub hat1: u8, // 4bit
|
||||||
pub hat2: u8, // 4bit
|
pub hat2: u8, // 4bit
|
||||||
pub hat3: u8, // 4bit
|
pub hat3: u8, // 4bit
|
||||||
@ -134,6 +136,7 @@ impl<'a, B: UsbBus> Joystick<'a, B> {
|
|||||||
let mut data: [u8; 14] = [0; 14];
|
let mut data: [u8; 14] = [0; 14];
|
||||||
|
|
||||||
// Did not make the packed struct work, so doing it manually
|
// Did not make the packed struct work, so doing it manually
|
||||||
|
// TODO: make this work with packed struct
|
||||||
data[0] = report.x as u8;
|
data[0] = report.x as u8;
|
||||||
data[1] = ((report.x >> 8) as u8) | ((report.y << 4) as u8);
|
data[1] = ((report.x >> 8) as u8) | ((report.y << 4) as u8);
|
||||||
data[2] = (report.y >> 4) as u8;
|
data[2] = (report.y >> 4) as u8;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user