PINE64

Full Version: Reading the CPU temperature
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have been trying, unsuccessfully, to read the temperature from the TS-ADC controller. I have configured the various TSADC registers and. as far as I can tell, the relevant clocks are all enabled. Still, any attempt to read TSADC_DATA0 results in 0. Also, if I understand correctly, the value of TSADC_USER_CON shows that the analog-to-digital conversion never finishes.

Here are the values of the various registers that I believe are related to the TSADC:


Code:
CRU_CLKSEL_CON27=1f (DIV=1f SEL=0)
CRU_CLKGATE_CON9=0 (TSADC=0)
CRU_CLKGATE_CON22=0 (PCLK_TSADC=0)
CRU_CLKSEL_CON25=187
CRU_CLKGATE_CON8=0 (PERILP1=0)
GRF_SARADC_TESTBIT=4
GRF_TSADC_TESTBIT_L=80
GRF_TSADC_TESTBIT_H=84
TSADC_USER_CON=1200
TSADC_AUTO_CON=10133
TSADC_AUTO_PERIOD=753
TSADC_AUTO_PERIOD_HT=753
TSADC_HIGHT_INT_DEBOUNCE=4
TSADC_HIGHT_TSHUT_DEBOUNCE=4

Am I missing anything?

Thanks,
--Elad
Are you doing some bare metal programming? I see you have clock, is there maybe also a power register somewhere? Maybe have a look at the Linux driver ...
(11-16-2019, 12:06 PM)xalius Wrote: [ -> ]Are you doing some bare metal programming? I see you have clock, is there maybe also a power register somewhere? Maybe have a look at the Linux driver ...

Yes, I looked at both the Linux and NetBSD drivers, and couldn't find anything beyond what I have. The drivers themselves rely on the device tree for clocks, but I followed the tree up as much as I could, and believe that all relevant clocks are enabled by default.
I'm running QNX on the board. Got the basics up (all 6 cores, MMU, GIC, timers, UART) but I'm afraid of ramping up the core frequency on the two clusters without monitoring the CPU temperature.

OK, got it to work. Probably just needed to be more careful with all the clocks:

Code:
// Assert reset.
out32(cru_regs + 0x438, (0x10001 << 8));
printf("CRU_SOFTRST_CON14=%x\n", in32(cru_regs + 0x438));

// Set up clocks
// HCLK_PERILP1, PCLK_PERILP1
out32(cru_regs + CRU_CLKSEL_CON25, 0x079f0187);
out32(cru_regs + CRU_CLKGATE_CON8, (0x10000 << 2));

// SCLK_TSADC
out32(cru_regs + CRU_CLKSEL_CON27, 0x83ff001f);
out32(cru_regs + CRU_CLKGATE_CON9, (0x10000 << 10));

// PCLK_TSADC
out32(cru_regs + CRU_CLKGATE_CON22, (0x10000 << 13));

// De-assert reset
usleep(20);
out32(cru_regs + 0x438, (0x10000 << 8));
printf("CRU_SOFTRST_CON14=%x\n", in32(cru_regs + 0x438));

// Whatever this is...
out32(grf_regs + 0x0e648, (0x10001 << 7));
out32(grf_regs + 0x0e64c, (0x10001 << 7));
usleep(20);
out32(grf_regs + 0x0e644, (0x10001 << 2));
out32(grf_regs + 0x0e64c, (0x10001 << 2));
usleep(100);

// Set up auto mode.
out32(tsadc_regs + TSADC_AUTO_PERIOD, 1875);
out32(tsadc_regs + TSADC_AUTO_PERIOD_HT, 1875);
out32(tsadc_regs + TSADC_HIGHT_INT_DEBOUNCE, 4);
out32(tsadc_regs + TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
Good Wink also if you are worried about your hardware, there is a fail-safe circuit that connects the over temperature output to reset, so as long as the overtemperature condition exists, the RK3399 will be held in reset.