summaryrefslogtreecommitdiffstats
path: root/src/input_common/helpers/joycon_protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/joycon_protocol')
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.cpp7
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.h2
-rw-r--r--src/input_common/helpers/joycon_protocol/joycon_types.h8
-rw-r--r--src/input_common/helpers/joycon_protocol/nfc.cpp34
-rw-r--r--src/input_common/helpers/joycon_protocol/nfc.h6
5 files changed, 34 insertions, 23 deletions
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
index 2b42a4555..077d72cd0 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
@@ -236,13 +236,13 @@ DriverResult JoyconCommonProtocol::GetMCUDataResponse(ReportMode report_mode,
return DriverResult::Success;
}
-DriverResult JoyconCommonProtocol::SendMCUData(ReportMode report_mode, SubCommand sc,
+DriverResult JoyconCommonProtocol::SendMCUData(ReportMode report_mode, MCUSubCommand sc,
std::span<const u8> buffer,
MCUCommandResponse& output) {
SubCommandPacket packet{
.output_report = OutputReport::MCU_DATA,
.packet_counter = GetCounter(),
- .sub_command = sc,
+ .mcu_sub_command = sc,
.command_data = {},
};
@@ -269,8 +269,7 @@ DriverResult JoyconCommonProtocol::WaitSetMCUMode(ReportMode report_mode, MCUMod
std::size_t tries{};
do {
- const std::vector<u8> mcu_data{static_cast<u8>(MCUMode::Standby)};
- const auto result = SendMCUData(report_mode, SubCommand::STATE, mcu_data, output);
+ const auto result = SendMCUData(report_mode, MCUSubCommand::SetDeviceMode, {}, output);
if (result != DriverResult::Success) {
return result;
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.h b/src/input_common/helpers/joycon_protocol/common_protocol.h
index 62cae739a..411ec018a 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.h
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.h
@@ -156,7 +156,7 @@ public:
* @param buffer data to be send
* @returns output buffer containing the response
*/
- DriverResult SendMCUData(ReportMode report_mode, SubCommand sc, std::span<const u8> buffer,
+ DriverResult SendMCUData(ReportMode report_mode, MCUSubCommand sc, std::span<const u8> buffer,
MCUCommandResponse& output);
/**
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index dcac0e422..1c8d294b0 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -394,6 +394,7 @@ enum class DriverResult {
InvalidHandle,
NotSupported,
Disabled,
+ Delayed,
Unknown,
};
@@ -575,7 +576,6 @@ struct NFCPollingCommandData {
static_assert(sizeof(NFCPollingCommandData) == 0x05, "NFCPollingCommandData is an invalid size");
struct NFCRequestState {
- MCUSubCommand sub_command;
NFCReadCommand command_argument;
u8 packet_id;
INSERT_PADDING_BYTES(0x1);
@@ -587,6 +587,7 @@ struct NFCRequestState {
NFCPollingCommandData nfc_polling;
};
u8 crc;
+ INSERT_PADDING_BYTES(0x1);
};
static_assert(sizeof(NFCRequestState) == 0x26, "NFCRequestState is an invalid size");
@@ -659,7 +660,10 @@ struct SubCommandPacket {
OutputReport output_report;
u8 packet_counter;
INSERT_PADDING_BYTES(0x8); // This contains vibration data
- SubCommand sub_command;
+ union {
+ SubCommand sub_command;
+ MCUSubCommand mcu_sub_command;
+ };
std::array<u8, 0x26> command_data;
};
static_assert(sizeof(SubCommandPacket) == 0x31, "SubCommandPacket is an invalid size");
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp
index eeba82986..14818ae33 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.cpp
+++ b/src/input_common/helpers/joycon_protocol/nfc.cpp
@@ -72,6 +72,11 @@ DriverResult NfcProtocol::StartNFCPollingMode() {
}
DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
+ if (update_counter++ < AMIIBO_UPDATE_DELAY) {
+ return DriverResult::Delayed;
+ }
+ update_counter = 0;
+
LOG_DEBUG(Input, "Start NFC pooling Mode");
ScopedSetBlocking sb(this);
DriverResult result{DriverResult::Success};
@@ -87,7 +92,7 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
result = WaitUntilNfcIsReady();
}
if (result == DriverResult::Success) {
- result = StartPolling(tag_data);
+ result = StartPolling(tag_data, 7);
}
if (result == DriverResult::Success) {
result = GetAmiiboData(data);
@@ -129,9 +134,8 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() {
return DriverResult::Success;
}
-DriverResult NfcProtocol::StartPolling(TagFoundData& data) {
+DriverResult NfcProtocol::StartPolling(TagFoundData& data, std::size_t timeout_limit) {
LOG_DEBUG(Input, "Start Polling for tag");
- constexpr std::size_t timeout_limit = 7;
MCUCommandResponse output{};
std::size_t tries = 0;
@@ -278,7 +282,6 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) {
NFCRequestState request{
- .sub_command = MCUSubCommand::ReadDeviceMode,
.command_argument = NFCReadCommand::StartPolling,
.packet_id = 0x0,
.packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -296,13 +299,13 @@ DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) {
std::array<u8, sizeof(NFCRequestState)> request_data{};
memcpy(request_data.data(), &request, sizeof(NFCRequestState));
- request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
- return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+ request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+ return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+ output);
}
DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) {
NFCRequestState request{
- .sub_command = MCUSubCommand::ReadDeviceMode,
.command_argument = NFCReadCommand::StopPolling,
.packet_id = 0x0,
.packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -313,13 +316,13 @@ DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) {
std::array<u8, sizeof(NFCRequestState)> request_data{};
memcpy(request_data.data(), &request, sizeof(NFCRequestState));
- request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
- return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+ request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+ return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+ output);
}
DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& output) {
NFCRequestState request{
- .sub_command = MCUSubCommand::ReadDeviceMode,
.command_argument = NFCReadCommand::StartWaitingRecieve,
.packet_id = 0x0,
.packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -330,13 +333,13 @@ DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& out
std::vector<u8> request_data(sizeof(NFCRequestState));
memcpy(request_data.data(), &request, sizeof(NFCRequestState));
- request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
- return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+ request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+ return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+ output);
}
DriverResult NfcProtocol::SendReadAmiiboRequest(MCUCommandResponse& output, NFCPages ntag_pages) {
NFCRequestState request{
- .sub_command = MCUSubCommand::ReadDeviceMode,
.command_argument = NFCReadCommand::Ntag,
.packet_id = 0x0,
.packet_flag = MCUPacketFlag::LastCommandPacket,
@@ -355,8 +358,9 @@ DriverResult NfcProtocol::SendReadAmiiboRequest(MCUCommandResponse& output, NFCP
std::array<u8, sizeof(NFCRequestState)> request_data{};
memcpy(request_data.data(), &request, sizeof(NFCRequestState));
- request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
- return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, SubCommand::STATE, request_data, output);
+ request_data[36] = CalculateMCU_CRC8(request_data.data(), 36);
+ return SendMCUData(ReportMode::NFC_IR_MODE_60HZ, MCUSubCommand::ReadDeviceMode, request_data,
+ output);
}
NFCReadBlockCommand NfcProtocol::GetReadBlockCommand(NFCPages pages) const {
diff --git a/src/input_common/helpers/joycon_protocol/nfc.h b/src/input_common/helpers/joycon_protocol/nfc.h
index 11e263e07..4cb992d1d 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.h
+++ b/src/input_common/helpers/joycon_protocol/nfc.h
@@ -32,6 +32,9 @@ public:
bool IsEnabled() const;
private:
+ // Number of times the function will be delayed until it outputs valid data
+ static constexpr std::size_t AMIIBO_UPDATE_DELAY = 15;
+
struct TagFoundData {
u8 type;
std::vector<u8> uuid;
@@ -39,7 +42,7 @@ private:
DriverResult WaitUntilNfcIsReady();
- DriverResult StartPolling(TagFoundData& data);
+ DriverResult StartPolling(TagFoundData& data, std::size_t timeout_limit = 1);
DriverResult ReadTag(const TagFoundData& data);
@@ -56,6 +59,7 @@ private:
NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const;
bool is_enabled{};
+ std::size_t update_counter{};
};
} // namespace InputCommon::Joycon