summaryrefslogtreecommitdiff
path: root/src/input_common/helpers/joycon_protocol/common_protocol.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/joycon_protocol/common_protocol.h')
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.h b/src/input_common/helpers/joycon_protocol/common_protocol.h
new file mode 100644
index 000000000..a65e4aa76
--- /dev/null
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.h
@@ -0,0 +1,146 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// Based on dkms-hid-nintendo implementation, CTCaer joycon toolkit and dekuNukem reverse
5// engineering https://github.com/nicman23/dkms-hid-nintendo/blob/master/src/hid-nintendo.c
6// https://github.com/CTCaer/jc_toolkit
7// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering
8
9#pragma once
10
11#include <memory>
12#include <span>
13#include <vector>
14
15#include "common/common_types.h"
16#include "input_common/helpers/joycon_protocol/joycon_types.h"
17
18namespace InputCommon::Joycon {
19
20/// Joycon driver functions that handle low level communication
21class JoyconCommonProtocol {
22public:
23 explicit JoyconCommonProtocol(std::shared_ptr<JoyconHandle> hidapi_handle_);
24
25 /**
26 * Sets handle to blocking. In blocking mode, SDL_hid_read() will wait (block) until there is
27 * data to read before returning.
28 */
29 void SetBlocking();
30
31 /**
32 * Sets handle to non blocking. In non-blocking mode calls to SDL_hid_read() will return
33 * immediately with a value of 0 if there is no data to be read
34 */
35 void SetNonBlocking();
36
37 /**
38 * Sends a request to obtain the joycon type from device
39 * @returns controller type of the joycon
40 */
41 DriverResult GetDeviceType(ControllerType& controller_type);
42
43 /**
44 * Verifies and sets the joycon_handle if device is valid
45 * @param device info from the driver
46 * @returns success if the device is valid
47 */
48 DriverResult CheckDeviceAccess(SDL_hid_device_info* device);
49
50 /**
51 * Sends a request to set the polling mode of the joycon
52 * @param report_mode polling mode to be set
53 */
54 DriverResult SetReportMode(Joycon::ReportMode report_mode);
55
56 /**
57 * Sends data to the joycon device
58 * @param buffer data to be send
59 */
60 DriverResult SendData(std::span<const u8> buffer);
61
62 /**
63 * Waits for incoming data of the joycon device that matchs the subcommand
64 * @param sub_command type of data to be returned
65 * @returns a buffer containing the responce
66 */
67 DriverResult GetSubCommandResponse(SubCommand sub_command, std::vector<u8>& output);
68
69 /**
70 * Sends a sub command to the device and waits for it's reply
71 * @param sc sub command to be send
72 * @param buffer data to be send
73 * @returns output buffer containing the responce
74 */
75 DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output);
76
77 /**
78 * Sends vibration data to the joycon
79 * @param buffer data to be send
80 */
81 DriverResult SendVibrationReport(std::span<const u8> buffer);
82
83 /**
84 * Reads the SPI memory stored on the joycon
85 * @param Initial address location
86 * @param size in bytes to be read
87 * @returns output buffer containing the responce
88 */
89 DriverResult ReadSPI(CalAddr addr, u8 size, std::vector<u8>& output);
90
91 /**
92 * Enables MCU chip on the joycon
93 * @param enable if true the chip will be enabled
94 */
95 DriverResult EnableMCU(bool enable);
96
97 /**
98 * Configures the MCU to the correspoinding mode
99 * @param MCUConfig configuration
100 */
101 DriverResult ConfigureMCU(const MCUConfig& config);
102
103 /**
104 * Waits until there's MCU data available. On timeout returns error
105 * @param report mode of the expected reply
106 * @returns a buffer containing the responce
107 */
108 DriverResult GetMCUDataResponse(ReportMode report_mode_, std::vector<u8>& output);
109
110 /**
111 * Sends data to the MCU chip and waits for it's reply
112 * @param report mode of the expected reply
113 * @param sub command to be send
114 * @param buffer data to be send
115 * @returns output buffer containing the responce
116 */
117 DriverResult SendMCUData(ReportMode report_mode, SubCommand sc, std::span<const u8> buffer,
118 std::vector<u8>& output);
119
120 /**
121 * Wait's until the MCU chip is on the specified mode
122 * @param report mode of the expected reply
123 * @param MCUMode configuration
124 */
125 DriverResult WaitSetMCUMode(ReportMode report_mode, MCUMode mode);
126
127 /**
128 * Calculates the checksum from the MCU data
129 * @param buffer containing the data to be send
130 * @param size of the buffer in bytes
131 * @returns byte with the correct checksum
132 */
133 u8 CalculateMCU_CRC8(u8* buffer, u8 size) const;
134
135private:
136 /**
137 * Increments and returns the packet counter of the handle
138 * @param joycon_handle device to send the data
139 * @returns packet counter value
140 */
141 u8 GetCounter();
142
143 std::shared_ptr<JoyconHandle> hidapi_handle;
144};
145
146} // namespace InputCommon::Joycon