Add function to detect the gyro model in a 3ds (#949)

* Add gyro model detection

* Add gyro detection to sysinfo

* Add gyro model as lua global

* Normalize line endings to LF

* Add documentation, add var to gm9 script, change model to start at 1
This commit is contained in:
Tage Mellemstrand 2026-03-20 15:29:18 +01:00 committed by GitHub
parent d2445f0396
commit 9310455cac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 82 additions and 0 deletions

29
arm9/source/common/gyro.c Normal file
View File

@ -0,0 +1,29 @@
#include "gyro.h"
#include "i2c.h"
u32 GetGyroModel() {
uint8_t buffer;
if (I2C_readRegBuf(I2C_DEV_GYRO, GYRO_1_PWR_MGM, &buffer, 1)) {
// ITG-3270 - o3DS and early o2DS
return 1;
} else if (I2C_readRegBuf(I2C_DEV_GYRO2, GYRO_2_PWR_MGM_1, &buffer, 1)) {
// ITG-1010 - late models o2DS and early n3DS
return 2;
} else if (I2C_readRegBuf(I2C_DEV_GYRO3, GYRO_3_PWR_MGM, &buffer, 1)) {
// ?? - later models n3DS
return 3;
} else {
// ????
return 0;
}
}
const char* GetGyroModelString() {
switch (GetGyroModel()) {
case 1: return "1";
case 2: return "2";
case 3: return "3";
default: return "0";
}
}

20
arm9/source/common/gyro.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include "common.h"
typedef enum {
GYRO_1_WHO_AM_I = 0x00,
GYRO_1_PWR_MGM = 0x3E
} GyroModel1Register;
typedef enum {
GYRO_2_PWR_MGM_1 = 0x6B,
GYRO_2_WHO_AM_I = 0x75
} GyroModel2Register;
typedef enum {
GYRO_3_PWR_MGM = 0x39 // Unconfirmed
} GyroModel3Register;
u32 GetGyroModel();
const char* GetGyroModelString();

View File

@ -8,6 +8,7 @@
#include "fsutil.h"
#include "unittype.h"
#include "nand.h"
#include "gyro.h"
#include "gm9loader.h"
#include "gm9os.h"
#include "gm9ui.h"
@ -188,6 +189,14 @@ bool ExecuteLuaScript(const char* path_script) {
lua_pushinteger(L, GetNandSizeSectors(NAND_SYSNAND) * 0x200);
lua_setglobal(L, "NANDSIZE");
u32 gyro_model = GetGyroModel();
if (gyro_model) {
lua_pushinteger(L, gyro_model);
} else {
lua_pushnil(L);
}
lua_setglobal(L, "GYROMODEL");
lua_pushboolean(L, IS_DEVKIT);
lua_setglobal(L, "IS_DEVKIT");

View File

@ -26,7 +26,9 @@ typedef enum
I2C_DEV_CAMERA = 1, // Unconfirmed
I2C_DEV_CAMERA2 = 2, // Unconfirmed
I2C_DEV_MCU = 3,
I2C_DEV_GYRO3 = 9,
I2C_DEV_GYRO = 10,
I2C_DEV_GYRO2 = 11,
I2C_DEV_DEBUG_PAD = 12,
I2C_DEV_IR = 13,
I2C_DEV_EEPROM = 14, // Unconfirmed

View File

@ -18,6 +18,7 @@
#include "ips.h"
#include "bps.h"
#include "pxi.h"
#include "gyro.h"
#define _MAX_ARGS 4
@ -525,6 +526,7 @@ bool init_vars(const char* path_script) {
set_var("HAX", IS_UNLOCKED ? (isntrboot() ? "ntrboot" : "sighax") : ""); // type of hax running from
set_var("ONTYPE", IS_O3DS ? "O3DS" : "N3DS"); // type of the console
set_var("RDTYPE", IS_DEVKIT ? "devkit" : "retail"); // devkit / retail
set_var("GYROMODEL", GetGyroModelString()); // gyro model
char* ptr = set_var("GM9VER", VERSION); // GodMode9 version, truncated below
while (*(ptr++) != '\0') if (*ptr == '-') *ptr = '\0';

View File

@ -8,6 +8,7 @@
#include "sdmmc.h" // for NAND / SD CID
#include "vff.h"
#include "sha.h"
#include "gyro.h"
#include <ctype.h>
#include <limits.h>
#include <string.h>
@ -56,6 +57,8 @@ typedef struct _SysInfo {
// From hardware information.
char model[15 + 1];
char product_code[3 + 1];
// From Gyro I2C
uint8_t gyro_model;
// From OTP.
char soc_date[19 + 1];
// From SecureInfo_A/B
@ -100,6 +103,12 @@ void GetSysInfo_Hardware(SysInfo* info, char nand_drive) {
}
}
void GetSysInfo_Gyro(SysInfo* info, char nand_drive) {
(void) nand_drive;
info->gyro_model = GetGyroModel();
}
// Read OTP.
void GetSysInfo_OTP(SysInfo* info, char nand_drive) {
@ -588,6 +597,7 @@ void MeowSprintf(char** text, const char* format, ...)
void MyriaSysinfo(char* sysinfo_txt) {
SysInfo info;
GetSysInfo_Hardware(&info, '1');
GetSysInfo_Gyro(&info, '1');
GetSysInfo_OTP(&info, '1');
GetSysInfo_SecureInfo(&info, '1');
GetSysInfo_Movable(&info, '1');
@ -602,6 +612,7 @@ void MyriaSysinfo(char* sysinfo_txt) {
MeowSprintf(meow, STR_SYSINFO_SOC_MANUFACTURING_DATE, info.soc_date);
MeowSprintf(meow, STR_SYSINFO_SYSTEM_ASSEMBLY_DATE, info.assembly_date);
MeowSprintf(meow, STR_SYSINFO_ORIGINAL_FIRMWARE, info.original_firmware);
MeowSprintf(meow, STR_SYSINFO_GYRO_MODEL, info.gyro_model);
MeowSprintf(meow, "\r\n");
MeowSprintf(meow, STR_SYSINFO_FRIENDCODE_SEED, info.friendcodeseed);
MeowSprintf(meow, STR_SYSINFO_SD_KEYY, info.movablekeyy);

View File

@ -800,6 +800,7 @@
"END_OF_SCRIPT_UNRESOLVED_FOR": "end of script: unresolved 'for'",
"SYSINFO_MODEL": "Model: %s (%s)\r\n",
"SYSINFO_SERIAL": "Serial: %s\r\n",
"SYSINFO_GYRO_MODEL": "Gyro model: %u\r\n",
"SYSINFO_REGION_SYSTEM": "Region (system): %s\r\n",
"SYSINFO_REGION_SALES": "Region (sales): %s\r\n",
"SYSINFO_SOC_MANUFACTURING_DATE": "SoC manufacturing date: %s\r\n",

View File

@ -120,6 +120,7 @@ ONTYPE | CONSOLE_TYPE | “O3DS" or “N3DS"
RDTYPE | IS_DEVKIT | boolean instead of a string
HAX | HAX |  
GM9VER | GM9VER |  
GYROMODEL | GYROMODEL | int instead of string
## Comparisons with standard Lua
@ -162,6 +163,13 @@ local json = require("json")
#### GM9VER
The version such as `"v2.1.1-159-gff2cb913"`, the same string that is shown on the main screen.
#### GYROMODEL
The type of Gyro sensor present
* `1`: ITG-3270, used in O3DS and some O2DS
* `2`: ITG-1010, used in late model O2DS and N3DS
* `3`: Unknown name, used in late model N3DS
* `nil`: Unknown model
#### SCRIPT
Path to the executed script, such as `"0:/gm9/luascripts/myscript.lua"`.