This commit is contained in:
Narr the Reg
2023-01-30 18:22:23 -06:00
parent f629f2722c
commit 0d25195f22
4 changed files with 96 additions and 12 deletions

View File

@@ -253,8 +253,8 @@ DriverResult JoyconDriver::SetPollingMode() {
if (motion_enabled && supported_features.motion) { if (motion_enabled && supported_features.motion) {
generic_protocol->EnableImu(true); generic_protocol->EnableImu(true);
generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, generic_protocol->SetImuConfig({gyro_sensitivity, accelerometer_sensitivity,
accelerometer_sensitivity, accelerometer_performance); gyro_performance, accelerometer_performance});
} else { } else {
generic_protocol->EnableImu(false); generic_protocol->EnableImu(false);
} }
@@ -543,9 +543,10 @@ void JoyconDriver::SetCallbacks(const JoyconCallbacks& callbacks) {
DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info,
ControllerType& controller_type) { ControllerType& controller_type) {
static constexpr std::array<std::pair<u32, ControllerType>, 2> supported_devices{ static constexpr std::array<std::pair<u32, ControllerType>, 3> supported_devices{
std::pair<u32, ControllerType>{0x2006, ControllerType::Left}, std::pair<u32, ControllerType>{0x2006, ControllerType::Left},
{0x2007, ControllerType::Right}, {0x2007, ControllerType::Right},
{0x200e, ControllerType::Grip},
}; };
constexpr u16 nintendo_vendor_id = 0x057e; constexpr u16 nintendo_vendor_id = 0x057e;

View File

@@ -89,9 +89,25 @@ DriverResult GenericProtocol::GetSerialNumber(SerialNumber& serial_number) {
} }
DriverResult GenericProtocol::GetTemperature(u32& temperature) { DriverResult GenericProtocol::GetTemperature(u32& temperature) {
// Not all devices have temperature sensor ScopedSetBlocking sb(this);
temperature = 25; SubCommandResponse output{};
return DriverResult::NotSupported; std::array<u8, sizeof(ImuRegister)> 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) { DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) {
@@ -103,12 +119,30 @@ DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) {
return result; return result;
} }
DriverResult GenericProtocol::SetHomeLight() { DriverResult GenericProtocol::SetHomeLight(bool state) {
ScopedSetBlocking sb(this); ScopedSetBlocking sb(this);
static constexpr std::array<u8, 3> buffer{0x0f, 0xf0, 0x00}; static constexpr std::array<u8, 3> buffer{0x00, 0x0a, 0x00};
return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer); return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer);
} }
DriverResult GenericProtocol::SetHomeLightBlink(u8 duration) {
ScopedSetBlocking sb(this);
duration = std::clamp<u8>(duration, 0x8, 0xaf);
const std::array<u8, 4> 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<u8>(short_cycle_count, 0x0f);
short_cycle_duration = std::min<u8>(short_cycle_duration, 0xaf);
brightness = std::min<u8>(brightness, 0x64);
cycle_count = std::min<u8>(cycle_count, 0x0f);
const std::array<u8, 4> buffer{0x05, cycle_count, 0xf0, 0x01};
return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer);
}
DriverResult GenericProtocol::SetLedBusy() { DriverResult GenericProtocol::SetLedBusy() {
return DriverResult::NotSupported; return DriverResult::NotSupported;
} }

View File

@@ -74,22 +74,27 @@ public:
DriverResult GetSerialNumber(SerialNumber& serial_number); DriverResult GetSerialNumber(SerialNumber& serial_number);
/** /**
* Request joycon serial number from the device * Reads the temperature directly from the IMU sensor registers. IMU sensor needs to be enabled
* @returns 16 byte serial number * for this funtion to work properly
* @returns temperature in degrees
*/ */
DriverResult GetTemperature(u32& temperature); DriverResult GetTemperature(u32& temperature);
/** /**
* Request joycon serial number from the device * Request joycon serial number from the device
* @returns 16 byte serial number * @returns 15 byte firmware version
*/ */
DriverResult GetVersionNumber(FirmwareVersion& version); DriverResult GetVersionNumber(FirmwareVersion& version);
/** /**
* Sets home led behaviour * 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 * Sets home led into a slow breathing state
*/ */

View File

@@ -29,6 +29,7 @@ enum class ControllerType : u8 {
Left = 0x01, Left = 0x01,
Right = 0x02, Right = 0x02,
Pro = 0x03, Pro = 0x03,
Grip = 0x04,
Dual = 0x05, // TODO: Verify this id Dual = 0x05, // TODO: Verify this id
LarkHvc1 = 0x07, LarkHvc1 = 0x07,
LarkHvc2 = 0x08, LarkHvc2 = 0x08,
@@ -365,6 +366,43 @@ enum class IrRegistersAddress : u16 {
DenoiseColor = 0x6901, 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 { enum class ExternalDeviceId : u16 {
RingController = 0x2000, RingController = 0x2000,
Starlink = 0x2800, Starlink = 0x2800,
@@ -625,6 +663,11 @@ struct IrsWriteRegisters {
static_assert(sizeof(IrsWriteRegisters) == 0x26, "IrsWriteRegisters is an invalid size"); static_assert(sizeof(IrsWriteRegisters) == 0x26, "IrsWriteRegisters is an invalid size");
#pragma pack(pop) #pragma pack(pop)
struct ImuRegister {
ImuRegistersAddress address;
u8 size;
};
struct FirmwareVersion { struct FirmwareVersion {
u8 major; u8 major;
u8 minor; u8 minor;
@@ -685,6 +728,7 @@ struct SubCommandResponse {
SpiAddress spi_address; // Reply from SPI_FLASH_READ subcommand SpiAddress spi_address; // Reply from SPI_FLASH_READ subcommand
ExternalDeviceId external_device_id; // Reply from GET_EXTERNAL_DEVICE_INFO subcommand ExternalDeviceId external_device_id; // Reply from GET_EXTERNAL_DEVICE_INFO subcommand
DeviceInfo device_info; // Reply from REQ_DEV_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 u8 crc; // This is never used
}; };