CPU Temperature Shenanigans
I'll try to keep this somewhat short w/o rambling.

I wanted to make a code to read Broadway's CPU temp
All 3 thermal registers are set to always be null in Broadway (they are on disabled on purpose, specifically stated so in the manual)
Can only read Broadway CPU temp with separate device sending amps to the diode and reading the returned voltage
Broadway Manual makes absolutely zero mention of a Thermal Interrupt routine
But the Thermal Interrupt is present at 0x1700
The Interrupt is unused though from my limited tests
Still somehow the Wii knows to shut itself off when I disable the Fan (via code) and the Wii gets too hot (40ish minutes on MKW TT mode)

So anyway.... on the Gamecube console, all the Thermal Registers are used. Thus we can get the Gekko CPU temp.

I have a GC but no cables!

Anyway here is a snippet of source to read Gekko's temp. It "works" on Dolphin, meaning when I place in fake bit values for the read-only bits, the code responds correctly to values of those read-only bits.


#Temperature Read code crap, works on Dolphin when you simulate fake THRM register bit responses on the read-only bits
#Wont work on Wii, intended for GC, not tested on real hardware

#SPR list
#1020 = THRM1
#1021 = THRM2
#1022 = THRM3 (the TAU aka Thermal Assist Unit)

#TAU is currently running, disable it. Clear any previous data.
li r0, 0
mtspr 1022, r0

#We want to use TAU in single mode, disable usage of THRM2
#Clear the V (SPR valid) bit; bit 31
#I might be able to just write null to the register to disable it, but it may cause a program exception due to possibly writing new values to the read-only bits. Play it safe.
mfspr r0, 1021
rlwinm r0, r0, 0, 0, 30
mtspr 1021, r0

#Prepare THRM1
#Enable it (V high)
#Disable Thermal Interrupts (TIE low)
#Set initial threshold of 0x40 degress celisus (bits 2 thru 8)
#Clear TID bit so when TIN is high, we know above threshold, and when TIN is low we below it
mfspr r0, 1020
andis. r0, r0, 0xC000 #Clear everything out but the read-only bits
oris r0, r0, 0x2000 #Bits 2 thru 8 are set to value of 0x40
ori r0, r0, 0x0001 #Flip V (spr valid) bit high
mtspr 1020, r0

#Prepare THRM3
#Enable it (E bit high)
#Don't have any calibration set
#Set timer cycles to max (0x1FFF); the more cycles, the more accurate the reading; bits 18 thru 30 all high
li r0, 0x3FFF

#Start the TAU!
mtspr 1022, r0

#The most you can poll is 5 times, due to temperature readings being in 4*C increments. Poll 5 times for the highest accuracy.
#Set loop to 5
li r0, 5
mtctr r0

#Set initial threshold increment/decrement value (0x20)
li r5, 0x40 #Will be halved before first iteration, hence why we first set it to 0x40

#Temperature Check Loop

#Read THRM1
mfspr r3, 1020

#Temp is above threshold when following bits are this.. (combo only correct when TID is set to 0)
#TIN = 1
#TIV = 1

#Temp is below threshold when bits are this (only correct when TID is set to 0)
#TIN = 0
#TIV = 1

#Check if TIV is high (valid)
#This tells temperature has crossed the threshold
andis. r0, r3, 0x4000
beq- loop

#Temperature has crossed threshold, figure out if it crossed above or below (check TIN bit)
andis. r0, r3, 0x8000

#Extract the threshold from THRM1 and right align it, divide r5 by 2, adjust current threshold by new amount in r5
rlwinm r4, r3, 9, 25, 31
srwi r5, r5, 1

#Now branch
beq- lower_threshold

#Temperature is above threshold; raise it
add r0, r4, r5
b decrement_loop

#Temperature is below threshold; lower it
subf r0, r5, r4 #Equivalent to sub r0, r4, r5

#Place in new threshold value, update THRM1, decrement Loop
rlwimi r3, r0, 23, 2, 8 #Shift r0's value (new threshold) to be in bits 2 thru 8; then replace those bits into r3 while leaving all other r3's bits alone
mtspr 1020, r3
bdnz+ loop

#Loop is over, place latest iteration of r4 as the result; is this even accurate, lol?
mr r3, r4

If somebody can use devkitpro to compile a GC-specific dol file for a program that simply printf's the temperature, that would be appreciated.

Forum Jump:

Users browsing this thread: 1 Guest(s)