diff --git a/README.md b/README.md index ff536e4c..5513cdd6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Switch OC Suite -[![Join the chat at https://gitter.im/Switch-OC-Suite/community](https://badges.gitter.im/Switch-OC-Suite/community.svg)](https://gitter.im/Switch-OC-Suite/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) [![Join the chat at https://gitter.im/Switch-OC-Suite/community](https://badges.gitter.im/Switch-OC-Suite/community.svg)](https://gitter.im/Switch-OC-Suite/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Overclocking suite for Switch **(Mariko Only)** running on Atmosphere CFW. Support Horizon OS 13.0.0-13.2.0. -This project will not be actively maintained by me and I'm looking for collaborators. Open an issue if you are interested and would like to be added into the maintainer list. +This project will not be actively maintained in 2022 and I'm looking for collaborators. Open an issue if you are interested and would like to be added into the maintainer list. @@ -39,6 +39,8 @@ This project will not be actively maintained by me and I'm looking for collabora - **Official X1+ CPU/GPU Max clock: 1963.5/1267.2 MHz**. - Anything above that are not in the table of official module. ([issue #4](https://github.com/KazushiMe/Switch-OC-Suite/issues/4)) + - All maxed out OC is not recommended, and is strongly discouraged without charger. + - See `Battery Current Flow` in sys-clk-OC overlay `Miscellaneous`. - **Recommended RAM clock: 1862.4/1996.8 MHz**. - Only 1600 and MAX MHz could be selected in sys-clk. @@ -55,18 +57,9 @@ This project will not be actively maintained by me and I'm looking for collabora - CPU overvolting: 1220 mV, up from default 1120 mV. Frequencies ≥ 2193 MHz will enable overvolting. - - GPU overvolting: 1170 mV, default 1050 mV. Frequencies ≥ 1420 Mhz trigger overvolting. ([issue #4](https://github.com/KazushiMe/Switch-OC-Suite/issues/4)) + - GPU overvolting: 1170 mV, default 1050 mV. Frequencies ≥ 1420 MHz trigger overvolting. - You cannot set > 1267 MHz without official chargers. - - RAM [NOT RECOMMENDED] - - Only diff patch for hekate bootloader is provided. - - Edit `oc.ini` to change Vddq voltage value: - ```ini - [emc] - volt=600000 - ``` - - Overvolting beyond 650mV is not safe and proved to be not much helpful. - - **Fan Control Optimization** at high load - Higher tolerable temperature and smoother fan curve. Set `holdable_tskin` to 56˚C. Previously it's set to 48˚C, so by default the fan would go crazy (80~100%) easily with a slight degree of OC. - Replace crappy factory thermal paste is preferred. @@ -75,10 +68,9 @@ This project will not be actively maintained by me and I'm looking for collabora - **Modded sys-clk and ReverseNX**(-Tools and -RT) - **No need to change clocks manually** after toggling modes in ReverseNX - - Add `/config/sys-clk/downclock_dock.flag` to use handheld clocks in Docked mode when Handheld mode is set in ReverseNX. - To **disable this feature**, use original version of ReverseNX-RT and delete `/config/sys-clk/ReverseNX_sync.flag`. - **Auto-Boost CPU for faster game loading** - - Enable CPU Boost (1963.5 MHz) if CPU Core#3 (System Core) is stressed, especially when the game is loading assets from eMMC/SD card. + - Enable CPU Boost (1785 MHz) when CPU Core#3 (System Core) is stressed, especially when the game is loading assets from eMMC/SD card. - Auto-Boost will be enabled only when charger is connected. (>90% w/ PD charger or >95% w/ unsupported charger) - To **disable this feature**, simply remove `boost.flag` in `/config/sys-clk/`. @@ -128,7 +120,7 @@ Grab necessary patches from the repo, then compile sys-clk, ReverseNX-RT, hekate - CTCaer for [Hekate-ipl](https://github.com/CTCaer/hekate) bootloader, RE and hardware research - [devkitPro](https://devkitpro.org/) for All-In-One homebrew toolchains -- masagrator for [ReverseNX-RT](https://github.com/masagrator/ReverseNX-RT) and [BatteryChargeInfoNX](https://github.com/masagrator/BatteryChargeInfoNX) +- masagrator for [ReverseNX-RT](https://github.com/masagrator/ReverseNX-RT) and info on BatteryChargeInfoFields in psm module - Nvidia for [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual) - RetroNX team for [sys-clk](https://github.com/retronx-team/sys-clk) - SciresM and Reswitched Team for the state-of-the-art [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere) CFW of Switch diff --git a/SdOut/oc.ini b/SdOut/oc.ini deleted file mode 100644 index 75a59b2c..00000000 --- a/SdOut/oc.ini +++ /dev/null @@ -1,2 +0,0 @@ -[emc] -volt=600000 diff --git a/SdOut/switch/.overlays/InfoNX-ovl.ovl b/SdOut/switch/.overlays/InfoNX-ovl.ovl deleted file mode 100644 index c468ac3d..00000000 Binary files a/SdOut/switch/.overlays/InfoNX-ovl.ovl and /dev/null differ diff --git a/SdOut/switch/.overlays/sys-clk-overlay.ovl b/SdOut/switch/.overlays/sys-clk-overlay.ovl index fcdcb021..8d35c3b1 100644 Binary files a/SdOut/switch/.overlays/sys-clk-overlay.ovl and b/SdOut/switch/.overlays/sys-clk-overlay.ovl differ diff --git a/Source/InfoNX/.gitignore b/Source/InfoNX/.gitignore deleted file mode 100644 index 6b42bc57..00000000 --- a/Source/InfoNX/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ - -build/ - -*.ovl - -*.elf - -*.nacp - -*.nro -*.DS_Store diff --git a/Source/InfoNX/Makefile b/Source/InfoNX/Makefile deleted file mode 100644 index 8287157d..00000000 --- a/Source/InfoNX/Makefile +++ /dev/null @@ -1,208 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") -endif - -TOPDIR ?= $(CURDIR) -include $(DEVKITPRO)/libnx/switch_rules - -#--------------------------------------------------------------------------------- -# TARGET is the name of the output -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# DATA is a list of directories containing data files -# INCLUDES is a list of directories containing header files -# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional) -# -# NO_ICON: if set to anything, do not use icon. -# NO_NACP: if set to anything, no .nacp file is generated. -# APP_TITLE is the name of the app stored in the .nacp file (Optional) -# APP_AUTHOR is the author of the app stored in the .nacp file (Optional) -# APP_VERSION is the version of the app stored in the .nacp file (Optional) -# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional) -# ICON is the filename of the icon (.jpg), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .jpg -# - icon.jpg -# - /default_icon.jpg -# -# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .json -# - config.json -# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead -# of a homebrew executable (.nro). This is intended to be used for sysmodules. -# NACP building is skipped as well. -#--------------------------------------------------------------------------------- -APP_TITLE := InfoNX -APP_VERSION := 1.0.1 - -TARGET := InfoNX-ovl -BUILD := build -SOURCES := source -DATA := data -INCLUDES := libs/libtesla/include - -NO_ICON := 1 - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE - -CFLAGS := -g -Wall -Os -ffunction-sections \ - $(ARCH) $(DEFINES) - -CFLAGS += $(INCLUDE) -D__SWITCH__ -DAPP_VERSION="\"$(APP_VERSION)\"" - -CXXFLAGS := $(CFLAGS) -fno-exceptions -std=c++20 - -ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) - -LIBS := -lnx - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(PORTLIBS) $(LIBNX) - - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export OUTPUT := $(CURDIR)/$(TARGET) -export TOPDIR := $(CURDIR) - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -export DEPSDIR := $(CURDIR)/$(BUILD) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES_BIN := $(addsuffix .o,$(BINFILES)) -export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) -export OFILES := $(OFILES_BIN) $(OFILES_SRC) -export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) - -ifeq ($(strip $(CONFIG_JSON)),) - jsons := $(wildcard *.json) - ifneq (,$(findstring $(TARGET).json,$(jsons))) - export APP_JSON := $(TOPDIR)/$(TARGET).json - else - ifneq (,$(findstring config.json,$(jsons))) - export APP_JSON := $(TOPDIR)/config.json - endif - endif -else - export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) -endif - -ifeq ($(strip $(ICON)),) - icons := $(wildcard *.jpg) - ifneq (,$(findstring $(TARGET).jpg,$(icons))) - export APP_ICON := $(TOPDIR)/$(TARGET).jpg - else - ifneq (,$(findstring icon.jpg,$(icons))) - export APP_ICON := $(TOPDIR)/icon.jpg - endif - endif -else - export APP_ICON := $(TOPDIR)/$(ICON) -endif - -ifeq ($(strip $(NO_ICON)),) - export NROFLAGS += --icon=$(APP_ICON) -endif - -ifeq ($(strip $(NO_NACP)),) - export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp -endif - -ifneq ($(APP_TITLEID),) - export NACPFLAGS += --titleid=$(APP_TITLEID) -endif - -ifneq ($(ROMFS),) - export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) -endif - -.PHONY: $(BUILD) clean all - -#--------------------------------------------------------------------------------- -all: $(BUILD) - - -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @rm -fr $(BUILD) $(TARGET).ovl $(TARGET).nro $(TARGET).nacp $(TARGET).elf - - -#--------------------------------------------------------------------------------- -else -.PHONY: all - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -all : $(OUTPUT).ovl - -$(OUTPUT).ovl : $(OUTPUT).elf $(OUTPUT).nacp - @elf2nro $< $@ $(NROFLAGS) - @echo "built ... $(notdir $(OUTPUT).ovl)" - -$(OUTPUT).elf : $(OFILES) - -$(OFILES_SRC) : $(HFILES_BIN) - -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -%.bin.o %_bin.h : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/Source/InfoNX/libs/libtesla b/Source/InfoNX/libs/libtesla deleted file mode 160000 index 640629f4..00000000 --- a/Source/InfoNX/libs/libtesla +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 640629f49f9e8997ef0769b21b26f4fc177c736f diff --git a/Source/InfoNX/source/main.cpp b/Source/InfoNX/source/main.cpp deleted file mode 100644 index 62e57ea4..00000000 --- a/Source/InfoNX/source/main.cpp +++ /dev/null @@ -1,411 +0,0 @@ -#define TESLA_INIT_IMPL // If you have more than one file using the tesla header, only define this in the main one -#include // The Tesla Header -#include -#include -#include -#include -#include -#include -#include "rgltr.h" - -#define IS_BAT_CHARGE_ON ((_batteryChargeInfoFields->unk_x14 >> 8) & 1) -#define IS_SLOW_CHARGE_ON (_batteryChargeInfoFields->ChargeCurrentLimit < 1024) - -static Service g_rgltrSrv; - -Result rgltrInitialize(void) { - if(hosversionBefore(8,0,0)) - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - - return smGetService(&g_rgltrSrv, "rgltr"); -} - -void rgltrExit(void) { - serviceClose(&g_rgltrSrv); -} - -Service* rgltrGetServiceSession(void) { - return &g_rgltrSrv; -} - -Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id) { - const u32 in = module_id; - return serviceDispatchIn(&g_rgltrSrv, 0, in, - .out_num_objects = 1, - .out_objects = &session_out->s, - ); -} - -Result rgltrGetPowerModuleNumLimit(u32 *out) { - return serviceDispatchOut(&g_rgltrSrv, 3, *out); -} - -void rgltrCloseSession(RgltrSession* session) { - serviceClose(&session->s); -} - -Result rgltrGetVoltageEnabled(RgltrSession* session, u32 *out) { - return serviceDispatchOut(&session->s, 2, *out); -} - -Result rgltrGetVoltage(RgltrSession* session, u32 *out_volt) { - return serviceDispatchOut(&session->s, 4, *out_volt); -} - -///* Notes VoltageAvg -// -// Vavg time = 175.8ms x 2^(6+VOLT), default: VOLT = 2 (Vavg time = 45s) -// -///End of Notes - -extern "C" bool is_mariko(); -extern "C" void clk_check(); - -typedef struct { - u32 cpu_out_hz; - u32 gpu_out_hz; - u32 emc_out_hz; - u32 cpu_out_volt; - u32 gpu_out_volt; - u32 emc_out_volt; -} ClkFields; - -bool is_mariko() { - u64 hardware_type = 0; - - splInitialize(); - splGetConfig(SplConfigItem_HardwareType, &hardware_type); - splExit(); - - switch(hardware_type) { - case 0: //Icosa - case 1: //Copper - return false; - case 2: //Hoag - case 3: //Iowa - case 4: //Calcio - case 5: //Aula - return true; - default: - return false; - } -} - -void clk_check(ClkFields *out, bool mariko) { - int res = 0; - - ClkrstSession clkrstSession; - RgltrSession rgltrSession; - - res = clkrstInitialize(); - if(R_FAILED(res)) { - fatalThrow(res); - } - - res = rgltrInitialize(); - if(R_FAILED(res)) { - fatalThrow(res); - } - - rgltrOpenSession(&rgltrSession, mariko ? PcvPowerDomainId_Max77812_Cpu : PcvPowerDomainId_Max77621_Cpu); - clkrstOpenSession(&clkrstSession, PcvModuleId_CpuBus, 3); - rgltrGetVoltage(&rgltrSession, &out->cpu_out_volt); - clkrstGetClockRate(&clkrstSession, &out->cpu_out_hz); - clkrstCloseSession(&clkrstSession); - rgltrCloseSession(&rgltrSession); - - rgltrOpenSession(&rgltrSession, mariko ? PcvPowerDomainId_Max77812_Gpu : PcvPowerDomainId_Max77621_Gpu); - clkrstOpenSession(&clkrstSession, PcvModuleId_GPU, 3); - rgltrGetVoltage(&rgltrSession, &out->gpu_out_volt); - clkrstGetClockRate(&clkrstSession, &out->gpu_out_hz); - clkrstCloseSession(&clkrstSession); - rgltrCloseSession(&rgltrSession); - - rgltrOpenSession(&rgltrSession, mariko ? PcvPowerDomainId_Max77812_Dram : PcvPowerDomainId_Max77620_Sd1); - clkrstOpenSession(&clkrstSession, PcvModuleId_EMC, 3); - rgltrGetVoltage(&rgltrSession, &out->emc_out_volt); - clkrstGetClockRate(&clkrstSession, &out->emc_out_hz); - clkrstCloseSession(&clkrstSession); - rgltrCloseSession(&rgltrSession); - - clkrstExit(); - rgltrExit(); -} - -typedef enum { - NoHub = BIT(0), //If hub is disconnected - Rail = BIT(8), //At least one Joy-con is charging from rail - SPDSRC = BIT(12), //OTG - ACC = BIT(16) //Accessory -} BatteryChargeInfoFieldsFlags; - -typedef enum { - NewPDO = 1, //Received new Power Data Object - NoPD = 2, //No Power Delivery source is detected - AcceptedRDO = 3 //Received and accepted Request Data Object -} BatteryChargeInfoFieldsPDControllerState; //BM92T series - -const char* strPDControllerState[] = { - "Received new PDO", - "No PD Source", - "Received/Accpted RDO" -}; - -typedef enum { - None = 0, - PD = 1, - TypeC_1500mA = 2, - TypeC_3000mA = 3, - DCP = 4, - CDP = 5, - SDP = 6, - Apple_500mA = 7, - Apple_1000mA = 8, - Apple_2000mA = 9 -} BatteryChargeInfoFieldsChargerType; - -const char* strChargerType[] = { - "None", - "PD", - "USB-C@1.5A", - "USB-C@3.0A", - "USB-DCP", - "USB-CDP", - "USB-SDP", - "Apple@0.5A", - "Apple@1.0A", - "Apple@2.0A", -}; - -typedef enum { - Sink = 1, - Source = 2 -} BatteryChargeInfoFieldsPowerRole; - -const char* strPowerRole[] = { - "Sink", - "Source", -}; - -typedef struct { - int32_t InputCurrentLimit; //Input (Sink) current limit in mA - int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA - int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C) - int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C) - int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases - int32_t unk_x14; //Possibly flags - BatteryChargeInfoFieldsPDControllerState PDControllerState; //Power Delivery Controller State - int32_t BatteryTemperature; //Battery temperature in milli C - int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm) - int32_t VoltageAvg; //Voltage avg in mV (more in Notes) - int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm) - BatteryChargeInfoFieldsPowerRole PowerRole; - BatteryChargeInfoFieldsChargerType ChargerType; - int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV - int32_t ChargerCurrentLimit; //Charger and external device current limit in mA - BatteryChargeInfoFieldsFlags Flags; //Unknown flags -} BatteryChargeInfoFields; - -Result psmGetBatteryChargeInfoFields(Service* psmService, BatteryChargeInfoFields *out) { - return serviceDispatchOut(psmService, 17, *out); -} - -static Result psmEnableBatteryCharging(Service* psmService) { - return serviceDispatch(psmService, 2); -} - -static Result psmDisableBatteryCharging(Service* psmService) { - return serviceDispatch(psmService, 3); -} - -static Result psmDisableSlowCharging(Service* psmService) { - return serviceDispatch(psmService, 10); -} - -static Result psmEnableSlowCharging(Service* psmService) { - return serviceDispatch(psmService, 11); -} - -FanController g_ICon; -float rotationSpeedLevel = 0; -unsigned int changeSlowChargingState = 0; -unsigned int changeDisableChargingState = 0; - -bool threadexit = false; -int32_t socTempMili = 0; -char Print_x[800]; -Thread t0; -bool IsEnoughPowerSupplied; - -void Loop(void*) { - static Service* psmService = psmGetServiceSession(); - static BatteryChargeInfoFields* _batteryChargeInfoFields = new BatteryChargeInfoFields; - static ClkFields* _clkFields = new ClkFields; - while (threadexit == false) { - if(changeSlowChargingState) - { - changeSlowChargingState = 0; - if(IS_SLOW_CHARGE_ON) - psmDisableSlowCharging(psmService); - else - psmEnableSlowCharging(psmService); - } - if(changeDisableChargingState) - { - changeDisableChargingState = 0; - if(IS_BAT_CHARGE_ON) - psmDisableBatteryCharging(psmService); - else - psmEnableBatteryCharging(psmService); - } - - psmGetBatteryChargeInfoFields(psmService, _batteryChargeInfoFields); - clk_check(_clkFields, is_mariko()); - tsGetTemperatureMilliC(TsLocation_External, &socTempMili); - psmIsEnoughPowerSupplied(&IsEnoughPowerSupplied); - fanControllerGetRotationSpeedLevel(&g_ICon, &rotationSpeedLevel); - - snprintf(Print_x, sizeof(Print_x), - "Current Limit: %u mA IN, %u mA OUT" - "\nBattery Charg. Limit: %u mA, %u mV" - "\nunk_x10: 0x%08" PRIx32 - "\nunk_x14: 0x%08" PRIx32 - "\nPD Contr. State: %s (%u)" - "\nBattery Temp.: %.2f\u00B0C" - "\nRaw Battery Charge: %.2f%%" - "\nVoltage Avg: %u mV" - "\nBattery Age: %.2f%%" - "\nPower Role: %s (%u)" - "\nCharger Type: %s (%u)" - "\nCharger Limit: %u mV, %u mA" - "\nunk_x3c: 0x%08" PRIx32 - "\nEnough Power Supplied: %s" - "\n" - "\nCPU Clock: %6.1f MHz" - "\nCPU Volt : %6.1f mV\n" - "\nGPU Clock: %6.1f MHz" - "\nGPU Volt : %6.1f mV\n" - "\nEMC Clock: %6.1f MHz" - "\nEMC Volt : %6.1f mV\n" - "\nSoC Temp : %2.2f \u00B0C" - "\nFan Speed: %2.2f %%\n" - "\nL-Stick: Slow Charging(0.5A) (%s)" - "\nR-Stick: Disable Charging (%s)" - , - _batteryChargeInfoFields->InputCurrentLimit, - _batteryChargeInfoFields->VBUSCurrentLimit, - _batteryChargeInfoFields->ChargeCurrentLimit, - _batteryChargeInfoFields->ChargeVoltageLimit, - _batteryChargeInfoFields->unk_x10, - _batteryChargeInfoFields->unk_x14, - strPDControllerState[_batteryChargeInfoFields->PDControllerState], _batteryChargeInfoFields->PDControllerState, - (float)_batteryChargeInfoFields->BatteryTemperature / 1000, - (float)_batteryChargeInfoFields->RawBatteryCharge / 1000, - _batteryChargeInfoFields->VoltageAvg, - (float)_batteryChargeInfoFields->BatteryAge / 1000, - strPowerRole[_batteryChargeInfoFields->PowerRole], _batteryChargeInfoFields->PowerRole, - strChargerType[_batteryChargeInfoFields->ChargerType], _batteryChargeInfoFields->ChargerType, - _batteryChargeInfoFields->ChargerVoltageLimit, - _batteryChargeInfoFields->ChargerCurrentLimit, - (int32_t)_batteryChargeInfoFields->Flags, - IsEnoughPowerSupplied ? "Yes" : "No", - (double)_clkFields->cpu_out_hz / 1000000, - (double)_clkFields->cpu_out_volt / 1000, - (double)_clkFields->gpu_out_hz / 1000000, - (double)_clkFields->gpu_out_volt / 1000, - (double)_clkFields->emc_out_hz / 1000000, - (double)_clkFields->emc_out_volt / 1000, - (float)socTempMili / 1000, - rotationSpeedLevel * 100, - IS_SLOW_CHARGE_ON ? "ON" : "OFF", - !IS_BAT_CHARGE_ON ? "ON" : "OFF" - ); - svcSleepThread(800'000'000); - } - delete _batteryChargeInfoFields; - delete _clkFields; -} - -class GuiTest : public tsl::Gui { -public: - GuiTest(u8 arg1, u8 arg2, bool arg3) { } - - // Called when this Gui gets loaded to create the UI - // Allocate all elements on the heap. libtesla will make sure to clean them up when not needed anymore - virtual tsl::elm::Element* createUI() override { - // A OverlayFrame is the base element every overlay consists of. This will draw the default Title and Subtitle. - // If you need more information in the header or want to change it's look, use a HeaderOverlayFrame. - auto frame = new tsl::elm::OverlayFrame("InfoNX", APP_VERSION); - - // A list that can contain sub elements and handles scrolling - auto list = new tsl::elm::List(); - - list->addItem(new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { - renderer->drawString(Print_x, false, x, y+20, 15, renderer->a(0xFFFF)); - }), 500); - - // Add the list to the frame for it to be drawn - frame->setContent(list); - - - // Return the frame to have it become the top level element of this Gui - return frame; - } - - // Called once every frame to update values - virtual void update() override {} - - // Called once every frame to handle inputs not handled by other UI elements - virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override { - if (keysHeld & HidNpadButton_A) { - tsl::hlp::requestForeground(false); - return true; - } - if (keysHeld & HidNpadButton_StickL) { - changeSlowChargingState++; - return true; - } - if (keysHeld & HidNpadButton_StickR) { - changeDisableChargingState++; - return true; - } - return false; // Return true here to singal the inputs have been consumed - } -}; - -class OverlayTest : public tsl::Overlay { -public: - // libtesla already initialized fs, hid, pl, pmdmnt, hid:sys and set:sys - virtual void initServices() override { - smInitialize(); - psmInitialize(); - tsInitialize(); - fanInitialize(); - fanOpenController(&g_ICon, 0x3D000001); - threadCreate(&t0, Loop, NULL, NULL, 0x4000, 0x3F, -2); - threadStart(&t0); - } // Called at the start to initialize all services necessary for this Overlay - - virtual void exitServices() override { - threadexit = true; - threadWaitForExit(&t0); - threadClose(&t0); - fanControllerClose(&g_ICon); - fanExit(); - tsExit(); - psmExit(); - smExit(); - } // Callet at the end to clean up all services previously initialized - - virtual void onShow() override {} // Called before overlay wants to change from invisible to visible state - - virtual void onHide() override {} // Called before overlay wants to change from visible to invisible state - - virtual std::unique_ptr loadInitialGui() override { - return initially(1, 2, true); // Initial Gui to load. It's possible to pass arguments to it's constructor like this - } -}; - -int main(int argc, char **argv) { - return tsl::loop(argc, argv); -} diff --git a/Source/InfoNX/source/pcv_types.h b/Source/InfoNX/source/pcv_types.h deleted file mode 100644 index 50d3e3ea..00000000 --- a/Source/InfoNX/source/pcv_types.h +++ /dev/null @@ -1,41 +0,0 @@ -typedef enum { - PcvPowerDomain_Max77620_Sd0 = 0, - PcvPowerDomain_Max77620_Sd1 = 1, - PcvPowerDomain_Max77620_Sd2 = 2, - PcvPowerDomain_Max77620_Sd3 = 3, - PcvPowerDomain_Max77620_Ldo0 = 4, - PcvPowerDomain_Max77620_Ldo1 = 5, - PcvPowerDomain_Max77620_Ldo2 = 6, - PcvPowerDomain_Max77620_Ldo3 = 7, - PcvPowerDomain_Max77620_Ldo4 = 8, - PcvPowerDomain_Max77620_Ldo5 = 9, - PcvPowerDomain_Max77620_Ldo6 = 10, - PcvPowerDomain_Max77620_Ldo7 = 11, - PcvPowerDomain_Max77620_Ldo8 = 12, - PcvPowerDomain_Max77621_Cpu = 13, - PcvPowerDomain_Max77621_Gpu = 14, - PcvPowerDomain_Max77812_Cpu = 15, - PcvPowerDomain_Max77812_Gpu = 16, - PcvPowerDomain_Max77812_Dram = 17, -} PowerDomain; - -typedef enum { - PcvPowerDomainId_Max77620_Sd0 = 0x3A000080, - PcvPowerDomainId_Max77620_Sd1 = 0x3A000081, - PcvPowerDomainId_Max77620_Sd2 = 0x3A000082, - PcvPowerDomainId_Max77620_Sd3 = 0x3A000083, - PcvPowerDomainId_Max77620_Ldo0 = 0x3A0000A0, - PcvPowerDomainId_Max77620_Ldo1 = 0x3A0000A1, - PcvPowerDomainId_Max77620_Ldo2 = 0x3A0000A2, - PcvPowerDomainId_Max77620_Ldo3 = 0x3A0000A3, - PcvPowerDomainId_Max77620_Ldo4 = 0x3A0000A4, - PcvPowerDomainId_Max77620_Ldo5 = 0x3A0000A5, - PcvPowerDomainId_Max77620_Ldo6 = 0x3A0000A6, - PcvPowerDomainId_Max77620_Ldo7 = 0x3A0000A7, - PcvPowerDomainId_Max77620_Ldo8 = 0x3A0000A8, - PcvPowerDomainId_Max77621_Cpu = 0x3A000003, - PcvPowerDomainId_Max77621_Gpu = 0x3A000004, - PcvPowerDomainId_Max77812_Cpu = 0x3A000003, - PcvPowerDomainId_Max77812_Gpu = 0x3A000004, - PcvPowerDomainId_Max77812_Dram = 0x3A000005, -} PowerDomainId; \ No newline at end of file diff --git a/Source/InfoNX/source/rgltr.h b/Source/InfoNX/source/rgltr.h deleted file mode 100644 index 1b1c2be1..00000000 --- a/Source/InfoNX/source/rgltr.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -//#include "../types.h" -//#include "../sf/service.h" -//#include "../services/pcv.h" -#include -#include "pcv_types.h" - -typedef struct { - Service s; -} RgltrSession; - -Result rgltrInitialize(void); - -void rgltrExit(void); - -Service* rgltrGetServiceSession(void); - -Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id); -void rgltrCloseSession(RgltrSession* session); -Result rgltrGetVoltage(RgltrSession* session, u32 *out_volt); -Result rgltrGetPowerModuleNumLimit(u32 *out); -Result rgltrGetVoltageEnabled(RgltrSession* session, u32 *out); \ No newline at end of file diff --git a/Source/MemTesterNX/source/main.c b/Source/MemTesterNX/source/main.c index 43308259..035adcc8 100644 --- a/Source/MemTesterNX/source/main.c +++ b/Source/MemTesterNX/source/main.c @@ -384,10 +384,8 @@ int main(int argc, char* argv[]) for (int j = 0; j < testThreads; j++) testJobId[j] = -1; - ull count = 0; for (int j = 0; j < testThreads; ) { - count++; switch (testWorkerReport[j]) { case 0: diff --git a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp index bb61fc01..3dff72bb 100644 --- a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp @@ -1,5 +1,4 @@ -/* - * -------------------------------------------------------------------------- +/* -------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * , , * wrote this file. As long as you retain this notice you can do whatever you @@ -27,7 +26,7 @@ void MiscGui::preDraw(tsl::gfx::Renderer* render) { BaseMenuGui::preDraw(render); - render->drawString(this->psmOutput, false, 40, 300, SMALL_TEXT_SIZE, DESC_COLOR); + render->drawString(this->infoOutput, false, 40, 300, SMALL_TEXT_SIZE, DESC_COLOR); } void MiscGui::listUI() @@ -70,7 +69,7 @@ void MiscGui::update() { frameCounter = 0; PsmUpdate(); - PsmGetInfo(this->psmOutput, sizeof(this->psmOutput)); + GetInfo(this->infoOutput, sizeof(this->infoOutput)); this->chargingToggle->setState(this->PsmIsCharging()); this->fastChargingToggle->setState(this->PsmIsFastCharging()); } diff --git a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h index 66e5ac97..c2cbde5d 100644 --- a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h +++ b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h @@ -1,5 +1,4 @@ -/* - * -------------------------------------------------------------------------- +/* -------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * , , * wrote this file. As long as you retain this notice you can do whatever you @@ -102,6 +101,13 @@ class MiscGui : public BaseMenuGui ChargeInfoFlags Flags; //Unknown flags } ChargeInfo; + typedef enum + { + Max17050Reg_Current = 0x0A, + Max17050Reg_AvgCurrent = 0x0B, + Max17050Reg_Cycle = 0x17, + } Max17050Reg; + void PsmUpdate(uint32_t dispatchId = 0) { smInitialize(); @@ -140,35 +146,114 @@ class MiscGui : public BaseMenuGui return this->isEnoughPowerSupplied; } - void PsmGetInfo(char* out, size_t outsize) + Result I2cReadRegHandler(u8 reg, I2cDevice dev, u16 *out) + { + // ams::fatal::srv::StopSoundTask::StopSound() + // I2C Bus Communication Reference: https://www.ti.com/lit/an/slva704/slva704.pdf + struct { u8 reg; } __attribute__((packed)) cmd; + struct { u16 val; } __attribute__((packed)) rec; + + I2cSession _session; + + Result res = i2cOpenSession(&_session, dev); + if (res) + return res; + + cmd.reg = reg; + res = i2csessionSendAuto(&_session, &cmd, sizeof(cmd), I2cTransactionOption_All); + if (res) + { + i2csessionClose(&_session); + return res; + } + + res = i2csessionReceiveAuto(&_session, &rec, sizeof(rec), I2cTransactionOption_All); + if (res) + { + i2csessionClose(&_session); + return res; + } + + *out = rec.val; + i2csessionClose(&_session); + return 0; + } + + bool Max17050ReadReg(u8 reg, u16 *out) + { + u16 data = 0; + Result res = I2cReadRegHandler(reg, I2cDevice_Max17050, &data); + + if (res) + { + *out = res; + return false; + } + + *out = data; + return true; + } + + void GetInfo(char* out, size_t outsize) { float chargerVoltLimit = (float)chargeInfo->ChargerVoltageLimit / 1000; float chargerCurrLimit = (float)chargeInfo->ChargerCurrentLimit / 1000; float chargerOutWatts = chargerVoltLimit * chargerCurrLimit; + float batCurrent = 0; + float batCycleCount = 0; + char chargeVoltLimit[20] = ""; if (chargeInfo->ChargeVoltageLimit) snprintf(chargeVoltLimit, sizeof(chargeVoltLimit), ", %u mV", chargeInfo->ChargeVoltageLimit); + // From Hekate, too lazy to query configuration from reg + constexpr float max17050SenseResistor = 5.; // in uOhm + constexpr float max17050CGain = 1.99993; + + // Init, read registers and exit I2C service all here to save resources + { + smInitialize(); + i2cInitialize(); + u16 data = 0; + + if (Max17050ReadReg(Max17050Reg_Cycle, &data)) + batCycleCount = data / 100.; + + if (Max17050ReadReg(Max17050Reg_Current, &data)) + batCurrent = (s16)data * (1.5625 / (max17050SenseResistor * max17050CGain)); + + i2cExit(); + smExit(); + } + + char batWattsInfo[20] = ""; + if (std::abs(batCurrent) > 100) + snprintf(batWattsInfo, sizeof(batWattsInfo), " (%+.2f W)", batCurrent * (float)chargeInfo->VoltageAvg / 1000'000); + snprintf(out, outsize, - "Charger: %s %.1fV/%.1fA (%.1fW)" - "\n%s" - "\nBattery: %.3fV %.2f\u00B0C" - "\nCurrent Limit: %u mA IN, %u mA OUT" - "\nCharging Limit: %u mA%s" - "\nRaw Charge: %.2f%%" - "\nBattery Age: %.2f%%" - "\nPower Role: %s" + "%s" + "\nCharger: %s %.1fV/%.1fA (%.1fW)" + "\nBattery: %.3fV %.2f\u00B0C" + "\nCurrent Limit: %u mA IN, %u mA OUT" + "\nCharging Limit: %u mA%s" + "\nRaw Charge: %.2f%%" + "\nBattery Age: %.2f%%" + "\nPower Role: %s" + "\nCycle Count: %.2f (Reset at power-up)" + "\nCurrent Flow: %+.2f mA%s" , - ChargeInfoChargerTypeToStr(chargeInfo->ChargerType), chargerVoltLimit, chargerCurrLimit, chargerOutWatts, PsmIsEnoughPowerSupplied() ? "Enough Power Supplied" : "", + ChargeInfoChargerTypeToStr(chargeInfo->ChargerType), chargerVoltLimit, chargerCurrLimit, chargerOutWatts, (float)chargeInfo->VoltageAvg / 1000, (float)chargeInfo->BatteryTemperature / 1000, chargeInfo->InputCurrentLimit, chargeInfo->VBUSCurrentLimit, chargeInfo->ChargeCurrentLimit, chargeVoltLimit, (float)chargeInfo->RawBatteryCharge / 1000, (float)chargeInfo->BatteryAge / 1000, - ChargeInfoPowerRoleToStr(chargeInfo->PowerRole) + ChargeInfoPowerRoleToStr(chargeInfo->PowerRole), + batCycleCount, + batCurrent, batWattsInfo ); } @@ -196,6 +281,6 @@ class MiscGui : public BaseMenuGui ChargeInfo* chargeInfo; bool isEnoughPowerSupplied = false; - char psmOutput[800] = ""; + char infoOutput[800] = ""; int frameCounter = 60; };