From 0d25195f22012fba93a0bf7605aa76230455bcf0 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Mon, 30 Jan 2023 18:22:23 -0600 Subject: [PATCH] alskjd --- src/input_common/helpers/joycon_driver.cpp | 7 +-- .../joycon_protocol/generic_functions.cpp | 44 ++++++++++++++++--- .../joycon_protocol/generic_functions.h | 13 ++++-- .../helpers/joycon_protocol/joycon_types.h | 44 +++++++++++++++++++ 4 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index 8f94c9f45..e50bb92a9 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp @@ -253,8 +253,8 @@ DriverResult JoyconDriver::SetPollingMode() { if (motion_enabled && supported_features.motion) { generic_protocol->EnableImu(true); - generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, - accelerometer_sensitivity, accelerometer_performance); + generic_protocol->SetImuConfig({gyro_sensitivity, accelerometer_sensitivity, + gyro_performance, accelerometer_performance}); } else { generic_protocol->EnableImu(false); } @@ -543,9 +543,10 @@ void JoyconDriver::SetCallbacks(const JoyconCallbacks& callbacks) { DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, ControllerType& controller_type) { - static constexpr std::array, 2> supported_devices{ + static constexpr std::array, 3> supported_devices{ std::pair{0x2006, ControllerType::Left}, {0x2007, ControllerType::Right}, + {0x200e, ControllerType::Grip}, }; constexpr u16 nintendo_vendor_id = 0x057e; diff --git a/src/input_common/helpers/joycon_protocol/generic_functions.cpp b/src/input_common/helpers/joycon_protocol/generic_functions.cpp index ab9eebc1b..d6e971753 100644 --- a/src/input_common/helpers/joycon_protocol/generic_functions.cpp +++ b/src/input_common/helpers/joycon_protocol/generic_functions.cpp @@ -89,9 +89,25 @@ DriverResult GenericProtocol::GetSerialNumber(SerialNumber& serial_number) { } DriverResult GenericProtocol::GetTemperature(u32& temperature) { - // Not all devices have temperature sensor - temperature = 25; - return DriverResult::NotSupported; + ScopedSetBlocking sb(this); + SubCommandResponse output{}; + std::array buffer{}; + constexpr ImuRegister temperature_reg{ + .address = ImuRegistersAddress::OUT_TEMP, + .size = sizeof(SubCommandResponse::temperature), + }; + + // TODO: Ensure the IMU sensor is enabled + + temperature = 0; + memcpy(buffer.data(), &temperature_reg, sizeof(ImuRegister)); + const auto result = SendSubCommand(SubCommand::READ_IMU_REG, buffer, output); + + if (result == DriverResult::Success) { + temperature = output.temperature; + } + + return result; } DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) { @@ -103,12 +119,30 @@ DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) { return result; } -DriverResult GenericProtocol::SetHomeLight() { +DriverResult GenericProtocol::SetHomeLight(bool state) { ScopedSetBlocking sb(this); - static constexpr std::array buffer{0x0f, 0xf0, 0x00}; + static constexpr std::array buffer{0x00, 0x0a, 0x00}; return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer); } +DriverResult GenericProtocol::SetHomeLightBlink(u8 duration) { + ScopedSetBlocking sb(this); + duration = std::clamp(duration, 0x8, 0xaf); + const std::array buffer{0x05, duration, 0xf0, 0x01}; + return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer); +} + +DriverResult GenericProtocol::SetHomeLightPattern(u8 short_cycle_count, u8 short_cycle_duration, u8 brightness, u8 cycle_count) { + ScopedSetBlocking sb(this); + short_cycle_count = std::min(short_cycle_count, 0x0f); + short_cycle_duration = std::min(short_cycle_duration, 0xaf); + brightness = std::min(brightness, 0x64); + cycle_count = std::min(cycle_count, 0x0f); + const std::array buffer{0x05, cycle_count, 0xf0, 0x01}; + return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer); +} + + DriverResult GenericProtocol::SetLedBusy() { return DriverResult::NotSupported; } diff --git a/src/input_common/helpers/joycon_protocol/generic_functions.h b/src/input_common/helpers/joycon_protocol/generic_functions.h index 47cb1ab98..5199408e6 100644 --- a/src/input_common/helpers/joycon_protocol/generic_functions.h +++ b/src/input_common/helpers/joycon_protocol/generic_functions.h @@ -74,22 +74,27 @@ public: DriverResult GetSerialNumber(SerialNumber& serial_number); /** - * Request joycon serial number from the device - * @returns 16 byte serial number + * Reads the temperature directly from the IMU sensor registers. IMU sensor needs to be enabled + * for this funtion to work properly + * @returns temperature in degrees */ DriverResult GetTemperature(u32& temperature); /** * Request joycon serial number from the device - * @returns 16 byte serial number + * @returns 15 byte firmware version */ DriverResult GetVersionNumber(FirmwareVersion& version); /** * Sets home led behaviour */ - DriverResult SetHomeLight(); + DriverResult SetHomeLight(bool state); + DriverResult SetHomeLightBlink(u8 duration); + + DriverResult SetHomeLightPattern(u8 short_cycle_count, u8 short_cycle_duration, u8 brightness, + u8 cycle_count); /** * Sets home led into a slow breathing state */ diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index 304e9c801..55b322224 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h @@ -29,6 +29,7 @@ enum class ControllerType : u8 { Left = 0x01, Right = 0x02, Pro = 0x03, + Grip = 0x04, Dual = 0x05, // TODO: Verify this id LarkHvc1 = 0x07, LarkHvc2 = 0x08, @@ -365,6 +366,43 @@ enum class IrRegistersAddress : u16 { DenoiseColor = 0x6901, }; +// See LSM6DS3 register table +enum class ImuRegistersAddress : u8 { + FUNC_CFG_ACCESS = 0x01, + SENSOR_SYNC_TIME_FRAME = 0x04, + FIFO_CTRL = 0x06, + ORIENT_CFG_G = 0x0b, + INT1_CTRL = 0x0d, + INT2_CTRL = 0x0e, + WHO_AM_I = 0x0f, + ACCEL_GYRO_CONTROL_REG = 0x10, + MASTER_CONFIG = 0x1a, + WAKE_UP_SRC = 0x1b, + TAP_SRC = 0x1c, + D6D_SRC = 0x1d, + STATUS_REG = 0x1e, + OUT_TEMP = 0x20, + OUTX_GYRO = 0x22, + OUTX_ACCEL = 0x28, + SENSORHUB_REG = 0x2e, + FIFO_STATUS = 0x39, + FIFO_DATA_OUT = 0x3e, + TIMESTAMP_REG = 0x40, + STEP_TIMESTAMP = 0x49, + STEP_COUNTER = 0x4b, + SENSORHUB13_REG = 0x4d, + FUNC_SRC = 0x53, + TAP_CFG = 0x58, + TAP_THS_6D = 0x59, + INT_DUR2 = 0x5a, + WAKE_UP_THS = 0x5b, + WAKE_UP_DUR = 0x5c, + FREE_FALL = 0x5d, + MD1_CFG = 0x5e, + MD2_CFG = 0x5f, + OUT_MAG_RAW = 0x66, +}; + enum class ExternalDeviceId : u16 { RingController = 0x2000, Starlink = 0x2800, @@ -625,6 +663,11 @@ struct IrsWriteRegisters { static_assert(sizeof(IrsWriteRegisters) == 0x26, "IrsWriteRegisters is an invalid size"); #pragma pack(pop) +struct ImuRegister { + ImuRegistersAddress address; + u8 size; +}; + struct FirmwareVersion { u8 major; u8 minor; @@ -685,6 +728,7 @@ struct SubCommandResponse { SpiAddress spi_address; // Reply from SPI_FLASH_READ subcommand ExternalDeviceId external_device_id; // Reply from GET_EXTERNAL_DEVICE_INFO subcommand DeviceInfo device_info; // Reply from REQ_DEV_INFO subcommand + u16 temperature; // Reply from READ_IMU_REG->OUT_TEMP }; u8 crc; // This is never used };