input_common: Address byte review
This commit is contained in:
		| @@ -60,15 +60,12 @@ void Joycons::Setup() { | |||||||
|         device = std::make_shared<Joycon::JoyconDriver>(port++); |         device = std::make_shared<Joycon::JoyconDriver>(port++); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!scan_thread_running) { |  | ||||||
|     scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); }); |     scan_thread = std::jthread([this](std::stop_token stop_token) { ScanThread(stop_token); }); | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Joycons::ScanThread(std::stop_token stop_token) { | void Joycons::ScanThread(std::stop_token stop_token) { | ||||||
|     constexpr u16 nintendo_vendor_id = 0x057e; |     constexpr u16 nintendo_vendor_id = 0x057e; | ||||||
|     Common::SetCurrentThreadName("yuzu:input:JoyconScanThread"); |     Common::SetCurrentThreadName("JoyconScanThread"); | ||||||
|     scan_thread_running = true; |  | ||||||
|     while (!stop_token.stop_requested()) { |     while (!stop_token.stop_requested()) { | ||||||
|         SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0); |         SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0); | ||||||
|         SDL_hid_device_info* cur_dev = devs; |         SDL_hid_device_info* cur_dev = devs; | ||||||
| @@ -82,9 +79,9 @@ void Joycons::ScanThread(std::stop_token stop_token) { | |||||||
|             cur_dev = cur_dev->next; |             cur_dev = cur_dev->next; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         SDL_hid_free_enumeration(devs); | ||||||
|         std::this_thread::sleep_for(std::chrono::seconds(5)); |         std::this_thread::sleep_for(std::chrono::seconds(5)); | ||||||
|     } |     } | ||||||
|     scan_thread_running = false; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { | bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { | ||||||
| @@ -185,19 +182,19 @@ void Joycons::RegisterNewDevice(SDL_hid_device_info* device_info) { | |||||||
|  |  | ||||||
| std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle( | std::shared_ptr<Joycon::JoyconDriver> Joycons::GetNextFreeHandle( | ||||||
|     Joycon::ControllerType type) const { |     Joycon::ControllerType type) const { | ||||||
|  |  | ||||||
|     if (type == Joycon::ControllerType::Left) { |     if (type == Joycon::ControllerType::Left) { | ||||||
|         for (const auto& device : left_joycons) { |         const auto unconnected_device = | ||||||
|             if (!device->IsConnected()) { |             std::ranges::find_if(left_joycons, [](auto& device) { return !device->IsConnected(); }); | ||||||
|                 return device; |         if (unconnected_device != left_joycons.end()) { | ||||||
|             } |             return *unconnected_device; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (type == Joycon::ControllerType::Right) { |     if (type == Joycon::ControllerType::Right) { | ||||||
|         for (const auto& device : right_joycons) { |         const auto unconnected_device = std::ranges::find_if( | ||||||
|             if (!device->IsConnected()) { |             right_joycons, [](auto& device) { return !device->IsConnected(); }); | ||||||
|                 return device; |  | ||||||
|             } |         if (unconnected_device != right_joycons.end()) { | ||||||
|  |             return *unconnected_device; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| @@ -391,20 +388,25 @@ std::shared_ptr<Joycon::JoyconDriver> Joycons::GetHandle(PadIdentifier identifie | |||||||
|         return false; |         return false; | ||||||
|     }; |     }; | ||||||
|     const auto type = static_cast<Joycon::ControllerType>(identifier.pad); |     const auto type = static_cast<Joycon::ControllerType>(identifier.pad); | ||||||
|  |  | ||||||
|     if (type == Joycon::ControllerType::Left) { |     if (type == Joycon::ControllerType::Left) { | ||||||
|         for (const auto& device : left_joycons) { |         const auto matching_device = std::ranges::find_if( | ||||||
|             if (is_handle_active(device)) { |             left_joycons, [is_handle_active](auto& device) { return is_handle_active(device); }); | ||||||
|                 return device; |  | ||||||
|             } |         if (matching_device != left_joycons.end()) { | ||||||
|  |             return *matching_device; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (type == Joycon::ControllerType::Right) { |     if (type == Joycon::ControllerType::Right) { | ||||||
|         for (const auto& device : right_joycons) { |         const auto matching_device = std::ranges::find_if( | ||||||
|             if (is_handle_active(device)) { |             right_joycons, [is_handle_active](auto& device) { return is_handle_active(device); }); | ||||||
|                 return device; |  | ||||||
|             } |         if (matching_device != right_joycons.end()) { | ||||||
|  |             return *matching_device; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -676,7 +678,7 @@ std::string Joycons::JoyconName(Joycon::ControllerType type) const { | |||||||
|     case Joycon::ControllerType::Dual: |     case Joycon::ControllerType::Dual: | ||||||
|         return "Dual Joycon"; |         return "Dual Joycon"; | ||||||
|     default: |     default: | ||||||
|         return "Unknow Joycon"; |         return "Unknown Joycon"; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| } // namespace InputCommon | } // namespace InputCommon | ||||||
|   | |||||||
| @@ -99,7 +99,6 @@ private: | |||||||
|     std::string JoyconName(Joycon::ControllerType type) const; |     std::string JoyconName(Joycon::ControllerType type) const; | ||||||
|  |  | ||||||
|     std::jthread scan_thread; |     std::jthread scan_thread; | ||||||
|     bool scan_thread_running{}; |  | ||||||
|  |  | ||||||
|     // Joycon types are split by type to ease supporting dualjoycon configurations |     // Joycon types are split by type to ease supporting dualjoycon configurations | ||||||
|     std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{}; |     std::array<std::shared_ptr<Joycon::JoyconDriver>, MaxSupportedControllers> left_joycons{}; | ||||||
|   | |||||||
| @@ -321,7 +321,7 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||||||
|     if (Settings::values.enable_joycon_driver) { |     if (Settings::values.enable_joycon_driver) { | ||||||
|         if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && |         if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && | ||||||
|             (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { |             (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { | ||||||
|             LOG_ERROR(Input, "Device black listed {}", joystick_index); |             LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); | ||||||
|             SDL_JoystickClose(sdl_joystick); |             SDL_JoystickClose(sdl_joystick); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ DriverResult JoyconDriver::InitializeDevice() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void JoyconDriver::InputThread(std::stop_token stop_token) { | void JoyconDriver::InputThread(std::stop_token stop_token) { | ||||||
|     LOG_INFO(Input, "JC Adapter input thread started"); |     LOG_INFO(Input, "Joycon Adapter input thread started"); | ||||||
|     Common::SetCurrentThreadName("JoyconInput"); |     Common::SetCurrentThreadName("JoyconInput"); | ||||||
|     input_thread_running = true; |     input_thread_running = true; | ||||||
|  |  | ||||||
| @@ -157,7 +157,7 @@ void JoyconDriver::InputThread(std::stop_token stop_token) { | |||||||
|  |  | ||||||
|     is_connected = false; |     is_connected = false; | ||||||
|     input_thread_running = false; |     input_thread_running = false; | ||||||
|     LOG_INFO(Input, "JC Adapter input thread stopped"); |     LOG_INFO(Input, "Joycon Adapter input thread stopped"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void JoyconDriver::OnNewData(std::span<u8> buffer) { | void JoyconDriver::OnNewData(std::span<u8> buffer) { | ||||||
| @@ -349,7 +349,7 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool JoyconDriver::IsInputThreadValid() const { | bool JoyconDriver::IsInputThreadValid() const { | ||||||
|     if (!is_connected) { |     if (!is_connected.load()) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     if (hidapi_handle->handle == nullptr) { |     if (hidapi_handle->handle == nullptr) { | ||||||
| @@ -491,7 +491,7 @@ DriverResult JoyconDriver::SetRingConMode() { | |||||||
|  |  | ||||||
| bool JoyconDriver::IsConnected() const { | bool JoyconDriver::IsConnected() const { | ||||||
|     std::scoped_lock lock{mutex}; |     std::scoped_lock lock{mutex}; | ||||||
|     return is_connected; |     return is_connected.load(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool JoyconDriver::IsVibrationEnabled() const { | bool JoyconDriver::IsVibrationEnabled() const { | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include <atomic> | ||||||
| #include <functional> | #include <functional> | ||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <span> | #include <span> | ||||||
| @@ -97,7 +98,7 @@ private: | |||||||
|     std::unique_ptr<RumbleProtocol> rumble_protocol; |     std::unique_ptr<RumbleProtocol> rumble_protocol; | ||||||
|  |  | ||||||
|     // Connection status |     // Connection status | ||||||
|     bool is_connected{}; |     std::atomic<bool> is_connected{}; | ||||||
|     u64 delta_time; |     u64 delta_time; | ||||||
|     std::size_t error_counter{}; |     std::size_t error_counter{}; | ||||||
|     std::shared_ptr<JoyconHandle> hidapi_handle; |     std::shared_ptr<JoyconHandle> hidapi_handle; | ||||||
|   | |||||||
| @@ -12,10 +12,10 @@ CalibrationProtocol::CalibrationProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|     : JoyconCommonProtocol(std::move(handle)) {} |     : JoyconCommonProtocol(std::move(handle)) {} | ||||||
|  |  | ||||||
| DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) { | DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> buffer; |     std::vector<u8> buffer; | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     calibration = {}; |     calibration = {}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     result = ReadSPI(CalAddr::USER_LEFT_MAGIC, sizeof(u16), buffer); |     result = ReadSPI(CalAddr::USER_LEFT_MAGIC, sizeof(u16), buffer); | ||||||
|  |  | ||||||
| @@ -44,15 +44,14 @@ DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration | |||||||
|     // Set a valid default calibration if data is missing |     // Set a valid default calibration if data is missing | ||||||
|     ValidateCalibration(calibration); |     ValidateCalibration(calibration); | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) { | DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> buffer; |     std::vector<u8> buffer; | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     calibration = {}; |     calibration = {}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     result = ReadSPI(CalAddr::USER_RIGHT_MAGIC, sizeof(u16), buffer); |     result = ReadSPI(CalAddr::USER_RIGHT_MAGIC, sizeof(u16), buffer); | ||||||
|  |  | ||||||
| @@ -81,15 +80,14 @@ DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibratio | |||||||
|     // Set a valid default calibration if data is missing |     // Set a valid default calibration if data is missing | ||||||
|     ValidateCalibration(calibration); |     ValidateCalibration(calibration); | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) { | DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> buffer; |     std::vector<u8> buffer; | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     calibration = {}; |     calibration = {}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     result = ReadSPI(CalAddr::USER_IMU_MAGIC, sizeof(u16), buffer); |     result = ReadSPI(CalAddr::USER_IMU_MAGIC, sizeof(u16), buffer); | ||||||
|  |  | ||||||
| @@ -124,7 +122,6 @@ DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibrati | |||||||
|  |  | ||||||
|     ValidateCalibration(calibration); |     ValidateCalibration(calibration); | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -58,9 +58,8 @@ DriverResult JoyconCommonProtocol::CheckDeviceAccess(SDL_hid_device_info* device | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult JoyconCommonProtocol::SetReportMode(ReportMode report_mode) { | DriverResult JoyconCommonProtocol::SetReportMode(ReportMode report_mode) { | ||||||
|     const std::vector<u8> buffer{static_cast<u8>(report_mode)}; |     const std::array<u8, 1> buffer{static_cast<u8>(report_mode)}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::SET_REPORT_MODE, buffer); | ||||||
|     return SendSubCommand(SubCommand::SET_REPORT_MODE, buffer, output); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult JoyconCommonProtocol::SendData(std::span<const u8> buffer) { | DriverResult JoyconCommonProtocol::SendData(std::span<const u8> buffer) { | ||||||
| @@ -120,7 +119,12 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const | |||||||
|     return DriverResult::Success; |     return DriverResult::Success; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult JoyconCommonProtocol::SendMcuCommand(SubCommand sc, std::span<const u8> buffer) { | DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) { | ||||||
|  |     std::vector<u8> output; | ||||||
|  |     return SendSubCommand(sc, buffer, output); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | DriverResult JoyconCommonProtocol::SendMCUCommand(SubCommand sc, std::span<const u8> buffer) { | ||||||
|     std::vector<u8> local_buffer(MaxResponseSize); |     std::vector<u8> local_buffer(MaxResponseSize); | ||||||
|  |  | ||||||
|     local_buffer[0] = static_cast<u8>(OutputReport::MCU_DATA); |     local_buffer[0] = static_cast<u8>(OutputReport::MCU_DATA); | ||||||
| @@ -147,7 +151,7 @@ DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffe | |||||||
| DriverResult JoyconCommonProtocol::ReadSPI(CalAddr addr, u8 size, std::vector<u8>& output) { | DriverResult JoyconCommonProtocol::ReadSPI(CalAddr addr, u8 size, std::vector<u8>& output) { | ||||||
|     constexpr std::size_t MaxTries = 10; |     constexpr std::size_t MaxTries = 10; | ||||||
|     std::size_t tries = 0; |     std::size_t tries = 0; | ||||||
|     std::vector<u8> buffer = {0x00, 0x00, 0x00, 0x00, size}; |     std::array<u8, 5> buffer = {0x00, 0x00, 0x00, 0x00, size}; | ||||||
|     std::vector<u8> local_buffer(size + 20); |     std::vector<u8> local_buffer(size + 20); | ||||||
|  |  | ||||||
|     buffer[0] = static_cast<u8>(static_cast<u16>(addr) & 0x00FF); |     buffer[0] = static_cast<u8>(static_cast<u16>(addr) & 0x00FF); | ||||||
| @@ -169,10 +173,8 @@ DriverResult JoyconCommonProtocol::ReadSPI(CalAddr addr, u8 size, std::vector<u8 | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult JoyconCommonProtocol::EnableMCU(bool enable) { | DriverResult JoyconCommonProtocol::EnableMCU(bool enable) { | ||||||
|     std::vector<u8> output; |     const std::array<u8, 1> mcu_state{static_cast<u8>(enable ? 1 : 0)}; | ||||||
|  |     const auto result = SendSubCommand(SubCommand::SET_MCU_STATE, mcu_state); | ||||||
|     const std::vector<u8> mcu_state{static_cast<u8>(enable ? 1 : 0)}; |  | ||||||
|     const auto result = SendSubCommand(SubCommand::SET_MCU_STATE, mcu_state, output); |  | ||||||
|  |  | ||||||
|     if (result != DriverResult::Success) { |     if (result != DriverResult::Success) { | ||||||
|         LOG_ERROR(Input, "SendMCUData failed with error {}", result); |         LOG_ERROR(Input, "SendMCUData failed with error {}", result); | ||||||
| @@ -183,13 +185,11 @@ DriverResult JoyconCommonProtocol::EnableMCU(bool enable) { | |||||||
|  |  | ||||||
| DriverResult JoyconCommonProtocol::ConfigureMCU(const MCUConfig& config) { | DriverResult JoyconCommonProtocol::ConfigureMCU(const MCUConfig& config) { | ||||||
|     LOG_DEBUG(Input, "ConfigureMCU"); |     LOG_DEBUG(Input, "ConfigureMCU"); | ||||||
|     std::vector<u8> output; |  | ||||||
|  |  | ||||||
|     std::array<u8, sizeof(MCUConfig)> config_buffer; |     std::array<u8, sizeof(MCUConfig)> config_buffer; | ||||||
|     memcpy(config_buffer.data(), &config, sizeof(MCUConfig)); |     memcpy(config_buffer.data(), &config, sizeof(MCUConfig)); | ||||||
|     config_buffer[37] = CalculateMCU_CRC8(config_buffer.data() + 1, 36); |     config_buffer[37] = CalculateMCU_CRC8(config_buffer.data() + 1, 36); | ||||||
|  |  | ||||||
|     const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, config_buffer, output); |     const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, config_buffer); | ||||||
|  |  | ||||||
|     if (result != DriverResult::Success) { |     if (result != DriverResult::Success) { | ||||||
|         LOG_ERROR(Input, "Set MCU config failed with error {}", result); |         LOG_ERROR(Input, "Set MCU config failed with error {}", result); | ||||||
|   | |||||||
| @@ -74,12 +74,19 @@ public: | |||||||
|      */ |      */ | ||||||
|     DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output); |     DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sends a sub command to the device and waits for it's reply and ignores the output | ||||||
|  |      * @param sc sub command to be send | ||||||
|  |      * @param buffer data to be send | ||||||
|  |      */ | ||||||
|  |     DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sends a mcu command to the device |      * Sends a mcu command to the device | ||||||
|      * @param sc sub command to be send |      * @param sc sub command to be send | ||||||
|      * @param buffer data to be send |      * @param buffer data to be send | ||||||
|      */ |      */ | ||||||
|     DriverResult SendMcuCommand(SubCommand sc, std::span<const u8> buffer); |     DriverResult SendMCUCommand(SubCommand sc, std::span<const u8> buffer); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sends vibration data to the joycon |      * Sends vibration data to the joycon | ||||||
| @@ -150,4 +157,17 @@ private: | |||||||
|     std::shared_ptr<JoyconHandle> hidapi_handle; |     std::shared_ptr<JoyconHandle> hidapi_handle; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | class ScopedSetBlocking { | ||||||
|  | public: | ||||||
|  |     explicit ScopedSetBlocking(JoyconCommonProtocol* self) : m_self{self} { | ||||||
|  |         m_self->SetBlocking(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ~ScopedSetBlocking() { | ||||||
|  |         m_self->SetNonBlocking(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     JoyconCommonProtocol* m_self{}; | ||||||
|  | }; | ||||||
| } // namespace InputCommon::Joycon | } // namespace InputCommon::Joycon | ||||||
|   | |||||||
| @@ -10,22 +10,18 @@ GenericProtocol::GenericProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|     : JoyconCommonProtocol(std::move(handle)) {} |     : JoyconCommonProtocol(std::move(handle)) {} | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::EnablePassiveMode() { | DriverResult GenericProtocol::EnablePassiveMode() { | ||||||
|     SetBlocking(); |     ScopedSetBlocking sb(this); | ||||||
|     const auto result = SetReportMode(ReportMode::SIMPLE_HID_MODE); |     return SetReportMode(ReportMode::SIMPLE_HID_MODE); | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::EnableActiveMode() { | DriverResult GenericProtocol::EnableActiveMode() { | ||||||
|     SetBlocking(); |     ScopedSetBlocking sb(this); | ||||||
|     const auto result = SetReportMode(ReportMode::STANDARD_FULL_60HZ); |     return SetReportMode(ReportMode::STANDARD_FULL_60HZ); | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::GetDeviceInfo(DeviceInfo& device_info) { | DriverResult GenericProtocol::GetDeviceInfo(DeviceInfo& device_info) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> output; |     std::vector<u8> output; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     const auto result = SendSubCommand(SubCommand::REQ_DEV_INFO, {}, output); |     const auto result = SendSubCommand(SubCommand::REQ_DEV_INFO, {}, output); | ||||||
|  |  | ||||||
| @@ -34,7 +30,6 @@ DriverResult GenericProtocol::GetDeviceInfo(DeviceInfo& device_info) { | |||||||
|         memcpy(&device_info, output.data(), sizeof(DeviceInfo)); |         memcpy(&device_info, output.data(), sizeof(DeviceInfo)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -43,36 +38,30 @@ DriverResult GenericProtocol::GetControllerType(ControllerType& controller_type) | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::EnableImu(bool enable) { | DriverResult GenericProtocol::EnableImu(bool enable) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     const std::array<u8, 1> buffer{static_cast<u8>(enable ? 1 : 0)}; |     const std::array<u8, 1> buffer{static_cast<u8>(enable ? 1 : 0)}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::ENABLE_IMU, buffer); | ||||||
|     SetBlocking(); |  | ||||||
|     const auto result = SendSubCommand(SubCommand::ENABLE_IMU, buffer, output); |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::SetImuConfig(GyroSensitivity gsen, GyroPerformance gfrec, | DriverResult GenericProtocol::SetImuConfig(GyroSensitivity gsen, GyroPerformance gfrec, | ||||||
|                                            AccelerometerSensitivity asen, |                                            AccelerometerSensitivity asen, | ||||||
|                                            AccelerometerPerformance afrec) { |                                            AccelerometerPerformance afrec) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     const std::array<u8, 4> buffer{static_cast<u8>(gsen), static_cast<u8>(asen), |     const std::array<u8, 4> buffer{static_cast<u8>(gsen), static_cast<u8>(asen), | ||||||
|                                    static_cast<u8>(gfrec), static_cast<u8>(afrec)}; |                                    static_cast<u8>(gfrec), static_cast<u8>(afrec)}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::SET_IMU_SENSITIVITY, buffer); | ||||||
|     SetBlocking(); |  | ||||||
|     const auto result = SendSubCommand(SubCommand::SET_IMU_SENSITIVITY, buffer, output); |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::GetBattery(u32& battery_level) { | DriverResult GenericProtocol::GetBattery(u32& battery_level) { | ||||||
|  |     // This function is meant to request the high resolution battery status | ||||||
|     battery_level = 0; |     battery_level = 0; | ||||||
|     return DriverResult::NotSupported; |     return DriverResult::NotSupported; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::GetColor(Color& color) { | DriverResult GenericProtocol::GetColor(Color& color) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> buffer; |     std::vector<u8> buffer; | ||||||
|     SetBlocking(); |  | ||||||
|     const auto result = ReadSPI(CalAddr::COLOR_DATA, 12, buffer); |     const auto result = ReadSPI(CalAddr::COLOR_DATA, 12, buffer); | ||||||
|     SetNonBlocking(); |  | ||||||
|  |  | ||||||
|     color = {}; |     color = {}; | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
| @@ -86,10 +75,9 @@ DriverResult GenericProtocol::GetColor(Color& color) { | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::GetSerialNumber(SerialNumber& serial_number) { | DriverResult GenericProtocol::GetSerialNumber(SerialNumber& serial_number) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     std::vector<u8> buffer; |     std::vector<u8> buffer; | ||||||
|     SetBlocking(); |  | ||||||
|     const auto result = ReadSPI(CalAddr::SERIAL_NUMBER, 16, buffer); |     const auto result = ReadSPI(CalAddr::SERIAL_NUMBER, 16, buffer); | ||||||
|     SetNonBlocking(); |  | ||||||
|  |  | ||||||
|     serial_number = {}; |     serial_number = {}; | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
| @@ -115,14 +103,9 @@ DriverResult GenericProtocol::GetVersionNumber(FirmwareVersion& version) { | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::SetHomeLight() { | DriverResult GenericProtocol::SetHomeLight() { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     static constexpr std::array<u8, 3> buffer{0x0f, 0xf0, 0x00}; |     static constexpr std::array<u8, 3> buffer{0x0f, 0xf0, 0x00}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer); | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     const auto result = SendSubCommand(SubCommand::SET_HOME_LIGHT, buffer, output); |  | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::SetLedBusy() { | DriverResult GenericProtocol::SetLedBusy() { | ||||||
| @@ -130,14 +113,9 @@ DriverResult GenericProtocol::SetLedBusy() { | |||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::SetLedPattern(u8 leds) { | DriverResult GenericProtocol::SetLedPattern(u8 leds) { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     const std::array<u8, 1> buffer{leds}; |     const std::array<u8, 1> buffer{leds}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::SET_PLAYER_LIGHTS, buffer); | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     const auto result = SendSubCommand(SubCommand::SET_PLAYER_LIGHTS, buffer, output); |  | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult GenericProtocol::SetLedBlinkPattern(u8 leds) { | DriverResult GenericProtocol::SetLedBlinkPattern(u8 leds) { | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ IrsProtocol::IrsProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|  |  | ||||||
| DriverResult IrsProtocol::EnableIrs() { | DriverResult IrsProtocol::EnableIrs() { | ||||||
|     LOG_INFO(Input, "Enable IRS"); |     LOG_INFO(Input, "Enable IRS"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ); |         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ); | ||||||
| @@ -49,14 +49,13 @@ DriverResult IrsProtocol::EnableIrs() { | |||||||
|  |  | ||||||
|     is_enabled = true; |     is_enabled = true; | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult IrsProtocol::DisableIrs() { | DriverResult IrsProtocol::DisableIrs() { | ||||||
|     LOG_DEBUG(Input, "Disable IRS"); |     LOG_DEBUG(Input, "Disable IRS"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = EnableMCU(false); |         result = EnableMCU(false); | ||||||
| @@ -64,7 +63,6 @@ DriverResult IrsProtocol::DisableIrs() { | |||||||
|  |  | ||||||
|     is_enabled = false; |     is_enabled = false; | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -148,7 +146,7 @@ DriverResult IrsProtocol::ConfigureIrs() { | |||||||
|     }; |     }; | ||||||
|     buf_image.resize((static_cast<u8>(fragments) + 1) * 300); |     buf_image.resize((static_cast<u8>(fragments) + 1) * 300); | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(IrsConfigure)); |     std::array<u8, sizeof(IrsConfigure)> request_data{}; | ||||||
|     memcpy(request_data.data(), &irs_configuration, sizeof(IrsConfigure)); |     memcpy(request_data.data(), &irs_configuration, sizeof(IrsConfigure)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|     do { |     do { | ||||||
| @@ -191,7 +189,7 @@ DriverResult IrsProtocol::WriteRegistersStep1() { | |||||||
|         .crc = {}, |         .crc = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(IrsWriteRegisters)); |     std::array<u8, sizeof(IrsWriteRegisters)> request_data{}; | ||||||
|     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters)); |     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|  |  | ||||||
| @@ -208,7 +206,7 @@ DriverResult IrsProtocol::WriteRegistersStep1() { | |||||||
|  |  | ||||||
|         // First time we need to set the report mode |         // First time we need to set the report mode | ||||||
|         if (result == DriverResult::Success && tries == 0) { |         if (result == DriverResult::Success && tries == 0) { | ||||||
|             result = SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request); |             result = SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request); | ||||||
|         } |         } | ||||||
|         if (result == DriverResult::Success && tries == 0) { |         if (result == DriverResult::Success && tries == 0) { | ||||||
|             GetSubCommandResponse(SubCommand::SET_MCU_CONFIG, output); |             GetSubCommandResponse(SubCommand::SET_MCU_CONFIG, output); | ||||||
| @@ -250,7 +248,7 @@ DriverResult IrsProtocol::WriteRegistersStep2() { | |||||||
|         .crc = {}, |         .crc = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(IrsWriteRegisters)); |     std::array<u8, sizeof(IrsWriteRegisters)> request_data{}; | ||||||
|     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters)); |     memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|     do { |     do { | ||||||
| @@ -272,7 +270,7 @@ DriverResult IrsProtocol::RequestFrame(u8 frame) { | |||||||
|     mcu_request[3] = frame; |     mcu_request[3] = frame; | ||||||
|     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36); |     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36); | ||||||
|     mcu_request[37] = 0xFF; |     mcu_request[37] = 0xFF; | ||||||
|     return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request); |     return SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request); | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult IrsProtocol::ResendFrame(u8 frame) { | DriverResult IrsProtocol::ResendFrame(u8 frame) { | ||||||
| @@ -282,7 +280,7 @@ DriverResult IrsProtocol::ResendFrame(u8 frame) { | |||||||
|     mcu_request[3] = 0x0; |     mcu_request[3] = 0x0; | ||||||
|     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36); |     mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36); | ||||||
|     mcu_request[37] = 0xFF; |     mcu_request[37] = 0xFF; | ||||||
|     return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request); |     return SendMCUCommand(SubCommand::SET_REPORT_MODE, mcu_request); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::vector<u8> IrsProtocol::GetImage() const { | std::vector<u8> IrsProtocol::GetImage() const { | ||||||
|   | |||||||
| @@ -273,6 +273,18 @@ enum class NFCTagType : u8 { | |||||||
|     Ntag215 = 0x01, |     Ntag215 = 0x01, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum class NFCPages { | ||||||
|  |     Block0 = 0, | ||||||
|  |     Block45 = 45, | ||||||
|  |     Block135 = 135, | ||||||
|  |     Block231 = 231, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum class NFCStatus : u8 { | ||||||
|  |     LastPackage = 0x04, | ||||||
|  |     TagLost = 0x07, | ||||||
|  | }; | ||||||
|  |  | ||||||
| enum class IrsMode : u8 { | enum class IrsMode : u8 { | ||||||
|     None = 0x02, |     None = 0x02, | ||||||
|     Moment = 0x03, |     Moment = 0x03, | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ NfcProtocol::NfcProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|  |  | ||||||
| DriverResult NfcProtocol::EnableNfc() { | DriverResult NfcProtocol::EnableNfc() { | ||||||
|     LOG_INFO(Input, "Enable NFC"); |     LOG_INFO(Input, "Enable NFC"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ); |         result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ); | ||||||
| @@ -35,14 +35,13 @@ DriverResult NfcProtocol::EnableNfc() { | |||||||
|         result = ConfigureMCU(config); |         result = ConfigureMCU(config); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult NfcProtocol::DisableNfc() { | DriverResult NfcProtocol::DisableNfc() { | ||||||
|     LOG_DEBUG(Input, "Disable NFC"); |     LOG_DEBUG(Input, "Disable NFC"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = EnableMCU(false); |         result = EnableMCU(false); | ||||||
| @@ -50,15 +49,14 @@ DriverResult NfcProtocol::DisableNfc() { | |||||||
|  |  | ||||||
|     is_enabled = false; |     is_enabled = false; | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult NfcProtocol::StartNFCPollingMode() { | DriverResult NfcProtocol::StartNFCPollingMode() { | ||||||
|     LOG_DEBUG(Input, "Start NFC pooling Mode"); |     LOG_DEBUG(Input, "Start NFC pooling Mode"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     TagFoundData tag_data{}; |     TagFoundData tag_data{}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = WaitSetMCUMode(ReportMode::NFC_IR_MODE_60HZ, MCUMode::NFC); |         result = WaitSetMCUMode(ReportMode::NFC_IR_MODE_60HZ, MCUMode::NFC); | ||||||
| @@ -70,15 +68,14 @@ DriverResult NfcProtocol::StartNFCPollingMode() { | |||||||
|         is_enabled = true; |         is_enabled = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { | DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { | ||||||
|     LOG_DEBUG(Input, "Start NFC pooling Mode"); |     LOG_DEBUG(Input, "Start NFC pooling Mode"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     TagFoundData tag_data{}; |     TagFoundData tag_data{}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = StartPolling(tag_data); |         result = StartPolling(tag_data); | ||||||
| @@ -96,20 +93,18 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { | |||||||
|         result = GetAmiiboData(data); |         result = GetAmiiboData(data); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool NfcProtocol::HasAmiibo() { | bool NfcProtocol::HasAmiibo() { | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     TagFoundData tag_data{}; |     TagFoundData tag_data{}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = StartPolling(tag_data); |         result = StartPolling(tag_data); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result == DriverResult::Success; |     return result == DriverResult::Success; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -169,55 +164,53 @@ DriverResult NfcProtocol::ReadTag(const TagFoundData& data) { | |||||||
|     LOG_INFO(Input, "Tag detected, type={}, uuid={}", data.type, uuid_string); |     LOG_INFO(Input, "Tag detected, type={}, uuid={}", data.type, uuid_string); | ||||||
|  |  | ||||||
|     tries = 0; |     tries = 0; | ||||||
|     std::size_t ntag_pages = 0; |     NFCPages ntag_pages = NFCPages::Block0; | ||||||
|     // Read Tag data |     // Read Tag data | ||||||
| loop1: |  | ||||||
|     while (true) { |     while (true) { | ||||||
|         auto result = SendReadAmiiboRequest(output, ntag_pages); |         auto result = SendReadAmiiboRequest(output, ntag_pages); | ||||||
|  |         const auto mcu_report = static_cast<MCUReport>(output[49]); | ||||||
|         int attempt = 0; |         const auto nfc_status = static_cast<NFCStatus>(output[56]); | ||||||
|         while (1) { |  | ||||||
|             if (attempt != 0) { |  | ||||||
|                 result = GetMCUDataResponse(ReportMode::NFC_IR_MODE_60HZ, output); |  | ||||||
|             } |  | ||||||
|             if ((output[49] == 0x3a || output[49] == 0x2a) && output[56] == 0x07) { |  | ||||||
|                 return DriverResult::ErrorReadingData; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x3a && output[51] == 0x07 && output[52] == 0x01) { |  | ||||||
|                 if (data.type != 2) { |  | ||||||
|                     goto loop1; |  | ||||||
|                 } |  | ||||||
|                 switch (output[74]) { |  | ||||||
|                 case 0: |  | ||||||
|                     ntag_pages = 135; |  | ||||||
|                     break; |  | ||||||
|                 case 3: |  | ||||||
|                     ntag_pages = 45; |  | ||||||
|                     break; |  | ||||||
|                 case 4: |  | ||||||
|                     ntag_pages = 231; |  | ||||||
|                     break; |  | ||||||
|                 default: |  | ||||||
|                     return DriverResult::ErrorReadingData; |  | ||||||
|                 } |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x2a && output[56] == 0x04) { |  | ||||||
|                 // finished |  | ||||||
|                 SendStopPollingRequest(output); |  | ||||||
|                 return DriverResult::Success; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x2a) { |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|             if (attempt++ > 6) { |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (result != DriverResult::Success) { |         if (result != DriverResult::Success) { | ||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) && | ||||||
|  |             nfc_status == NFCStatus::TagLost) { | ||||||
|  |             return DriverResult::ErrorReadingData; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07 && output[52] == 0x01) { | ||||||
|  |             if (data.type != 2) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             switch (output[74]) { | ||||||
|  |             case 0: | ||||||
|  |                 ntag_pages = NFCPages::Block135; | ||||||
|  |                 break; | ||||||
|  |             case 3: | ||||||
|  |                 ntag_pages = NFCPages::Block45; | ||||||
|  |                 break; | ||||||
|  |             case 4: | ||||||
|  |                 ntag_pages = NFCPages::Block231; | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 return DriverResult::ErrorReadingData; | ||||||
|  |             } | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { | ||||||
|  |             // finished | ||||||
|  |             SendStopPollingRequest(output); | ||||||
|  |             return DriverResult::Success; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Ignore other state reports | ||||||
|  |         if (mcu_report == MCUReport::NFCState) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (tries++ > timeout_limit) { |         if (tries++ > timeout_limit) { | ||||||
|             return DriverResult::Timeout; |             return DriverResult::Timeout; | ||||||
|         } |         } | ||||||
| @@ -231,47 +224,44 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) { | |||||||
|     std::vector<u8> output; |     std::vector<u8> output; | ||||||
|     std::size_t tries = 0; |     std::size_t tries = 0; | ||||||
|  |  | ||||||
|     std::size_t ntag_pages = 135; |     NFCPages ntag_pages = NFCPages::Block135; | ||||||
|     std::size_t ntag_buffer_pos = 0; |     std::size_t ntag_buffer_pos = 0; | ||||||
|     // Read Tag data |     // Read Tag data | ||||||
| loop1: |  | ||||||
|     while (true) { |     while (true) { | ||||||
|         auto result = SendReadAmiiboRequest(output, ntag_pages); |         auto result = SendReadAmiiboRequest(output, ntag_pages); | ||||||
|  |         const auto mcu_report = static_cast<MCUReport>(output[49]); | ||||||
|         int attempt = 0; |         const auto nfc_status = static_cast<NFCStatus>(output[56]); | ||||||
|         while (1) { |  | ||||||
|             if (attempt != 0) { |  | ||||||
|                 result = GetMCUDataResponse(ReportMode::NFC_IR_MODE_60HZ, output); |  | ||||||
|             } |  | ||||||
|             if ((output[49] == 0x3a || output[49] == 0x2a) && output[56] == 0x07) { |  | ||||||
|                 return DriverResult::ErrorReadingData; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x3a && output[51] == 0x07) { |  | ||||||
|                 std::size_t payload_size = (output[54] << 8 | output[55]) & 0x7FF; |  | ||||||
|                 if (output[52] == 0x01) { |  | ||||||
|                     memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 116, |  | ||||||
|                            payload_size - 60); |  | ||||||
|                     ntag_buffer_pos += payload_size - 60; |  | ||||||
|                 } else { |  | ||||||
|                     memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 56, payload_size); |  | ||||||
|                 } |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x2a && output[56] == 0x04) { |  | ||||||
|                 LOG_INFO(Input, "Finished reading amiibo"); |  | ||||||
|                 return DriverResult::Success; |  | ||||||
|             } |  | ||||||
|             if (output[49] == 0x2a) { |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|             if (attempt++ > 4) { |  | ||||||
|                 goto loop1; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (result != DriverResult::Success) { |         if (result != DriverResult::Success) { | ||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if ((mcu_report == MCUReport::NFCReadData || mcu_report == MCUReport::NFCState) && | ||||||
|  |             nfc_status == NFCStatus::TagLost) { | ||||||
|  |             return DriverResult::ErrorReadingData; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (mcu_report == MCUReport::NFCReadData && output[51] == 0x07) { | ||||||
|  |             std::size_t payload_size = (output[54] << 8 | output[55]) & 0x7FF; | ||||||
|  |             if (output[52] == 0x01) { | ||||||
|  |                 memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 116, payload_size - 60); | ||||||
|  |                 ntag_buffer_pos += payload_size - 60; | ||||||
|  |             } else { | ||||||
|  |                 memcpy(ntag_data.data() + ntag_buffer_pos, output.data() + 56, payload_size); | ||||||
|  |             } | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) { | ||||||
|  |             LOG_INFO(Input, "Finished reading amiibo"); | ||||||
|  |             return DriverResult::Success; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Ignore other state reports | ||||||
|  |         if (mcu_report == MCUReport::NFCState) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (tries++ > timeout_limit) { |         if (tries++ > timeout_limit) { | ||||||
|             return DriverResult::Timeout; |             return DriverResult::Timeout; | ||||||
|         } |         } | ||||||
| @@ -298,7 +288,7 @@ DriverResult NfcProtocol::SendStartPollingRequest(std::vector<u8>& output) { | |||||||
|         .crc = {}, |         .crc = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(NFCRequestState)); |     std::array<u8, sizeof(NFCRequestState)> request_data{}; | ||||||
|     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); |     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | ||||||
| @@ -315,7 +305,7 @@ DriverResult NfcProtocol::SendStopPollingRequest(std::vector<u8>& output) { | |||||||
|         .crc = {}, |         .crc = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(NFCRequestState)); |     std::array<u8, sizeof(NFCRequestState)> request_data{}; | ||||||
|     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); |     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | ||||||
| @@ -338,7 +328,7 @@ DriverResult NfcProtocol::SendStartWaitingRecieveRequest(std::vector<u8>& output | |||||||
|     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, std::size_t ntag_pages) { | DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, NFCPages ntag_pages) { | ||||||
|     NFCRequestState request{ |     NFCRequestState request{ | ||||||
|         .sub_command = MCUSubCommand::ReadDeviceMode, |         .sub_command = MCUSubCommand::ReadDeviceMode, | ||||||
|         .command_argument = NFCReadCommand::Ntag, |         .command_argument = NFCReadCommand::Ntag, | ||||||
| @@ -357,20 +347,19 @@ DriverResult NfcProtocol::SendReadAmiiboRequest(std::vector<u8>& output, std::si | |||||||
|         .crc = {}, |         .crc = {}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     std::vector<u8> request_data(sizeof(NFCRequestState)); |     std::array<u8, sizeof(NFCRequestState)> request_data{}; | ||||||
|     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); |     memcpy(request_data.data(), &request, sizeof(NFCRequestState)); | ||||||
|     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); |     request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36); | ||||||
|     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); |     return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output); | ||||||
| } | } | ||||||
|  |  | ||||||
| NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const { | NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(NFCPages pages) const { | ||||||
|     if (pages == 0) { |     switch (pages) { | ||||||
|  |     case NFCPages::Block0: | ||||||
|         return { |         return { | ||||||
|             .block_count = 1, |             .block_count = 1, | ||||||
|         }; |         }; | ||||||
|     } |     case NFCPages::Block45: | ||||||
|  |  | ||||||
|     if (pages == 45) { |  | ||||||
|         return { |         return { | ||||||
|             .block_count = 1, |             .block_count = 1, | ||||||
|             .blocks = |             .blocks = | ||||||
| @@ -378,9 +367,7 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const { | |||||||
|                     NFCReadBlock{0x00, 0x2C}, |                     NFCReadBlock{0x00, 0x2C}, | ||||||
|                 }, |                 }, | ||||||
|         }; |         }; | ||||||
|     } |     case NFCPages::Block135: | ||||||
|  |  | ||||||
|     if (pages == 135) { |  | ||||||
|         return { |         return { | ||||||
|             .block_count = 3, |             .block_count = 3, | ||||||
|             .blocks = |             .blocks = | ||||||
| @@ -390,9 +377,7 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const { | |||||||
|                     {0x78, 0x86}, |                     {0x78, 0x86}, | ||||||
|                 }, |                 }, | ||||||
|         }; |         }; | ||||||
|     } |     case NFCPages::Block231: | ||||||
|  |  | ||||||
|     if (pages == 231) { |  | ||||||
|         return { |         return { | ||||||
|             .block_count = 4, |             .block_count = 4, | ||||||
|             .blocks = |             .blocks = | ||||||
| @@ -403,9 +388,9 @@ NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(std::size_t pages) const { | |||||||
|                     {0xb4, 0xe6}, |                     {0xb4, 0xe6}, | ||||||
|                 }, |                 }, | ||||||
|         }; |         }; | ||||||
|     } |     default: | ||||||
|  |  | ||||||
|         return {}; |         return {}; | ||||||
|  |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool NfcProtocol::IsEnabled() const { | bool NfcProtocol::IsEnabled() const { | ||||||
|   | |||||||
| @@ -51,9 +51,9 @@ private: | |||||||
|  |  | ||||||
|     DriverResult SendStartWaitingRecieveRequest(std::vector<u8>& output); |     DriverResult SendStartWaitingRecieveRequest(std::vector<u8>& output); | ||||||
|  |  | ||||||
|     DriverResult SendReadAmiiboRequest(std::vector<u8>& output, std::size_t ntag_pages); |     DriverResult SendReadAmiiboRequest(std::vector<u8>& output, NFCPages ntag_pages); | ||||||
|  |  | ||||||
|     NFCReadBlockCommand GetReadBlockCommand(std::size_t pages) const; |     NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const; | ||||||
|  |  | ||||||
|     bool is_enabled{}; |     bool is_enabled{}; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -224,9 +224,9 @@ void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) { | |||||||
|         Joycon::PasivePadButton::StickL, |         Joycon::PasivePadButton::StickL, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     for (std::size_t i = 0; i < left_buttons.size(); ++i) { |     for (auto left_button : left_buttons) { | ||||||
|         const bool button_status = (input.button_input & static_cast<u32>(left_buttons[i])) != 0; |         const bool button_status = (input.button_input & static_cast<u32>(left_button)) != 0; | ||||||
|         const int button = static_cast<int>(left_buttons[i]); |         const int button = static_cast<int>(left_button); | ||||||
|         callbacks.on_button_data(button, button_status); |         callbacks.on_button_data(button, button_status); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -241,9 +241,9 @@ void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) { | |||||||
|         Joycon::PasivePadButton::StickR, |         Joycon::PasivePadButton::StickR, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     for (std::size_t i = 0; i < right_buttons.size(); ++i) { |     for (auto right_button : right_buttons) { | ||||||
|         const bool button_status = (input.button_input & static_cast<u32>(right_buttons[i])) != 0; |         const bool button_status = (input.button_input & static_cast<u32>(right_button)) != 0; | ||||||
|         const int button = static_cast<int>(right_buttons[i]); |         const int button = static_cast<int>(right_button); | ||||||
|         callbacks.on_button_data(button, button_status); |         callbacks.on_button_data(button, button_status); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -259,9 +259,9 @@ void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) { | |||||||
|         Joycon::PasivePadButton::StickL,  Joycon::PasivePadButton::StickR, |         Joycon::PasivePadButton::StickL,  Joycon::PasivePadButton::StickR, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     for (std::size_t i = 0; i < pro_buttons.size(); ++i) { |     for (auto pro_button : pro_buttons) { | ||||||
|         const bool button_status = (input.button_input & static_cast<u32>(pro_buttons[i])) != 0; |         const bool button_status = (input.button_input & static_cast<u32>(pro_button)) != 0; | ||||||
|         const int button = static_cast<int>(pro_buttons[i]); |         const int button = static_cast<int>(pro_button); | ||||||
|         callbacks.on_button_data(button, button_status); |         callbacks.on_button_data(button, button_status); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -11,8 +11,8 @@ RingConProtocol::RingConProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|  |  | ||||||
| DriverResult RingConProtocol::EnableRingCon() { | DriverResult RingConProtocol::EnableRingCon() { | ||||||
|     LOG_DEBUG(Input, "Enable Ringcon"); |     LOG_DEBUG(Input, "Enable Ringcon"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = SetReportMode(ReportMode::STANDARD_FULL_60HZ); |         result = SetReportMode(ReportMode::STANDARD_FULL_60HZ); | ||||||
| @@ -30,14 +30,13 @@ DriverResult RingConProtocol::EnableRingCon() { | |||||||
|         result = ConfigureMCU(config); |         result = ConfigureMCU(config); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult RingConProtocol::DisableRingCon() { | DriverResult RingConProtocol::DisableRingCon() { | ||||||
|     LOG_DEBUG(Input, "Disable RingCon"); |     LOG_DEBUG(Input, "Disable RingCon"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |  | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = EnableMCU(false); |         result = EnableMCU(false); | ||||||
| @@ -45,15 +44,14 @@ DriverResult RingConProtocol::DisableRingCon() { | |||||||
|  |  | ||||||
|     is_enabled = false; |     is_enabled = false; | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult RingConProtocol::StartRingconPolling() { | DriverResult RingConProtocol::StartRingconPolling() { | ||||||
|     LOG_DEBUG(Input, "Enable Ringcon"); |     LOG_DEBUG(Input, "Enable Ringcon"); | ||||||
|     bool is_connected = false; |     ScopedSetBlocking sb(this); | ||||||
|     DriverResult result{DriverResult::Success}; |     DriverResult result{DriverResult::Success}; | ||||||
|     SetBlocking(); |     bool is_connected = false; | ||||||
|  |  | ||||||
|     if (result == DriverResult::Success) { |     if (result == DriverResult::Success) { | ||||||
|         result = IsRingConnected(is_connected); |         result = IsRingConnected(is_connected); | ||||||
| @@ -66,13 +64,13 @@ DriverResult RingConProtocol::StartRingconPolling() { | |||||||
|         is_enabled = true; |         is_enabled = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult RingConProtocol::IsRingConnected(bool& is_connected) { | DriverResult RingConProtocol::IsRingConnected(bool& is_connected) { | ||||||
|     LOG_DEBUG(Input, "IsRingConnected"); |     LOG_DEBUG(Input, "IsRingConnected"); | ||||||
|     constexpr std::size_t max_tries = 28; |     constexpr std::size_t max_tries = 28; | ||||||
|  |     constexpr u8 ring_controller_id = 0x20; | ||||||
|     std::vector<u8> output; |     std::vector<u8> output; | ||||||
|     std::size_t tries = 0; |     std::size_t tries = 0; | ||||||
|     is_connected = false; |     is_connected = false; | ||||||
| @@ -88,7 +86,7 @@ DriverResult RingConProtocol::IsRingConnected(bool& is_connected) { | |||||||
|         if (tries++ >= max_tries) { |         if (tries++ >= max_tries) { | ||||||
|             return DriverResult::NoDeviceDetected; |             return DriverResult::NoDeviceDetected; | ||||||
|         } |         } | ||||||
|     } while (output[14] != 0x59 || output[16] != 0x20); |     } while (output[16] != ring_controller_id); | ||||||
|  |  | ||||||
|     is_connected = true; |     is_connected = true; | ||||||
|     return DriverResult::Success; |     return DriverResult::Success; | ||||||
| @@ -96,30 +94,20 @@ DriverResult RingConProtocol::IsRingConnected(bool& is_connected) { | |||||||
|  |  | ||||||
| DriverResult RingConProtocol::ConfigureRing() { | DriverResult RingConProtocol::ConfigureRing() { | ||||||
|     LOG_DEBUG(Input, "ConfigureRing"); |     LOG_DEBUG(Input, "ConfigureRing"); | ||||||
|     constexpr std::size_t max_tries = 28; |  | ||||||
|     DriverResult result{DriverResult::Success}; |  | ||||||
|     std::vector<u8> output; |  | ||||||
|     std::size_t tries = 0; |  | ||||||
|  |  | ||||||
|     static constexpr std::array<u8, 37> ring_config{ |     static constexpr std::array<u8, 37> ring_config{ | ||||||
|         0x06, 0x03, 0x25, 0x06, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x16, 0xED, 0x34, 0x36, |         0x06, 0x03, 0x25, 0x06, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x16, 0xED, 0x34, 0x36, | ||||||
|         0x00, 0x00, 0x00, 0x0A, 0x64, 0x0B, 0xE6, 0xA9, 0x22, 0x00, 0x00, 0x04, 0x00, |         0x00, 0x00, 0x00, 0x0A, 0x64, 0x0B, 0xE6, 0xA9, 0x22, 0x00, 0x00, 0x04, 0x00, | ||||||
|         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xA8, 0xE1, 0x34, 0x36}; |         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xA8, 0xE1, 0x34, 0x36}; | ||||||
|     do { |  | ||||||
|         result = SendSubCommand(SubCommand::UNKNOWN_RINGCON3, ring_config, output); |     const DriverResult result = SendSubCommand(SubCommand::UNKNOWN_RINGCON3, ring_config); | ||||||
|  |  | ||||||
|     if (result != DriverResult::Success) { |     if (result != DriverResult::Success) { | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|         if (tries++ >= max_tries) { |  | ||||||
|             return DriverResult::NoDeviceDetected; |  | ||||||
|         } |  | ||||||
|     } while (output[14] != 0x5C); |  | ||||||
|  |  | ||||||
|     static constexpr std::array<u8, 4> ringcon_data{0x04, 0x01, 0x01, 0x02}; |     static constexpr std::array<u8, 4> ringcon_data{0x04, 0x01, 0x01, 0x02}; | ||||||
|     result = SendSubCommand(SubCommand::UNKNOWN_RINGCON2, ringcon_data, output); |     return SendSubCommand(SubCommand::UNKNOWN_RINGCON2, ringcon_data); | ||||||
|  |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool RingConProtocol::IsEnabled() const { | bool RingConProtocol::IsEnabled() const { | ||||||
|   | |||||||
| @@ -14,12 +14,9 @@ RumbleProtocol::RumbleProtocol(std::shared_ptr<JoyconHandle> handle) | |||||||
|  |  | ||||||
| DriverResult RumbleProtocol::EnableRumble(bool is_enabled) { | DriverResult RumbleProtocol::EnableRumble(bool is_enabled) { | ||||||
|     LOG_DEBUG(Input, "Enable Rumble"); |     LOG_DEBUG(Input, "Enable Rumble"); | ||||||
|  |     ScopedSetBlocking sb(this); | ||||||
|     const std::array<u8, 1> buffer{static_cast<u8>(is_enabled ? 1 : 0)}; |     const std::array<u8, 1> buffer{static_cast<u8>(is_enabled ? 1 : 0)}; | ||||||
|     std::vector<u8> output; |     return SendSubCommand(SubCommand::ENABLE_VIBRATION, buffer); | ||||||
|     SetBlocking(); |  | ||||||
|     const auto result = SendSubCommand(SubCommand::ENABLE_VIBRATION, buffer, output); |  | ||||||
|     SetNonBlocking(); |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| DriverResult RumbleProtocol::SendVibration(const VibrationValue& vibration) { | DriverResult RumbleProtocol::SendVibration(const VibrationValue& vibration) { | ||||||
| @@ -66,9 +63,9 @@ u8 RumbleProtocol::EncodeLowFrequency(f32 frequency) const { | |||||||
| } | } | ||||||
|  |  | ||||||
| u8 RumbleProtocol::EncodeHighAmplitude(f32 amplitude) const { | u8 RumbleProtocol::EncodeHighAmplitude(f32 amplitude) const { | ||||||
|     /* More information about these values can be found here: |     // More information about these values can be found here: | ||||||
|      * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md |     // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md | ||||||
|      */ |  | ||||||
|     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{ |     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{ | ||||||
|         std::pair<f32, int>{0.0f, 0x0}, |         std::pair<f32, int>{0.0f, 0x0}, | ||||||
|         {0.01f, 0x2}, |         {0.01f, 0x2}, | ||||||
| @@ -183,9 +180,9 @@ u8 RumbleProtocol::EncodeHighAmplitude(f32 amplitude) const { | |||||||
| } | } | ||||||
|  |  | ||||||
| u16 RumbleProtocol::EncodeLowAmplitude(f32 amplitude) const { | u16 RumbleProtocol::EncodeLowAmplitude(f32 amplitude) const { | ||||||
|     /* More information about these values can be found here: |     // More information about these values can be found here: | ||||||
|      * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md |     // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md | ||||||
|      */ |  | ||||||
|     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{ |     static constexpr std::array<std::pair<f32, int>, 101> high_fequency_amplitude{ | ||||||
|         std::pair<f32, int>{0.0f, 0x0040}, |         std::pair<f32, int>{0.0f, 0x0040}, | ||||||
|         {0.01f, 0x8040}, |         {0.01f, 0x8040}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user