mirror of
https://github.com/ndeadly/MissionControl
synced 2024-11-22 20:33:07 +00:00
bluetooth-mitm: get booting on console again
This commit is contained in:
parent
de911fbd31
commit
f7a7f78468
15 changed files with 100 additions and 95 deletions
|
@ -3,8 +3,8 @@
|
|||
"title_id": "0x010000000000bd00",
|
||||
"title_id_range_min": "0x010000000000bd00",
|
||||
"title_id_range_max": "0x010000000000bd00",
|
||||
"main_thread_stack_size": "0x4000",
|
||||
"main_thread_priority": 42,
|
||||
"main_thread_stack_size": "0x10000",
|
||||
"main_thread_priority": 22,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"is_retail": true,
|
||||
|
@ -25,7 +25,7 @@
|
|||
"type": "kernel_flags",
|
||||
"value": {
|
||||
"highest_thread_priority": 63,
|
||||
"lowest_thread_priority": 24,
|
||||
"lowest_thread_priority": 12,
|
||||
"lowest_cpu_id": 3,
|
||||
"highest_cpu_id": 3
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
|||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x10000
|
||||
#define INNER_HEAP_SIZE 0x80000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||
|
||||
|
@ -92,9 +92,10 @@ void __libnx_exception_handler(ThreadExceptionDump* ctx) {
|
|||
ams::CrashHandler(ctx);
|
||||
}
|
||||
|
||||
void LaunchModules(void) {
|
||||
ams::mitm::btdrv::Launch();
|
||||
ams::mitm::btm::Launch();
|
||||
ams::Result LaunchModules(void) {
|
||||
R_TRY(ams::mitm::btdrv::Launch());
|
||||
R_TRY(ams::mitm::btm::Launch());
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
void WaitModules(void) {
|
||||
|
@ -103,7 +104,7 @@ void WaitModules(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
LaunchModules();
|
||||
R_ABORT_UNLESS(LaunchModules());
|
||||
WaitModules();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
#include "bluetooth_core.hpp"
|
||||
#include "../btdrv_mitm_flags.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include "../../controllers/controller_management.hpp"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
#include "bluetooth_hid.hpp"
|
||||
#include "../btdrv_mitm_flags.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include "../../controllers/controller_management.hpp"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "bluetooth_circular_buffer.hpp"
|
||||
#include "../btdrv_shim.h"
|
||||
#include "../btdrv_mitm_flags.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include "../../controllers/controller_management.hpp"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
|
|
|
@ -20,32 +20,6 @@
|
|||
|
||||
namespace ams::bluetooth {
|
||||
|
||||
enum SubCmdType : u8 {
|
||||
SubCmd_GetControllerState = 0x00,
|
||||
SubCmd_ManualPair = 0x01,
|
||||
SubCmd_RequestDeviceInfo = 0x02,
|
||||
SubCmd_SetInputReportMode = 0x03,
|
||||
SubCmd_TriggersElapsedTime = 0x04,
|
||||
SubCmd_SetHciState = 0x06,
|
||||
SubCmd_ResetPairingInfo = 0x07,
|
||||
SubCmd_SetShipPowerState = 0x08,
|
||||
SubCmd_SpiFlashRead = 0x10,
|
||||
SubCmd_SpiFlashWrite = 0x11,
|
||||
SubCmd_SpiSectorErase = 0x12,
|
||||
SubCmd_ResetMcu = 0x20,
|
||||
SubCmd_SetMcuConfig = 0x21,
|
||||
SubCmd_SetMcuState = 0x22,
|
||||
SubCmd_SetPlayerLeds = 0x30,
|
||||
SubCmd_GetPlayerLeds = 0x31,
|
||||
SubCmd_SetHomeLed = 0x38,
|
||||
SubCmd_EnableImu = 0x40,
|
||||
SubCmd_SetImuSensitivity = 0x41,
|
||||
SubCmd_WriteImuRegisters = 0x42,
|
||||
SubCmd_ReadImuRegisters = 0x43,
|
||||
SubCmd_EnableVibration = 0x48,
|
||||
SubCmd_GetRegulatedVoltage = 0x50,
|
||||
};
|
||||
|
||||
typedef BluetoothEventType EventType;
|
||||
typedef BluetoothHidEventType HidEventType;
|
||||
typedef BluetoothBleEventType BleEventType;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "btdrv_mitm_flags.hpp"
|
||||
#include "btdrv_shim.h"
|
||||
#include "bluetooth/bluetooth_events.hpp"
|
||||
#include "controllers/controller_management.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include <switch.h>
|
||||
#include <cstring>
|
||||
|
||||
|
|
|
@ -39,26 +39,28 @@ namespace ams::mitm::btdrv {
|
|||
alignas(os::ThreadStackAlignment) u8 g_btdrv_mitm_thread_stack[0x4000];
|
||||
constexpr s32 g_btdrv_mitm_thread_priority = 16;
|
||||
|
||||
void BtdrvMitmThreadFunction(void *arg) {
|
||||
R_ABORT_UNLESS(bluetooth::events::Initialize());
|
||||
|
||||
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btdrv::IBtdrvMitmInterface, ams::mitm::btdrv::BtdrvMitmService>(MitmServiceName)));
|
||||
server_manager->LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BtdrvMitmThreadFunction(void *arg) {
|
||||
R_ABORT_UNLESS(bluetooth::events::Initialize());
|
||||
|
||||
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btdrv::IBtdrvMitmInterface, ams::mitm::btdrv::BtdrvMitmService>(MitmServiceName)));
|
||||
server_manager->LoopProcess();
|
||||
}
|
||||
|
||||
void Launch(void) {
|
||||
os::CreateThread(&g_btdrv_mitm_thread,
|
||||
Result Launch(void) {
|
||||
R_TRY(os::CreateThread(&g_btdrv_mitm_thread,
|
||||
BtdrvMitmThreadFunction,
|
||||
nullptr,
|
||||
g_btdrv_mitm_thread_stack,
|
||||
sizeof(g_btdrv_mitm_thread_stack),
|
||||
g_btdrv_mitm_thread_priority
|
||||
);
|
||||
));
|
||||
|
||||
os::StartThread(&g_btdrv_mitm_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
void WaitFinished(void) {
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm::btdrv {
|
||||
|
||||
void Launch(void);
|
||||
Result Launch(void);
|
||||
void WaitFinished(void);
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
#include "btm_mitm_service.hpp"
|
||||
#include "btm_shim.h"
|
||||
#include "../btdrv_mitm/controllers/controller_management.hpp"
|
||||
#include "../controllers/controller_management.hpp"
|
||||
#include <cstring>
|
||||
|
||||
namespace ams::mitm::btm {
|
||||
|
@ -26,7 +26,7 @@ namespace ams::mitm::btm {
|
|||
void RenameConnectedDevices(BtmConnectedDevice devices[], size_t count) {
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
auto device = &devices[i];
|
||||
if (!IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||
if (!controller::IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ namespace ams::mitm::btm {
|
|||
|
||||
for (unsigned int i = 0; i < device_info->count; ++i) {
|
||||
auto device = &device_info->devices[i];
|
||||
if (!IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||
if (!controller::IsOfficialSwitchControllerName(device->name, sizeof(device->name))) {
|
||||
std::strncpy(device->name, controller::pro_controller_name, sizeof(device->name) - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "btm_types.hpp"
|
||||
#include "btm/btm_types.hpp"
|
||||
|
||||
namespace ams::mitm::btm {
|
||||
|
||||
|
|
|
@ -32,35 +32,36 @@ namespace ams::mitm::btm {
|
|||
};
|
||||
|
||||
constexpr size_t MaxServers = 1;
|
||||
constexpr size_t MaxSessions = 8;
|
||||
constexpr size_t MaxSessions = 6;
|
||||
|
||||
os::ThreadType g_btm_mitm_thread;
|
||||
alignas(os::ThreadStackAlignment) u8 g_btm_mitm_thread_stack[0x4000];
|
||||
constexpr s32 g_btm_mitm_thread_priority = 36;
|
||||
constexpr s32 g_btm_mitm_thread_priority = 18;
|
||||
|
||||
void BtmMitmThreadFunction(void *arg) {
|
||||
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btm::IBtmMitmInterface, ams::mitm::btm::BtmMitmService>(MitmServiceName)));
|
||||
server_manager->LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BtmMitmThreadFunction(void *arg) {
|
||||
auto server_manager = std::make_unique<sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions>>();
|
||||
R_ABORT_UNLESS((server_manager->RegisterMitmServer<ams::mitm::btm::IBtmMitmInterface, ams::mitm::btm::BtmMitmService>(MitmServiceName)));
|
||||
server_manager->LoopProcess();
|
||||
}
|
||||
|
||||
void Launch(void) {
|
||||
os::CreateThread(&g_btm_mitm_thread,
|
||||
Result Launch(void) {
|
||||
R_TRY(os::CreateThread(&g_btm_mitm_thread,
|
||||
BtmMitmThreadFunction,
|
||||
nullptr,
|
||||
g_btm_mitm_thread_stack,
|
||||
sizeof(g_btm_mitm_thread_stack),
|
||||
g_btm_mitm_thread_priority
|
||||
);
|
||||
));
|
||||
|
||||
os::StartThread(&g_btm_mitm_thread);
|
||||
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
void WaitFinished(void) {
|
||||
os::WaitThread(&g_btm_mitm_thread);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
namespace ams::mitm::btm {
|
||||
|
||||
void Launch(void);
|
||||
Result Launch(void);
|
||||
void WaitFinished(void);
|
||||
|
||||
}
|
||||
|
|
|
@ -54,46 +54,46 @@ namespace ams::controller {
|
|||
|
||||
Result EmulatedSwitchController::HandleSubCmdReport(const bluetooth::HidReport *report) {
|
||||
const uint8_t *subcmd = &report->data[10];
|
||||
auto subcmd_id = static_cast<bluetooth::SubCmdType>(subcmd[0]);
|
||||
auto subcmd_id = static_cast<SubCmdType>(subcmd[0]);
|
||||
|
||||
switch (subcmd_id) {
|
||||
case bluetooth::SubCmd_RequestDeviceInfo:
|
||||
case SubCmd_RequestDeviceInfo:
|
||||
R_TRY(this->SubCmdRequestDeviceInfo(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SpiFlashRead:
|
||||
case SubCmd_SpiFlashRead:
|
||||
R_TRY(this->SubCmdSpiFlashRead(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SpiFlashWrite:
|
||||
case SubCmd_SpiFlashWrite:
|
||||
R_TRY(this->SubCmdSpiFlashWrite(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SpiSectorErase:
|
||||
case SubCmd_SpiSectorErase:
|
||||
R_TRY(this->SubCmdSpiSectorErase(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetInputReportMode:
|
||||
case SubCmd_SetInputReportMode:
|
||||
R_TRY(this->SubCmdSetInputReportMode(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_TriggersElapsedTime:
|
||||
case SubCmd_TriggersElapsedTime:
|
||||
R_TRY(this->SubCmdTriggersElapsedTime(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetShipPowerState:
|
||||
case SubCmd_SetShipPowerState:
|
||||
R_TRY(this->SubCmdSetShipPowerState(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetMcuConfig:
|
||||
case SubCmd_SetMcuConfig:
|
||||
R_TRY(this->SubCmdSetMcuConfig(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetMcuState:
|
||||
case SubCmd_SetMcuState:
|
||||
R_TRY(this->SubCmdSetMcuState(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetPlayerLeds:
|
||||
case SubCmd_SetPlayerLeds:
|
||||
R_TRY(this->SubCmdSetPlayerLeds(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_SetHomeLed:
|
||||
case SubCmd_SetHomeLed:
|
||||
R_TRY(this->SubCmdSetHomeLed(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_EnableImu:
|
||||
case SubCmd_EnableImu:
|
||||
R_TRY(this->SubCmdEnableImu(report));
|
||||
break;
|
||||
case bluetooth::SubCmd_EnableVibration:
|
||||
case SubCmd_EnableVibration:
|
||||
R_TRY(this->SubCmdEnableVibration(report));
|
||||
break;
|
||||
default:
|
||||
|
@ -121,7 +121,7 @@ namespace ams::controller {
|
|||
uint32_t read_addr = *(uint32_t *)(&report->data[11]);
|
||||
uint8_t read_size = report->data[15];
|
||||
|
||||
const uint8_t prefix[] = {0x90, bluetooth::SubCmd_SpiFlashRead, report->data[11], report->data[12], report->data[13], report->data[14], report->data[15]};
|
||||
const uint8_t prefix[] = {0x90, SubCmd_SpiFlashRead, report->data[11], report->data[12], report->data[13], report->data[14], report->data[15]};
|
||||
|
||||
int response_size = read_size + sizeof(prefix);
|
||||
auto response = std::make_unique<uint8_t[]>(response_size);
|
||||
|
@ -137,37 +137,37 @@ namespace ams::controller {
|
|||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSpiFlashWrite(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SpiFlashWrite, 0x01};
|
||||
const uint8_t response[] = {0x80, SubCmd_SpiFlashWrite, 0x01};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSpiSectorErase(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SpiSectorErase, 0x01};
|
||||
const uint8_t response[] = {0x80, SubCmd_SpiSectorErase, 0x01};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSetInputReportMode(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetInputReportMode};
|
||||
const uint8_t response[] = {0x80, SubCmd_SetInputReportMode};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdTriggersElapsedTime(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x83, bluetooth::SubCmd_TriggersElapsedTime};
|
||||
const uint8_t response[] = {0x83, SubCmd_TriggersElapsedTime};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSetShipPowerState(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetShipPowerState, 0x00};
|
||||
const uint8_t response[] = {0x80, SubCmd_SetShipPowerState, 0x00};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSetMcuConfig(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0xa0, bluetooth::SubCmd_SetMcuConfig, 0x01, 0x00, 0xff, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c};
|
||||
const uint8_t response[] = {0xa0, SubCmd_SetMcuConfig, 0x01, 0x00, 0xff, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSetMcuState(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetMcuState};
|
||||
const uint8_t response[] = {0x80, SubCmd_SetMcuState};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
|
@ -176,22 +176,22 @@ namespace ams::controller {
|
|||
uint8_t led_mask = subCmd[1];
|
||||
R_TRY(this->SetPlayerLed(led_mask));
|
||||
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetPlayerLeds};
|
||||
const uint8_t response[] = {0x80, SubCmd_SetPlayerLeds};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdSetHomeLed(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_SetHomeLed};
|
||||
const uint8_t response[] = {0x80, SubCmd_SetHomeLed};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdEnableImu(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_EnableImu};
|
||||
const uint8_t response[] = {0x80, SubCmd_EnableImu};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
Result EmulatedSwitchController::SubCmdEnableVibration(const bluetooth::HidReport *report) {
|
||||
const uint8_t response[] = {0x80, bluetooth::SubCmd_EnableVibration};
|
||||
const uint8_t response[] = {0x80, SubCmd_EnableVibration};
|
||||
return this->FakeSubCmdResponse(response, sizeof(response));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../bluetooth/bluetooth_types.hpp"
|
||||
#include "../bluetooth/bluetooth_hid_report.hpp"
|
||||
#include "../btdrv_mitm/bluetooth/bluetooth_types.hpp"
|
||||
#include "../btdrv_mitm/bluetooth/bluetooth_hid_report.hpp"
|
||||
|
||||
namespace ams::controller {
|
||||
|
||||
|
@ -68,6 +68,32 @@ namespace ams::controller {
|
|||
uint16_t gyro_3;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
enum SubCmdType : u8 {
|
||||
SubCmd_GetControllerState = 0x00,
|
||||
SubCmd_ManualPair = 0x01,
|
||||
SubCmd_RequestDeviceInfo = 0x02,
|
||||
SubCmd_SetInputReportMode = 0x03,
|
||||
SubCmd_TriggersElapsedTime = 0x04,
|
||||
SubCmd_SetHciState = 0x06,
|
||||
SubCmd_ResetPairingInfo = 0x07,
|
||||
SubCmd_SetShipPowerState = 0x08,
|
||||
SubCmd_SpiFlashRead = 0x10,
|
||||
SubCmd_SpiFlashWrite = 0x11,
|
||||
SubCmd_SpiSectorErase = 0x12,
|
||||
SubCmd_ResetMcu = 0x20,
|
||||
SubCmd_SetMcuConfig = 0x21,
|
||||
SubCmd_SetMcuState = 0x22,
|
||||
SubCmd_SetPlayerLeds = 0x30,
|
||||
SubCmd_GetPlayerLeds = 0x31,
|
||||
SubCmd_SetHomeLed = 0x38,
|
||||
SubCmd_EnableImu = 0x40,
|
||||
SubCmd_SetImuSensitivity = 0x41,
|
||||
SubCmd_WriteImuRegisters = 0x42,
|
||||
SubCmd_ReadImuRegisters = 0x43,
|
||||
SubCmd_EnableVibration = 0x48,
|
||||
SubCmd_GetRegulatedVoltage = 0x50,
|
||||
};
|
||||
|
||||
struct SwitchOutputReport0x01;
|
||||
struct SwitchOutputReport0x03;
|
||||
struct SwitchOutputReport0x10;
|
||||
|
|
Loading…
Reference in a new issue