Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions rootfs/usr/share/inputplumber/devices/50-legion_go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ source_devices:
product_id: 0x61ee
interface_num: 2

# IMU
- group: imu
iio:
name: accel_3d
mount_matrix:
x: [0, 1, 0]
y: [1, 0, 0]
z: [0, 0, 1]

# IMU
- group: imu
iio:
Expand Down
62 changes: 12 additions & 50 deletions src/drivers/dualsense/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,11 @@ use crate::drivers::dualsense::{
};

use super::{
event::{AccelerometerEvent, AccelerometerInput, AxisEvent, AxisInput, Event, TouchAxisInput},
event::{AxisEvent, AxisInput, Event, InertialInput, IntertialEvent, TouchAxisInput},
hid_report::{PackedInputDataReport, SetStatePackedOutputData, UsbPackedOutputReport},
DS5_ACCEL_TO_SI, DS5_GYRO_TO_RADS, DS5_VID, INPUT_REPORT_BT_SIZE, PIDS,
};

// Source: https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c
pub const DS5_EDGE_NAME: &str = "Sony Interactive Entertainment DualSense Edge Wireless Controller";
pub const DS5_EDGE_VERSION: u16 = 256;
pub const DS5_EDGE_VID: u16 = 0x054c;
pub const DS5_EDGE_PID: u16 = 0x0df2;

pub const DS5_NAME: &str = "Sony Interactive Entertainment DualSense Wireless Controller";
pub const DS5_VERSION: u16 = 0x8111;
pub const DS5_VID: u16 = 0x054c;
pub const DS5_PID: u16 = 0x0ce6;

pub const PIDS: [u16; 2] = [DS5_EDGE_PID, DS5_PID];

pub const FEATURE_REPORT_PAIRING_INFO: u8 = 0x09;
pub const FEATURE_REPORT_FIRMWARE_INFO: u8 = 0x20;
pub const FEATURE_REPORT_CALIBRATION: u8 = 0x05;

pub const INPUT_REPORT_USB: u8 = 0x01;
pub const INPUT_REPORT_USB_SIZE: usize = 64;
pub const INPUT_REPORT_BT: u8 = 0x31;
pub const INPUT_REPORT_BT_SIZE: usize = 78;
pub const OUTPUT_REPORT_USB: u8 = 0x02;
pub const OUTPUT_REPORT_USB_SIZE: usize = 63;
pub const OUTPUT_REPORT_USB_SHORT_SIZE: usize = 48;
pub const OUTPUT_REPORT_BT: u8 = 0x31;
pub const OUTPUT_REPORT_BT_SIZE: usize = 78;

// Input report axis ranges
pub const STICK_X_MIN: f64 = u8::MIN as f64;
pub const STICK_X_MAX: f64 = u8::MAX as f64;
pub const STICK_Y_MIN: f64 = u8::MIN as f64;
pub const STICK_Y_MAX: f64 = u8::MAX as f64;
pub const TRIGGER_MAX: f64 = u8::MAX as f64;

// DualSense hardware limits
pub const DS5_ACC_RES_PER_G: u32 = 8192;
pub const DS5_TOUCHPAD_WIDTH: f64 = 1919.0;
pub const DS5_TOUCHPAD_HEIGHT: f64 = 1079.0;

/// PS5 Dualsense controller driver for reading gamepad input
pub struct Driver {
state: Option<PackedInputDataReport>,
Expand Down Expand Up @@ -420,18 +382,18 @@ impl Driver {
}

// Accelerometer events
events.push(Event::Accelerometer(AccelerometerEvent::Accelerometer(
AccelerometerInput {
x: state.accel_x.to_primitive(),
y: state.accel_y.to_primitive(),
z: state.accel_z.to_primitive(),
events.push(Event::Accelerometer(IntertialEvent::Accelerometer(
InertialInput {
x: state.accel_x.to_primitive() as f64 * DS5_ACCEL_TO_SI,
y: state.accel_y.to_primitive() as f64 * DS5_ACCEL_TO_SI,
z: state.accel_z.to_primitive() as f64 * DS5_ACCEL_TO_SI,
},
)));
events.push(Event::Accelerometer(AccelerometerEvent::Gyro(
AccelerometerInput {
x: state.pitch.to_primitive(),
y: state.yaw.to_primitive(),
z: state.roll.to_primitive(),
events.push(Event::Accelerometer(IntertialEvent::Gyroscope(
InertialInput {
x: state.pitch.to_primitive() as f64 * DS5_GYRO_TO_RADS,
y: state.yaw.to_primitive() as f64 * DS5_GYRO_TO_RADS,
z: state.roll.to_primitive() as f64 * DS5_GYRO_TO_RADS,
},
)));

Expand Down
18 changes: 9 additions & 9 deletions src/drivers/dualsense/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#[derive(Clone, Debug)]
pub enum Event {
Button(ButtonEvent),
Accelerometer(AccelerometerEvent),
Accelerometer(IntertialEvent),
Axis(AxisEvent),
Trigger(TriggerEvent),
}
Expand Down Expand Up @@ -78,18 +78,18 @@ pub enum TriggerEvent {
R2(TriggerInput),
}

/// AccelerometerInput represents the state of the accelerometer (x, y, z) values
/// InertialInput represents the state of the IMU (x, y, z) values
#[derive(Clone, Debug)]
pub struct AccelerometerInput {
pub x: i16,
pub y: i16,
pub z: i16,
pub struct InertialInput {
pub x: f64,
pub y: f64,
pub z: f64,
}

/// AccelerometerEvent has data from the accelerometer
#[derive(Clone, Debug)]
pub enum AccelerometerEvent {
Accelerometer(AccelerometerInput),
pub enum IntertialEvent {
Accelerometer(InertialInput),
/// Pitch, yaw, roll
Gyro(AccelerometerInput),
Gyroscope(InertialInput),
}
2 changes: 1 addition & 1 deletion src/drivers/dualsense/hid_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{error::Error, fmt::Display};

use packed_struct::prelude::*;

use super::driver::*;
use super::{INPUT_REPORT_BT, INPUT_REPORT_BT_SIZE, INPUT_REPORT_USB, INPUT_REPORT_USB_SIZE};

/// DualSense input report for USB and Bluetooth
#[derive(Debug, Copy, Clone)]
Expand Down
42 changes: 42 additions & 0 deletions src/drivers/dualsense/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,45 @@ pub mod hid_report;
#[cfg(test)]
mod hid_report_test;
pub mod report_descriptor;

// Source: https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c
pub const DS5_EDGE_NAME: &str = "Sony Interactive Entertainment DualSense Edge Wireless Controller";
pub const DS5_EDGE_VERSION: u16 = 256;
pub const DS5_EDGE_VID: u16 = 0x054c;
pub const DS5_EDGE_PID: u16 = 0x0df2;

pub const DS5_NAME: &str = "Sony Interactive Entertainment DualSense Wireless Controller";
pub const DS5_VERSION: u16 = 0x8111;
pub const DS5_VID: u16 = 0x054c;
pub const DS5_PID: u16 = 0x0ce6;

pub const PIDS: [u16; 2] = [DS5_EDGE_PID, DS5_PID];

pub const FEATURE_REPORT_PAIRING_INFO: u8 = 0x09;
pub const FEATURE_REPORT_FIRMWARE_INFO: u8 = 0x20;
pub const FEATURE_REPORT_CALIBRATION: u8 = 0x05;

pub const INPUT_REPORT_USB: u8 = 0x01;
pub const INPUT_REPORT_USB_SIZE: usize = 64;
pub const INPUT_REPORT_BT: u8 = 0x31;
pub const INPUT_REPORT_BT_SIZE: usize = 78;
pub const OUTPUT_REPORT_USB: u8 = 0x02;
pub const OUTPUT_REPORT_USB_SIZE: usize = 63;
pub const OUTPUT_REPORT_USB_SHORT_SIZE: usize = 48;
pub const OUTPUT_REPORT_BT: u8 = 0x31;
pub const OUTPUT_REPORT_BT_SIZE: usize = 78;

// Input report axis ranges
pub const STICK_X_MIN: f64 = u8::MIN as f64;
pub const STICK_X_MAX: f64 = u8::MAX as f64;
pub const STICK_Y_MIN: f64 = u8::MIN as f64;
pub const STICK_Y_MAX: f64 = u8::MAX as f64;
pub const TRIGGER_MAX: f64 = u8::MAX as f64;

// DualSense hardware limits
pub const DS5_ACCEL_TO_SI: f64 = 0.00119710083;
pub const DS5_SI_TO_ACCEL: f64 = 0.101971621;
pub const DS5_GYRO_TO_RADS: f64 = 0.00001706026;
pub const DS5_RADS_TO_GYRO: f64 = 57.29577951;
pub const DS5_TOUCHPAD_WIDTH: f64 = 1919.0;
pub const DS5_TOUCHPAD_HEIGHT: f64 = 1079.0;
14 changes: 7 additions & 7 deletions src/drivers/flydigi_vader_4_pro/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,16 +284,16 @@ impl Driver {
// Accelerometer events
events.push(Event::Inertia(InertialEvent::Accelerometer(
InertialInput {
x: -state.accel_x.to_primitive(),
y: state.accel_y.to_primitive(),
z: state.accel_z.to_primitive(),
x: -state.accel_x.to_primitive() as f64,
y: state.accel_y.to_primitive() as f64,
z: state.accel_z.to_primitive() as f64,
},
)));
// Gyro events. They need to be rotated in order for them to be read properly
events.push(Event::Inertia(InertialEvent::Gyro(InertialInput {
x: -(state.gyro_x.to_primitive() as i32 * 1143239 / i16::MAX as i32) as i16,
y: -(state.get_y() as i32 * 1143239 / i16::MAX as i32) as i16,
z: -(state.gyro_z.to_primitive() as i32 * 17873 / i16::MAX as i32) as i16,
events.push(Event::Inertia(InertialEvent::Gyroscope(InertialInput {
x: -(state.gyro_x.to_primitive() as f64 * 1143239.0 / i16::MAX as f64),
y: -(state.get_y() as f64 * 1143239.0 / i16::MAX as f64),
z: -(state.gyro_z.to_primitive() as f64 * 17873.0 / i16::MAX as f64),
})));
events
}
Expand Down
8 changes: 4 additions & 4 deletions src/drivers/flydigi_vader_4_pro/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ pub enum ButtonEvent {
/// [InertialInput] represents the state of the IMU (x, y, z) values
#[derive(Clone, Debug)]
pub struct InertialInput {
pub x: i16,
pub y: i16,
pub z: i16,
pub x: f64,
pub y: f64,
pub z: f64,
}

/// [InertialEvent] has data from the IMU
#[derive(Clone, Debug)]
pub enum InertialEvent {
Accelerometer(InertialInput),
Gyro(InertialInput),
Gyroscope(InertialInput),
}

/// [JoystickInput] is a double (x, y) axis
Expand Down
37 changes: 12 additions & 25 deletions src/drivers/horipad_steam/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,20 @@ use std::{error::Error, ffi::CString};
use hidapi::HidDevice;
use packed_struct::{types::SizedInteger, PackedStruct};

use crate::{drivers::horipad_steam::hid_report::Direction, udev::device::UdevDevice};
use crate::{
drivers::horipad_steam::{hid_report::Direction, HORIPAD_ACCEL_TO_SI, HORIPAD_GYRO_TO_RADS},
udev::device::UdevDevice,
};

use super::{
event::{
BinaryInput, ButtonEvent, Event, InertialEvent, InertialInput, JoystickEvent,
JoystickInput, TriggerEvent, TriggerInput,
},
hid_report::PackedInputDataReport,
HID_TIMEOUT, PACKET_SIZE, PIDS, REPORT_ID, VID,
};

// Report ID
pub const REPORT_ID: u8 = 0x07;

// Input report size
const PACKET_SIZE: usize = 287;

// HID buffer read timeout
const HID_TIMEOUT: i32 = 10;

// Input report axis ranges
pub const JOY_AXIS_MAX: f64 = 255.0;
pub const JOY_AXIS_MIN: f64 = 0.0;
pub const TRIGGER_AXIS_MAX: f64 = 255.0;

pub const VID: u16 = 0x0F0D;
pub const PIDS: [u16; 2] = [0x0196, 0x01AB];

#[derive(Debug, Clone, Default)]
struct DPadState {
up: bool,
Expand Down Expand Up @@ -289,15 +276,15 @@ impl Driver {
// Accelerometer events
events.push(Event::Inertia(InertialEvent::Accelerometer(
InertialInput {
x: -state.accel_x.to_primitive(),
y: state.accel_y.to_primitive(),
z: -state.accel_z.to_primitive(),
x: -state.accel_x.to_primitive() as f64 * HORIPAD_ACCEL_TO_SI,
y: state.accel_y.to_primitive() as f64 * HORIPAD_ACCEL_TO_SI,
z: -state.accel_z.to_primitive() as f64 * HORIPAD_ACCEL_TO_SI,
},
)));
events.push(Event::Inertia(InertialEvent::Gyro(InertialInput {
x: -state.pitch.to_primitive(),
y: state.yaw.to_primitive(),
z: -state.roll.to_primitive(),
events.push(Event::Inertia(InertialEvent::Gyroscope(InertialInput {
x: -state.pitch.to_primitive() as f64 * HORIPAD_GYRO_TO_RADS,
y: state.yaw.to_primitive() as f64 * HORIPAD_GYRO_TO_RADS,
z: -state.roll.to_primitive() as f64 * HORIPAD_GYRO_TO_RADS,
})));

log::trace!("Got events: {events:?}");
Expand Down
8 changes: 4 additions & 4 deletions src/drivers/horipad_steam/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ pub enum ButtonEvent {
/// [InertialInput] represents the state of the IMU (x, y, z) values
#[derive(Clone, Debug)]
pub struct InertialInput {
pub x: i16,
pub y: i16,
pub z: i16,
pub x: f64,
pub y: f64,
pub z: f64,
}

/// [InertialEvent] has data from the IMU
#[derive(Clone, Debug)]
pub enum InertialEvent {
Accelerometer(InertialInput),
Gyro(InertialInput),
Gyroscope(InertialInput),
}

/// [JoystickInput] is a double (x, y) axis
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/horipad_steam/hid_report.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use packed_struct::prelude::*;

use super::driver::REPORT_ID;
use super::REPORT_ID;

#[derive(PrimitiveEnum_u8, Clone, Copy, PartialEq, Debug, Default)]
pub enum Direction {
Expand Down
22 changes: 22 additions & 0 deletions src/drivers/horipad_steam/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,25 @@ pub mod hid_report;
#[cfg(test)]
pub mod hid_report_test;
pub mod report_descriptor;

// Report ID
pub const REPORT_ID: u8 = 0x07;

// Input report size
pub const PACKET_SIZE: usize = 287;

// HID buffer read timeout
pub const HID_TIMEOUT: i32 = 10;

// Input report axis ranges
pub const JOY_AXIS_MAX: f64 = 255.0;
pub const JOY_AXIS_MIN: f64 = 0.0;
pub const TRIGGER_AXIS_MAX: f64 = 255.0;

pub const VID: u16 = 0x0F0D;
pub const PIDS: [u16; 2] = [0x0196, 0x01AB];

pub const HORIPAD_ACCEL_TO_SI: f64 = 0.00059855041;
pub const HORIPAD_SI_TO_ACCEL: f64 = 0.101971621;
pub const HORIPAD_GYRO_TO_RADS: f64 = 0.00106422393;
pub const HORIPAD_RADS_TO_GYRO: f64 = 57.29577951;
Loading
Loading