diff options
| author | 2023-01-29 02:43:14 -0800 | |
|---|---|---|
| committer | 2023-01-29 02:43:14 -0800 | |
| commit | 9170387e71d4295477b74666a843a889af62b2a3 (patch) | |
| tree | ee08cde9257dc4c77943b7566ee678ed8317eec2 /src/input_common/helpers/joycon_protocol/calibration.cpp | |
| parent | Merge pull request #9691 from ameerj/msaa-texcache (diff) | |
| parent | input_common: joycon: Replace ReadSPI vector with span (diff) | |
| download | yuzu-9170387e71d4295477b74666a843a889af62b2a3.tar.gz yuzu-9170387e71d4295477b74666a843a889af62b2a3.tar.xz yuzu-9170387e71d4295477b74666a843a889af62b2a3.zip | |
Merge pull request #9689 from german77/joycon-calibration
input_common: joycon: Remove magic numbers from calibration protocol
Diffstat (limited to 'src/input_common/helpers/joycon_protocol/calibration.cpp')
| -rw-r--r-- | src/input_common/helpers/joycon_protocol/calibration.cpp | 210 |
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 | ||
| 14 | DriverResult CalibrationProtocol::GetLeftJoyStickCalibration(JoyStickCalibration& calibration) { | 14 | DriverResult 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 | ||
| 50 | DriverResult CalibrationProtocol::GetRightJoyStickCalibration(JoyStickCalibration& calibration) { | 50 | DriverResult 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 | ||
| 86 | DriverResult CalibrationProtocol::GetImuCalibration(MotionCalibration& calibration) { | 86 | DriverResult 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 | ||
| 128 | DriverResult CalibrationProtocol::GetRingCalibration(RingCalibration& calibration, | 130 | DriverResult 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 | ||
| 150 | DriverResult 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 | |||
| 162 | u16 CalibrationProtocol::GetXAxisCalibrationValue(std::span<u8> block) const { | ||
| 163 | return static_cast<u16>(((block[1] & 0x0F) << 8) | block[0]); | ||
| 164 | } | ||
| 165 | |||
| 166 | u16 CalibrationProtocol::GetYAxisCalibrationValue(std::span<u8> block) const { | ||
| 167 | return static_cast<u16>((block[2] << 4) | (block[1] >> 4)); | ||
| 168 | } | ||
| 169 | |||
| 146 | void CalibrationProtocol::ValidateCalibration(JoyStickCalibration& calibration) { | 170 | void 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 | |||
| 183 | void 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) { | 198 | u16 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 | ||
| 171 | void CalibrationProtocol::ValidateCalibration(MotionCalibration& calibration) { | 208 | s16 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 |