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