mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-07 14:24:12 +08:00
747 lines
20 KiB
C
747 lines
20 KiB
C
#pragma once
|
|
|
|
/*
|
|
* This file is part of libn3ds
|
|
* Copyright (C) 2024 luigoalma, profi200
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include "types.h"
|
|
#include "error_codes.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#define HWCAL_MAGIC (0x4C414343u) // "CCAL"
|
|
#define CAL_CRC_OFFSET(cal_type) offsetof(typeof(cal_type), crc16)
|
|
|
|
// Bitmasks for agingPassedMask field.
|
|
// Note: agingPassedMask is u16 so bits beyond 15 are not supported.
|
|
#define CAL_MASK_RTC_COMPENSATION BIT(0)
|
|
#define CAL_MASK_LCD_FLICKER BIT(1)
|
|
#define CAL_MASK_OUTER_CAMS1 BIT(2)
|
|
#define CAL_MASK_TOUCH BIT(3)
|
|
#define CAL_MASK_CIRCLE_PAD1 BIT(4)
|
|
#define CAL_MASK_CODEC BIT(5)
|
|
#define CAL_MASK_GYRO BIT(6)
|
|
#define CAL_MASK_RTC_CORRECTION BIT(7)
|
|
#define CAL_MASK_ACCELEROMETER BIT(8)
|
|
#define CAL_MASK_SURROUND_SOUND BIT(9)
|
|
#define CAL_MASK_ABL BIT(10) // LCD power save.
|
|
#define CAL_MASK_LCD_3D BIT(11) // LCD stereoscopic.
|
|
#define CAL_MASK_BACKLIGHT_PWM BIT(12)
|
|
#define CAL_MASK_CIRCLE_PAD2 BIT(13)
|
|
#define CAL_MASK_OUTER_CAMS2 BIT(14)
|
|
#define CAL_MASK_ABL_LGY BIT(15) // LCD power save legacy.
|
|
|
|
#define CAL_MASK_MCU_SLIDERS BIT(16)
|
|
#define CAL_MASK_ULCD_DELAY BIT(17)
|
|
#define CAL_MASK_MIC_ECHO_CANCEL BIT(18)
|
|
#define CAL_MASK_C_STICK BIT(19)
|
|
#define CAL_MASK_UNUSED BIT(20)
|
|
#define CAL_MASK_NEW_ABL BIT(21) // New LCD power save.
|
|
#define CAL_MASK_PIT BIT(22)
|
|
#define CAL_MASK_QTM BIT(23)
|
|
|
|
|
|
// Touchscreen calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u16 rawX0;
|
|
u16 rawY0;
|
|
u16 pointX0;
|
|
u16 pointY0;
|
|
u16 rawX1;
|
|
u16 rawY1;
|
|
u16 pointX1;
|
|
u16 pointY1;
|
|
} TouchCalBase;
|
|
static_assert(sizeof(TouchCalBase) == 0x10);
|
|
static_assert(offsetof(TouchCalBase, pointY1) == 0xE);
|
|
|
|
typedef struct
|
|
{
|
|
TouchCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[2];
|
|
} TouchCal;
|
|
static_assert(sizeof(TouchCal) == 0x14);
|
|
static_assert(offsetof(TouchCal, padding[1]) == 0x13);
|
|
|
|
// Circle-Pad calibration 1.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 centerX;
|
|
s16 centerY;
|
|
// "reserved" excluded to save space.
|
|
} CirclePadCal1Base;
|
|
static_assert(sizeof(CirclePadCal1Base) == 4);
|
|
static_assert(offsetof(CirclePadCal1Base, centerY) == 2);
|
|
|
|
typedef struct
|
|
{
|
|
CirclePadCal1Base base;
|
|
u8 reserved[4];
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[2];
|
|
} CirclePadCal1;
|
|
static_assert(sizeof(CirclePadCal1) == 0xC);
|
|
static_assert(offsetof(CirclePadCal1, padding[1]) == 0xB);
|
|
|
|
// LCD flicker calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u8 vcomTop;
|
|
u8 vcomBottom;
|
|
} LcdFlickerCalBase;
|
|
static_assert(sizeof(LcdFlickerCalBase) == 2);
|
|
static_assert(offsetof(LcdFlickerCalBase, vcomBottom) == 1);
|
|
|
|
typedef struct
|
|
{
|
|
LcdFlickerCalBase base;
|
|
u8 flippedBytes[2];
|
|
} LcdFlickerCal;
|
|
static_assert(sizeof(LcdFlickerCal) == 4);
|
|
static_assert(offsetof(LcdFlickerCal, flippedBytes[1]) == 3);
|
|
|
|
// RTC compensation calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u8 compensationValue;
|
|
} RtcCompensationCalBase;
|
|
static_assert(sizeof(RtcCompensationCalBase) == 1);
|
|
|
|
typedef struct
|
|
{
|
|
RtcCompensationCalBase base;
|
|
u8 flippedBytes[1];
|
|
u8 padding[2];
|
|
} RtcCompensationCal;
|
|
static_assert(sizeof(RtcCompensationCal) == 4);
|
|
static_assert(offsetof(RtcCompensationCal, padding[1]) == 3);
|
|
|
|
// RTC correction calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u8 correctionValue;
|
|
} RtcCorrectionCalBase;
|
|
static_assert(sizeof(RtcCorrectionCalBase) == 1);
|
|
|
|
typedef struct
|
|
{
|
|
RtcCorrectionCalBase base;
|
|
u8 flippedBytes[1];
|
|
u8 padding[6];
|
|
} RtcCorrectionCal;
|
|
static_assert(sizeof(RtcCorrectionCal) == 8);
|
|
static_assert(offsetof(RtcCorrectionCal, padding[5]) == 7);
|
|
|
|
// Outer camera calibration 1.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u32 flags;
|
|
float scale;
|
|
float rotationZ;
|
|
float translationX;
|
|
float translationY;
|
|
float rotationX;
|
|
float rotationY;
|
|
float viewAngleRight;
|
|
float viewAngleLeft;
|
|
float chartDistance;
|
|
float cameraDistance;
|
|
s16 imageWidth;
|
|
s16 imageHeight;
|
|
} OuterCamStruct1;
|
|
static_assert(sizeof(OuterCamStruct1) == 0x30);
|
|
static_assert(offsetof(OuterCamStruct1, imageHeight) == 0x2E);
|
|
|
|
typedef struct
|
|
{
|
|
s16 aeBaseTarget;
|
|
s16 kRL;
|
|
s16 kGL;
|
|
s16 kBL;
|
|
s16 ccmPosition;
|
|
} OuterCamStruct2;
|
|
static_assert(sizeof(OuterCamStruct2) == 10);
|
|
static_assert(offsetof(OuterCamStruct2, ccmPosition) == 8);
|
|
|
|
typedef struct
|
|
{
|
|
OuterCamStruct1 base;
|
|
u8 reserved[16];
|
|
u8 reserved2[64];
|
|
OuterCamStruct2 base2;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
} OuterCamCal1;
|
|
static_assert(sizeof(OuterCamCal1) == 0x8C);
|
|
static_assert(offsetof(OuterCamCal1, crc16) == 0x8A);
|
|
|
|
// Gyroscope calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 zeroX;
|
|
s16 plusX;
|
|
s16 minusX;
|
|
s16 zeroY;
|
|
s16 plusY;
|
|
s16 minusY;
|
|
s16 zeroZ;
|
|
s16 plusZ;
|
|
s16 minusZ;
|
|
} GyroscopeCalBase;
|
|
static_assert(sizeof(GyroscopeCalBase) == 0x12);
|
|
static_assert(offsetof(GyroscopeCalBase, minusZ) == 0x10);
|
|
|
|
typedef struct
|
|
{
|
|
GyroscopeCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
} GyroscopeCal;
|
|
static_assert(sizeof(GyroscopeCal) == 0x14);
|
|
static_assert(offsetof(GyroscopeCal, crc16) == 0x12);
|
|
|
|
// Accelerometer calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 offsetX;
|
|
s16 scaleX;
|
|
s16 offsetY;
|
|
s16 scaleY;
|
|
s16 offsetZ;
|
|
s16 scaleZ;
|
|
} AccelerometerCalBase;
|
|
static_assert(sizeof(AccelerometerCalBase) == 0xC);
|
|
static_assert(offsetof(AccelerometerCalBase, scaleZ) == 0xA);
|
|
|
|
typedef struct
|
|
{
|
|
AccelerometerCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[2];
|
|
} AccelerometerCal;
|
|
static_assert(sizeof(AccelerometerCal) == 0x10);
|
|
static_assert(offsetof(AccelerometerCal, padding[1]) == 0xF);
|
|
|
|
// CODEC calibration.
|
|
// ---------------------------------------------------------------- //
|
|
#define CDC_SWAP_IIR(b0, b1, a1) __builtin_bswap16(b0),__builtin_bswap16(b1),__builtin_bswap16(a1)
|
|
#define CDC_SWAP_BIQUAD(b0, b1, b2, a1, a2) __builtin_bswap16(b0),__builtin_bswap16(b1),__builtin_bswap16(b2),__builtin_bswap16(a1),__builtin_bswap16(a2)
|
|
|
|
// All coefficients are 16 bit fixed-point numbers.
|
|
// 1 sign bit (bit 15) and 15 fraction bits. Big endian.
|
|
// All filters are IIR filters.
|
|
// Note: All names based on TSC2117 datasheet/CTRAging/guesses.
|
|
// They may not match 100%.
|
|
|
|
// First order IIR. Or half a biquad.
|
|
typedef struct
|
|
{
|
|
s16 b0;
|
|
s16 b1;
|
|
// a0 always 1.0.
|
|
s16 a1; // Inverted.
|
|
} CdcIir;
|
|
static_assert(sizeof(CdcIir) == 6);
|
|
static_assert(offsetof(CdcIir, a1) == 4);
|
|
|
|
// Full IIR biquad filter.
|
|
typedef struct
|
|
{
|
|
s16 b0;
|
|
s16 b1; // Halved.
|
|
s16 b2;
|
|
// a0 always 1.0.
|
|
s16 a1; // Halved and inverted.
|
|
s16 a2; // Inverted.
|
|
} CdcBiquad;
|
|
static_assert(sizeof(CdcBiquad) == 10);
|
|
static_assert(offsetof(CdcBiquad, a2) == 8);
|
|
|
|
// Equalizer filters.
|
|
typedef struct
|
|
{
|
|
CdcBiquad a; // Not in TSC2117 datasheet. Name is a guess.
|
|
CdcBiquad b; // Not in TSC2117 datasheet. Name is a guess.
|
|
CdcBiquad c; // Not in TSC2117 datasheet. Name is a guess.
|
|
} CdcEqFilters;
|
|
static_assert(sizeof(CdcEqFilters) == 30);
|
|
static_assert(offsetof(CdcEqFilters, c) == 20);
|
|
|
|
// PRB_P25 filters.
|
|
typedef struct
|
|
{
|
|
CdcIir iir; // First order IIR filter.
|
|
CdcBiquad b; // Biquad filter B.
|
|
CdcBiquad c; // Biquad filter C.
|
|
CdcBiquad d; // Biquad filter D.
|
|
CdcBiquad e; // Biquad filter E.
|
|
CdcBiquad f; // Biquad filter F.
|
|
} CdcPrbP25Filters;
|
|
static_assert(sizeof(CdcPrbP25Filters) == 0x38);
|
|
static_assert(offsetof(CdcPrbP25Filters, f.a2) == 0x36);
|
|
|
|
typedef struct
|
|
{
|
|
u8 driverGainHp;
|
|
u8 driverGainSp;
|
|
u8 analogVolumeHp;
|
|
u8 analogVolumeSp;
|
|
s8 shutterVolumeI2s1;
|
|
s8 shutterVolumeI2s2;
|
|
u8 microphoneBias;
|
|
u8 quickCharge; // Microphone related.
|
|
u8 pgaGain; // Microphone gain.
|
|
u8 padding[3];
|
|
CdcEqFilters filterHp32;
|
|
CdcEqFilters filterHp47;
|
|
CdcEqFilters filterSp32;
|
|
CdcEqFilters filterSp47;
|
|
CdcPrbP25Filters filterMic32; // Note: Does not perfectly match TSC2117 datasheet.
|
|
CdcPrbP25Filters filterMic47; // Note: Does not perfectly match TSC2117 datasheet.
|
|
CdcPrbP25Filters filterFree;
|
|
|
|
// Analog calibration.
|
|
u8 analogInterval;
|
|
u8 analogStabilize;
|
|
u8 analogPrecharge;
|
|
u8 analogSense;
|
|
u8 analogDebounce;
|
|
u8 analogXpPullup;
|
|
u8 ymDriver;
|
|
u8 reserved;
|
|
} CodecCalBase;
|
|
static_assert(sizeof(CodecCalBase) == 0x134);
|
|
static_assert(offsetof(CodecCalBase, reserved) == 0x133);
|
|
|
|
typedef struct
|
|
{
|
|
CodecCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[2];
|
|
} CodecCal;
|
|
static_assert(sizeof(CodecCal) == 0x138);
|
|
static_assert(offsetof(CodecCal, padding[1]) == 0x137);
|
|
|
|
// PIT calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u16 visibleFactor; // float16?
|
|
u16 irFactor; // float16?
|
|
} PitCalBase;
|
|
static_assert(sizeof(PitCalBase) == 4);
|
|
static_assert(offsetof(PitCalBase, irFactor) == 2);
|
|
|
|
typedef struct
|
|
{
|
|
PitCalBase base;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
} PitCal;
|
|
static_assert(sizeof(PitCal) == 8);
|
|
static_assert(offsetof(PitCal, crc16) == 6);
|
|
|
|
// Surround sound calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 specialFilter[256];
|
|
s32 iirSurroundFilter[5];
|
|
} SurroundSoundCalBase;
|
|
static_assert(sizeof(SurroundSoundCalBase) == 0x214);
|
|
static_assert(offsetof(SurroundSoundCalBase, iirSurroundFilter[4]) == 0x210);
|
|
|
|
typedef struct
|
|
{
|
|
SurroundSoundCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[10];
|
|
} SurroundSoundCal;
|
|
static_assert(sizeof(SurroundSoundCal) == 0x220);
|
|
static_assert(offsetof(SurroundSoundCal, padding[9]) == 0x21F);
|
|
|
|
// LCD power save (ABL) calibration 1.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u32 ditherPattern;
|
|
u16 startX;
|
|
u16 startY;
|
|
u16 sizeX;
|
|
u16 sizeY;
|
|
u16 gthRatio;
|
|
u8 ditherMode;
|
|
u8 minRs;
|
|
u8 maxRs;
|
|
u8 minGth;
|
|
u8 minMax;
|
|
u8 exMax;
|
|
u8 inertia;
|
|
u8 lutListRs[9];
|
|
u8 reserved[2];
|
|
} LcdPowerSaveCalBase;
|
|
static_assert(sizeof(LcdPowerSaveCalBase) == 32);
|
|
static_assert(offsetof(LcdPowerSaveCalBase, reserved[1]) == 31);
|
|
|
|
typedef struct
|
|
{
|
|
LcdPowerSaveCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[14];
|
|
} LcdPowerSaveCal;
|
|
static_assert(sizeof(LcdPowerSaveCal) == 0x30);
|
|
static_assert(offsetof(LcdPowerSaveCal, padding) == 34);
|
|
|
|
// LCD stereoscopic (3D) calibration.
|
|
// ---------------------------------------------------------------- //
|
|
// New 3DS stable 3D calibration??
|
|
typedef struct
|
|
{
|
|
float pupillaryDistanceInMm;
|
|
float distanceEyesAndUpperLcdInMm;
|
|
float lcdWidthInMm;
|
|
float lcdHeightInMm;
|
|
float unknown[4];
|
|
} LcdStereoscopicCalBase;
|
|
static_assert(sizeof(LcdStereoscopicCalBase) == 0x20);
|
|
static_assert(offsetof(LcdStereoscopicCalBase, unknown[3]) == 0x1C);
|
|
|
|
typedef struct
|
|
{
|
|
LcdStereoscopicCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[14];
|
|
} LcdStereoscopicCal;
|
|
static_assert(sizeof(LcdStereoscopicCal) == 0x30);
|
|
static_assert(offsetof(LcdStereoscopicCal, padding[13]) == 0x2F);
|
|
|
|
// LCD backlight PWM calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
float coeffs[3][3]; // Polynomial coefficients. [LCD/mode]{A, B, C}.
|
|
u8 numLevels; // Number of luminance levels excluding 0.
|
|
u8 unknown; // TODO: Is numLevels actually u16?
|
|
u16 lumLevels[7]; // Luminance levels as used in HOME menu.
|
|
u16 hwBrightnessBase; // Alternatively hwBrightnessMax. Maximum hardware brightness.
|
|
u16 hwBrightnessMin; // Minimum hardware brightness.
|
|
} BacklightPwmCalBase;
|
|
static_assert(sizeof(BacklightPwmCalBase) == 0x38);
|
|
static_assert(offsetof(BacklightPwmCalBase, hwBrightnessMin) == 0x36);
|
|
|
|
typedef struct
|
|
{
|
|
BacklightPwmCalBase base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[6];
|
|
} BacklightPwmCal;
|
|
static_assert(sizeof(BacklightPwmCal) == 0x40);
|
|
static_assert(offsetof(BacklightPwmCal, padding[5]) == 0x3F);
|
|
|
|
// Circle-Pad calibration 2.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
float scaleX;
|
|
float scaleY;
|
|
s16 maxX;
|
|
s16 minX;
|
|
s16 maxY;
|
|
s16 minY;
|
|
s16 type;
|
|
u8 reserved[2]; // Needed for alignment anyway. Part of the reserved array in CirclePadCal2.
|
|
} CirclePadCal2Base;
|
|
static_assert(sizeof(CirclePadCal2Base) == 0x14);
|
|
static_assert(offsetof(CirclePadCal2Base, reserved[1]) == 0x13);
|
|
|
|
typedef struct
|
|
{
|
|
CirclePadCal2Base base;
|
|
u8 reserved[4];
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[6];
|
|
} CirclePadCal2;
|
|
static_assert(sizeof(CirclePadCal2) == 0x20);
|
|
static_assert(offsetof(CirclePadCal2, padding[5]) == 0x1F);
|
|
|
|
// Outer camera calibration 2.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u16 unknown[6];
|
|
} OuterCamCal2Base;
|
|
static_assert(sizeof(OuterCamCal2Base) == 0xC);
|
|
static_assert(offsetof(OuterCamCal2Base, unknown[5]) == 0xA);
|
|
|
|
typedef struct
|
|
{
|
|
OuterCamCal2Base base;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[2];
|
|
} OuterCamCal2;
|
|
static_assert(sizeof(OuterCamCal2) == 0x10);
|
|
static_assert(offsetof(OuterCamCal2, padding[1]) == 0xF);
|
|
|
|
// MCU 3D and volume slider calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 min;
|
|
s16 max;
|
|
} McuSliderBounds;
|
|
static_assert(sizeof(McuSliderBounds) == 4);
|
|
static_assert(offsetof(McuSliderBounds, max) == 2);
|
|
|
|
typedef struct
|
|
{
|
|
McuSliderBounds _3d;
|
|
McuSliderBounds vol;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[4];
|
|
} McuSliderCal;
|
|
static_assert(sizeof(McuSliderCal) == 0x10);
|
|
static_assert(offsetof(McuSliderCal, padding[3]) == 0xF);
|
|
|
|
// ULCD (2D <--> 3D) delay calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s8 to2d;
|
|
s8 to3d;
|
|
} ULcdDelayCalBase;
|
|
static_assert(sizeof(ULcdDelayCalBase) == 2);
|
|
static_assert(offsetof(ULcdDelayCalBase, to3d) == 1);
|
|
|
|
typedef struct
|
|
{
|
|
ULcdDelayCalBase base;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[10];
|
|
} ULcdDelayCal;
|
|
static_assert(sizeof(ULcdDelayCal) == 0x10);
|
|
static_assert(offsetof(ULcdDelayCal, padding[9]) == 0xF);
|
|
|
|
// Microphone echo cancellation calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u8 params[8];
|
|
} MicEchoCancelCalBase;
|
|
static_assert(sizeof(MicEchoCancelCalBase) == 8);
|
|
static_assert(offsetof(MicEchoCancelCalBase, params[7]) == 7);
|
|
|
|
typedef struct
|
|
{
|
|
MicEchoCancelCalBase base;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[4];
|
|
} MicEchoCancelCal;
|
|
static_assert(sizeof(MicEchoCancelCal) == 0x10);
|
|
static_assert(offsetof(MicEchoCancelCal, padding[3]) == 0xF);
|
|
|
|
// LCD power save (ABL) calibration for New 2DS/3DS.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u8 maxInertia;
|
|
u8 pad;
|
|
u16 pwmCntEx;
|
|
u32 histogram1;
|
|
u32 histogram2;
|
|
u32 adjust[64];
|
|
} NewLcdPowerSaveCalBase;
|
|
static_assert(sizeof(NewLcdPowerSaveCalBase) == 0x10C);
|
|
static_assert(offsetof(NewLcdPowerSaveCalBase, adjust[63]) == 0x108);
|
|
|
|
typedef struct
|
|
{
|
|
NewLcdPowerSaveCalBase base;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
} NewLcdPowerSaveCal;
|
|
static_assert(sizeof(NewLcdPowerSaveCal) == 0x110);
|
|
static_assert(offsetof(NewLcdPowerSaveCal, crc16) == 0x10E);
|
|
|
|
// C-Stick calibration. TODO: Is this actually Circle-Pad Pro?
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
s16 centerX; // TODO: Confirm this.
|
|
s16 centerY; // TODO: Confirm this.
|
|
} CStickCalBase;
|
|
static_assert(sizeof(CStickCalBase) == 4);
|
|
static_assert(offsetof(CStickCalBase, centerY) == 2);
|
|
|
|
typedef struct
|
|
{
|
|
CStickCalBase base;
|
|
u8 reserved[4];
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[4];
|
|
} CStickCal;
|
|
static_assert(sizeof(CStickCal) == 0x10);
|
|
static_assert(offsetof(CStickCal, padding[3]) == 0xF);
|
|
|
|
// QTM (head tracking) calibration.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
float divisorAtZero;
|
|
float translationX;
|
|
float translationY;
|
|
float rotationZ;
|
|
float horizontalAngle;
|
|
float optimalDistance;
|
|
} QtmCalBase;
|
|
static_assert(sizeof(QtmCalBase) == 0x18);
|
|
static_assert(offsetof(QtmCalBase, optimalDistance) == 0x14);
|
|
|
|
typedef struct
|
|
{
|
|
QtmCalBase base;
|
|
u16 agingFlag;
|
|
u16 crc16; // CRC16 init 0x55AA.
|
|
u8 padding[4];
|
|
} QtmCal;
|
|
static_assert(sizeof(QtmCal) == 0x20);
|
|
static_assert(offsetof(QtmCal, padding[3]) == 0x1F);
|
|
|
|
// Hardware calibration header.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
u32 magic;
|
|
u32 version;
|
|
u32 bodySize;
|
|
u8 modelVersion; // ?
|
|
u8 revision;
|
|
u16 agingPassedMask; // Mask of passed aging tests.
|
|
union
|
|
{
|
|
u8 sha256[32]; // Dev units.
|
|
u8 hmacSha256[32]; // Retail units.
|
|
};
|
|
} HwcalHeader;
|
|
static_assert(sizeof(HwcalHeader) == 0x30);
|
|
static_assert(offsetof(HwcalHeader, hmacSha256[31]) == 0x2F);
|
|
|
|
// Hardware calibration body.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
TouchCal touch;
|
|
CirclePadCal1 circlePad1;
|
|
LcdFlickerCal lcdFlicker;
|
|
RtcCompensationCal rtcCompensation;
|
|
RtcCorrectionCal rtcCorrection;
|
|
OuterCamCal1 outerCam1;
|
|
GyroscopeCal gyro;
|
|
AccelerometerCal accelerometer;
|
|
CodecCal codec;
|
|
PitCal pit;
|
|
SurroundSoundCal surroundSound;
|
|
LcdPowerSaveCal lcdPowersave;
|
|
LcdStereoscopicCal lcdStereoscopic;
|
|
BacklightPwmCal blPwn;
|
|
CirclePadCal2 circlePad2;
|
|
OuterCamCal2 outerCam2;
|
|
LcdPowerSaveCal lcdPowersaveLgy;
|
|
McuSliderCal slider;
|
|
ULcdDelayCal lcdModeDelay;
|
|
MicEchoCancelCal micEchoCancel;
|
|
NewLcdPowerSaveCal newLcdPowersave;
|
|
CStickCal cStick;
|
|
QtmCal qtm;
|
|
} HwcalBody;
|
|
static_assert(sizeof(HwcalBody) == 0x6B0);
|
|
static_assert(offsetof(HwcalBody, qtm.padding[3]) == 0x6AF);
|
|
|
|
// Whole hardware calibration with header.
|
|
// ---------------------------------------------------------------- //
|
|
typedef struct
|
|
{
|
|
// Header.
|
|
u32 magic;
|
|
u32 version;
|
|
u32 bodySize;
|
|
u8 modelVersion; // ?
|
|
u8 revision;
|
|
u16 agingPassedMask; // Mask of passed aging tests.
|
|
union
|
|
{
|
|
u8 sha256[32]; // Dev units.
|
|
u8 hmacSha256[32]; // Retail units.
|
|
};
|
|
u8 padding[0x1D0];
|
|
|
|
// Body.
|
|
TouchCal touch;
|
|
CirclePadCal1 circlePad1;
|
|
LcdFlickerCal lcdFlicker;
|
|
RtcCompensationCal rtcCompensation;
|
|
RtcCorrectionCal rtcCorrection;
|
|
OuterCamCal1 outerCam1;
|
|
GyroscopeCal gyro;
|
|
AccelerometerCal accelerometer;
|
|
CodecCal codec;
|
|
PitCal pit;
|
|
SurroundSoundCal surroundSound;
|
|
LcdPowerSaveCal lcdPowersave;
|
|
LcdStereoscopicCal lcdStereoscopic;
|
|
BacklightPwmCal blPwn;
|
|
CirclePadCal2 circlePad2;
|
|
OuterCamCal2 outerCam2;
|
|
LcdPowerSaveCal lcdPowersaveLgy;
|
|
McuSliderCal slider;
|
|
ULcdDelayCal lcdModeDelay;
|
|
MicEchoCancelCal micEchoCancel;
|
|
NewLcdPowerSaveCal newLcdPowersave;
|
|
CStickCal cStick;
|
|
QtmCal qtm;
|
|
u8 unused[0x120];
|
|
} Hwcal;
|
|
static_assert(sizeof(Hwcal) == 0x9D0);
|
|
static_assert(offsetof(Hwcal, unused[0x11F]) == 0x9CF);
|
|
|
|
|
|
extern CodecCalBase g_cdcCal;
|
|
extern BacklightPwmCalBase g_blPwmCal;
|
|
|
|
|
|
Result HWCAL_load(void);
|
|
u32 HWCAL_getLoadedMask(void);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif |