summaryrefslogtreecommitdiff
path: root/src/input_common/helpers/joycon_protocol/calibration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/joycon_protocol/calibration.cpp')
-rw-r--r--src/input_common/helpers/joycon_protocol/calibration.cpp210
1 files changed, 122 insertions, 88 deletions
diff --git a/src/input_common/helpers/joycon_protocol/calibration.cpp b/src/input_common/helpers/joycon_protocol/calibration.cpp
index f6e7e97d5..d8f040f75 100644
--- a/src/input_common/helpers/joycon_protocol/calibration.cpp
+++ b/src/input_common/helpers/joycon_protocol/calibration.cpp
@@ -13,33 +13,33 @@ CalibrationProtocol::CalibrationProtocol(std::shared_ptr<JoyconHandle> handle)
13 13
14DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) { 14DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) {
15 ScopedSetBlocking sb(this); 15 ScopedSetBlocking sb(this);
16 std::vector<u8> buffer;
17 DriverResult result{DriverResult::Success}; 16 DriverResult result{DriverResult::Success};
17 JoystickLeftSpiCalibration spi_calibration{};
18 bool has_user_calibration = false;
18 calibration = {}; 19 calibration = {};
19 20
20 result = ReadSPI(CalAddr::USER_LEFT_MAGIC, sizeof(u16), buffer);
21
22 if (result == DriverResult::Success) { 21 if (result == DriverResult::Success) {
23 const bool has_user_calibration = buffer[0] == 0xB2 && buffer[1] == 0xA1; 22 result = HasUserCalibration(SpiAddress::USER_LEFT_MAGIC, has_user_calibration);
24 if (has_user_calibration) {
25 result = ReadSPI(CalAddr::USER_LEFT_DATA, 9, buffer);
26 } else {
27 result = ReadSPI(CalAddr::FACT_LEFT_DATA, 9, buffer);
28 }
29 } 23 }
30 24
31 if (result == DriverResult::Success) { 25 // Read User defined calibration
32 calibration.x.max = static_cast<u16>(((buffer[1] & 0x0F) << 8) | buffer[0]); 26 if (result == DriverResult::Success && has_user_calibration) {
33 calibration.y.max = static_cast<u16>((buffer[2] << 4) | (buffer[1] >> 4)); 27 result = ReadSPI(SpiAddress::USER_LEFT_DATA, spi_calibration);
34 calibration.x.center = static_cast<u16>(((buffer[4] & 0x0F) << 8) | buffer[3]);
35 calibration.y.center = static_cast<u16>((buffer[5] << 4) | (buffer[4] >> 4));
36 calibration.x.min = static_cast<u16>(((buffer[7] & 0x0F) << 8) | buffer[6]);
37 calibration.y.min = static_cast<u16>((buffer[8] << 4) | (buffer[7] >> 4));
38 } 28 }
39 29
40 // Nintendo fix for drifting stick 30 // Read Factory calibration
41 // result = ReadSPI(0x60, 0x86 ,buffer, 16); 31 if (result == DriverResult::Success && !has_user_calibration) {
42 // calibration.deadzone = (u16)((buffer[4] << 8) & 0xF00 | buffer[3]); 32 result = ReadSPI(SpiAddress::FACT_LEFT_DATA, spi_calibration);
33 }
34
35 if (result == DriverResult::Success) {
36 calibration.x.center = GetXAxisCalibrationValue(spi_calibration.center);
37 calibration.y.center = GetYAxisCalibrationValue(spi_calibration.center);
38 calibration.x.min = GetXAxisCalibrationValue(spi_calibration.min);
39 calibration.y.min = GetYAxisCalibrationValue(spi_calibration.min);
40 calibration.x.max = GetXAxisCalibrationValue(spi_calibration.max);
41 calibration.y.max = GetYAxisCalibrationValue(spi_calibration.max);
42 }
43 43
44 // Set a valid default calibration if data is missing 44 // Set a valid default calibration if data is missing
45 ValidateCalibration(calibration); 45 ValidateCalibration(calibration);
@@ -49,33 +49,33 @@ DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration
49 49
50DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) { 50DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) {
51 ScopedSetBlocking sb(this); 51 ScopedSetBlocking sb(this);
52 std::vector<u8> buffer;
53 DriverResult result{DriverResult::Success}; 52 DriverResult result{DriverResult::Success};
53 JoystickRightSpiCalibration spi_calibration{};
54 bool has_user_calibration = false;
54 calibration = {}; 55 calibration = {};
55 56
56 result = ReadSPI(CalAddr::USER_RIGHT_MAGIC, sizeof(u16), buffer);
57
58 if (result == DriverResult::Success) { 57 if (result == DriverResult::Success) {
59 const bool has_user_calibration = buffer[0] == 0xB2 && buffer[1] == 0xA1; 58 result = HasUserCalibration(SpiAddress::USER_RIGHT_MAGIC, has_user_calibration);
60 if (has_user_calibration) {
61 result = ReadSPI(CalAddr::USER_RIGHT_DATA, 9, buffer);
62 } else {
63 result = ReadSPI(CalAddr::FACT_RIGHT_DATA, 9, buffer);
64 }
65 } 59 }
66 60
67 if (result == DriverResult::Success) { 61 // Read User defined calibration
68 calibration.x.center = static_cast<u16>(((buffer[1] & 0x0F) << 8) | buffer[0]); 62 if (result == DriverResult::Success && has_user_calibration) {
69 calibration.y.center = static_cast<u16>((buffer[2] << 4) | (buffer[1] >> 4)); 63 result = ReadSPI(SpiAddress::USER_RIGHT_DATA, spi_calibration);
70 calibration.x.min = static_cast<u16>(((buffer[4] & 0x0F) << 8) | buffer[3]); 64 }
71 calibration.y.min = static_cast<u16>((buffer[5] << 4) | (buffer[4] >> 4)); 65
72 calibration.x.max = static_cast<u16>(((buffer[7] & 0x0F) << 8) | buffer[6]); 66 // Read Factory calibration
73 calibration.y.max = static_cast<u16>((buffer[8] << 4) | (buffer[7] >> 4)); 67 if (result == DriverResult::Success && !has_user_calibration) {
68 result = ReadSPI(SpiAddress::FACT_RIGHT_DATA, spi_calibration);
74 } 69 }
75 70
76 // Nintendo fix for drifting stick 71 if (result == DriverResult::Success) {
77 // buffer = ReadSPI(0x60, 0x98 , 16); 72 calibration.x.center = GetXAxisCalibrationValue(spi_calibration.center);
78 // joystick.deadzone = (u16)((buffer[4] << 8) & 0xF00 | buffer[3]); 73 calibration.y.center = GetYAxisCalibrationValue(spi_calibration.center);
74 calibration.x.min = GetXAxisCalibrationValue(spi_calibration.min);
75 calibration.y.min = GetYAxisCalibrationValue(spi_calibration.min);
76 calibration.x.max = GetXAxisCalibrationValue(spi_calibration.max);
77 calibration.y.max = GetYAxisCalibrationValue(spi_calibration.max);
78 }
79 79
80 // Set a valid default calibration if data is missing 80 // Set a valid default calibration if data is missing
81 ValidateCalibration(calibration); 81 ValidateCalibration(calibration);
@@ -85,39 +85,41 @@ DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibratio
85 85
86DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) { 86DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) {
87 ScopedSetBlocking sb(this); 87 ScopedSetBlocking sb(this);
88 std::vector<u8> buffer;
89 DriverResult result{DriverResult::Success}; 88 DriverResult result{DriverResult::Success};
89 ImuSpiCalibration spi_calibration{};
90 bool has_user_calibration = false;
90 calibration = {}; 91 calibration = {};
91 92
92 result = ReadSPI(CalAddr::USER_IMU_MAGIC, sizeof(u16), buffer);
93
94 if (result == DriverResult::Success) { 93 if (result == DriverResult::Success) {
95 const bool has_user_calibration = buffer[0] == 0xB2 && buffer[1] == 0xA1; 94 result = HasUserCalibration(SpiAddress::USER_IMU_MAGIC, has_user_calibration);
96 if (has_user_calibration) { 95 }
97 result = ReadSPI(CalAddr::USER_IMU_DATA, sizeof(IMUCalibration), buffer); 96
98 } else { 97 // Read User defined calibration
99 result = ReadSPI(CalAddr::FACT_IMU_DATA, sizeof(IMUCalibration), buffer); 98 if (result == DriverResult::Success && has_user_calibration) {
100 } 99 result = ReadSPI(SpiAddress::USER_IMU_DATA, spi_calibration);
100 }
101
102 // Read Factory calibration
103 if (result == DriverResult::Success && !has_user_calibration) {
104 result = ReadSPI(SpiAddress::FACT_IMU_DATA, spi_calibration);
101 } 105 }
102 106
103 if (result == DriverResult::Success) { 107 if (result == DriverResult::Success) {
104 IMUCalibration device_calibration{}; 108 calibration.accelerometer[0].offset = spi_calibration.accelerometer_offset[0];
105 memcpy(&device_calibration, buffer.data(), sizeof(IMUCalibration)); 109 calibration.accelerometer[1].offset = spi_calibration.accelerometer_offset[1];
106 calibration.accelerometer[0].offset = device_calibration.accelerometer_offset[0]; 110 calibration.accelerometer[2].offset = spi_calibration.accelerometer_offset[2];
107 calibration.accelerometer[1].offset = device_calibration.accelerometer_offset[1];
108 calibration.accelerometer[2].offset = device_calibration.accelerometer_offset[2];
109 111
110 calibration.accelerometer[0].scale = device_calibration.accelerometer_scale[0]; 112 calibration.accelerometer[0].scale = spi_calibration.accelerometer_scale[0];
111 calibration.accelerometer[1].scale = device_calibration.accelerometer_scale[1]; 113 calibration.accelerometer[1].scale = spi_calibration.accelerometer_scale[1];
112 calibration.accelerometer[2].scale = device_calibration.accelerometer_scale[2]; 114 calibration.accelerometer[2].scale = spi_calibration.accelerometer_scale[2];
113 115
114 calibration.gyro[0].offset = device_calibration.gyroscope_offset[0]; 116 calibration.gyro[0].offset = spi_calibration.gyroscope_offset[0];
115 calibration.gyro[1].offset = device_calibration.gyroscope_offset[1]; 117 calibration.gyro[1].offset = spi_calibration.gyroscope_offset[1];
116 calibration.gyro[2].offset = device_calibration.gyroscope_offset[2]; 118 calibration.gyro[2].offset = spi_calibration.gyroscope_offset[2];
117 119
118 calibration.gyro[0].scale = device_calibration.gyroscope_scale[0]; 120 calibration.gyro[0].scale = spi_calibration.gyroscope_scale[0];
119 calibration.gyro[1].scale = device_calibration.gyroscope_scale[1]; 121 calibration.gyro[1].scale = spi_calibration.gyroscope_scale[1];
120 calibration.gyro[2].scale = device_calibration.gyroscope_scale[2]; 122 calibration.gyro[2].scale = spi_calibration.gyroscope_scale[2];
121 } 123 }
122 124
123 ValidateCalibration(calibration); 125 ValidateCalibration(calibration);
@@ -127,10 +129,12 @@ DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibrati
127 129
128DriverResult CalibrationProtocol::GetRingCalibration(RingCalibration& calibration, 130DriverResult CalibrationProtocol::GetRingCalibration(RingCalibration& calibration,
129 s16 current_value) { 131 s16 current_value) {
132 constexpr s16 DefaultRingRange{800};
133
130 // TODO: Get default calibration form ring itself 134 // TODO: Get default calibration form ring itself
131 if (ring_data_max == 0 && ring_data_min == 0) { 135 if (ring_data_max == 0 && ring_data_min == 0) {
132 ring_data_max = current_value + 800; 136 ring_data_max = current_value + DefaultRingRange;
133 ring_data_min = current_value - 800; 137 ring_data_min = current_value - DefaultRingRange;
134 ring_data_default = current_value; 138 ring_data_default = current_value;
135 } 139 }
136 ring_data_max = std::max(ring_data_max, current_value); 140 ring_data_max = std::max(ring_data_max, current_value);
@@ -143,42 +147,72 @@ DriverResult CalibrationProtocol::GetRingCalibration(RingCalibration& calibratio
143 return DriverResult::Success; 147 return DriverResult::Success;
144} 148}
145 149
150DriverResult CalibrationProtocol::HasUserCalibration(SpiAddress address,
151 bool& has_user_calibration) {
152 MagicSpiCalibration spi_magic{};
153 const DriverResult result{ReadSPI(address, spi_magic)};
154 has_user_calibration = false;
155 if (result == DriverResult::Success) {
156 has_user_calibration = spi_magic.first == CalibrationMagic::USR_MAGIC_0 &&
157 spi_magic.second == CalibrationMagic::USR_MAGIC_1;
158 }
159 return result;
160}
161
162u16 CalibrationProtocol::GetXAxisCalibrationValue(std::span<u8> block) const {
163 return static_cast<u16>(((block[1] & 0x0F) << 8) | block[0]);
164}
165
166u16 CalibrationProtocol::GetYAxisCalibrationValue(std::span<u8> block) const {
167 return static_cast<u16>((block[2] << 4) | (block[1] >> 4));
168}
169
146void CalibrationProtocol::ValidateCalibration(JoyStickCalibration& calibration) { 170void CalibrationProtocol::ValidateCalibration(JoyStickCalibration& calibration) {
147 constexpr u16 DefaultStickCenter{2048}; 171 constexpr u16 DefaultStickCenter{0x800};
148 constexpr u16 DefaultStickRange{1740}; 172 constexpr u16 DefaultStickRange{0x6cc};
149 173
150 if (calibration.x.center == 0xFFF || calibration.x.center == 0) { 174 calibration.x.center = ValidateValue(calibration.x.center, DefaultStickCenter);
151 calibration.x.center = DefaultStickCenter; 175 calibration.x.max = ValidateValue(calibration.x.max, DefaultStickRange);
152 } 176 calibration.x.min = ValidateValue(calibration.x.min, DefaultStickRange);
153 if (calibration.x.max == 0xFFF || calibration.x.max == 0) { 177
154 calibration.x.max = DefaultStickRange; 178 calibration.y.center = ValidateValue(calibration.y.center, DefaultStickCenter);
179 calibration.y.max = ValidateValue(calibration.y.max, DefaultStickRange);
180 calibration.y.min = ValidateValue(calibration.y.min, DefaultStickRange);
181}
182
183void CalibrationProtocol::ValidateCalibration(MotionCalibration& calibration) {
184 constexpr s16 DefaultAccelerometerScale{0x4000};
185 constexpr s16 DefaultGyroScale{0x3be7};
186 constexpr s16 DefaultOffset{0};
187
188 for (auto& sensor : calibration.accelerometer) {
189 sensor.scale = ValidateValue(sensor.scale, DefaultAccelerometerScale);
190 sensor.offset = ValidateValue(sensor.offset, DefaultOffset);
155 } 191 }
156 if (calibration.x.min == 0xFFF || calibration.x.min == 0) { 192 for (auto& sensor : calibration.gyro) {
157 calibration.x.min = DefaultStickRange; 193 sensor.scale = ValidateValue(sensor.scale, DefaultGyroScale);
194 sensor.offset = ValidateValue(sensor.offset, DefaultOffset);
158 } 195 }
196}
159 197
160 if (calibration.y.center == 0xFFF || calibration.y.center == 0) { 198u16 CalibrationProtocol::ValidateValue(u16 value, u16 default_value) const {
161 calibration.y.center = DefaultStickCenter; 199 if (value == 0) {
162 } 200 return default_value;
163 if (calibration.y.max == 0xFFF || calibration.y.max == 0) {
164 calibration.y.max = DefaultStickRange;
165 } 201 }
166 if (calibration.y.min == 0xFFF || calibration.y.min == 0) { 202 if (value == 0xFFF) {
167 calibration.y.min = DefaultStickRange; 203 return default_value;
168 } 204 }
205 return value;
169} 206}
170 207
171void CalibrationProtocol::ValidateCalibration(MotionCalibration& calibration) { 208s16 CalibrationProtocol::ValidateValue(s16 value, s16 default_value) const {
172 for (auto& sensor : calibration.accelerometer) { 209 if (value == 0) {
173 if (sensor.scale == 0) { 210 return default_value;
174 sensor.scale = 0x4000;
175 }
176 } 211 }
177 for (auto& sensor : calibration.gyro) { 212 if (value == 0xFFF) {
178 if (sensor.scale == 0) { 213 return default_value;
179 sensor.scale = 0x3be7;
180 }
181 } 214 }
215 return value;
182} 216}
183 217
184} // namespace InputCommon::Joycon 218} // namespace InputCommon::Joycon