While testing our custom Hardware with the nRF52840 in a climate chamber in the -40°C to +85°C range i noticed that the value read from the internal temperature sensor was much too low at -40°C. According to the specification the deviation should be within the -5°C to +5°C range over the whole operating temperature range. I am aware of the erratum 66 and have implemented the initialization code for this.
At high temperatures the accuracy is OK, i only see this large deviation at very low temperatures. I tested 12 PCBs simultaneously. Of 12 boards only 3 gave a temperature measurement result of -45°C or higher at -40°C climate chamber temperature. All remaining boards showed values below -45°C The lowest value i have seen on one board was -55,25°C.
I compared the internal CPU temperatures to a TMP1075 I²C temperature sensor mounted on the same board.. The TMP1075 sensors saw a temperature within the range of -39°C to -37°C during the same measurements..
Below is the code used to initialize and read the temperature sensor. I'm not 100% sure about this, as i didn't have any example code available, but the initialization should be ok, i just copied the suggested workaround from the errata sheet..
void init_cpu_temp_sensor(void)
{
NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
}
float read_cpu_temp_sensor(void)
{
int result;
NRF_TEMP->TASKS_START = 1;
NRF_TEMP->EVENTS_DATARDY = 0;
// Read it back to ensure it is written (needed on cortex m4)
volatile uint32_t dummy = NRF_TEMP->EVENTS_DATARDY;
(void) dummy;
while (0 == NRF_TEMP->EVENTS_DATARDY);
result = NRF_TEMP->TEMP;
NRF_TEMP->TASKS_STOP = 1;
return (float)result / 4;
}
Assuming that the code is ok (i hope so), what else could cause this high deviation of the temperature reading?
Best regards
Frank