Questions about the temperature sensor (TEMP)

Hi.

I am experimenting with an internal temperature sensor (TEMP) on an nRF52810 microcontroller and have some questions: 

1. How to select a crystal oscillator as a source of HFCLK to achieve better temperature sensor performance?

2. How to measure the time (in microseconds) in which the microcontroller completes the temperature measurement (the time between TASKS_START and DATARDY)? 

Thanks.

  • I tried to use the Executing Time Functions from Zephyr to measure time (in nanoseconds), but I think the result of the measurement is wrong.

    My program code -->

    ...
    #include <zephyr/timing/timing.h>
    ...
    
    /* TEMP */
    #define TEMP_BASE           (0x4000C000U)
    #define TEMP_TASKS_START    (TEMP_BASE + 0x000U)
    #define TEMP_TASKS_STOP     (TEMP_BASE + 0x004U)
    #define TEMP_EVENTS_DATARDY (TEMP_BASE + 0x100U)
    #define TEMP_TEMP           (TEMP_BASE + 0x508U)
    
    int main(void)
    { 	
    	int32_t tmp;
    	timing_t start_time, end_time;
    	uint64_t total_cycles;
        uint64_t total_ns;
    
    	timing_init();
    	
    	while (1) {
    	
    		timing_start();
    		*(uint32_t *)TEMP_TASKS_START = 1;
    		
    		start_time = timing_counter_get();
    		while (TEMP_EVENTS_DATARDY == 0) {
            	// need to wait for the event, an empty loop won't work
      	    }
    		end_time = timing_counter_get();
    
        	total_cycles = timing_cycles_get(&start_time, &end_time);
        	total_ns = timing_cycles_to_ns(total_cycles);
    
    		timing_stop();
    		LOG_INF("Temperature measurement time = %d ns", total_ns);
    		
    		tmp = *(int32_t *)TEMP_TEMP / 4;
    		LOG_INF("SoC temperature = %d\n", tmp);
    		
    		k_msleep(5000);
    	}
    	return 0;
    }

    Terminal output -->

    As you can see the function returns 1125 nanoseconds (1.125 microseconds), although the documentation says that the temperature calculation time is about 36 microseconds. 

    Can you please tell me where I'm making a mistake?
    Thank you.

  • Hi,

     

    You are not clearing your events, and it seems that you're also not dereferencing TEMP_EVENTS_DATARDY. The data types are returned as 64 bit length, so you need to print as "%lld" types.

    I would recommend that you rather include "nrf.h" and access the temp directly (or include nrf_temp.h and use that API):

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/zephyr.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/timing/timing.h>
    #include "nrf.h"
    
    int main(void)
    {
    	int32_t tmp;
    	timing_t start_time, end_time;
    	uint64_t total_cycles;
    	uint64_t total_ns;
    	timing_init();
    	while (1) {
    		timing_start();
    		NRF_TEMP->TASKS_START = 1;
    		start_time = timing_counter_get();
    		while (NRF_TEMP->EVENTS_DATARDY == 0) {}
    		end_time = timing_counter_get();
    		timing_stop();		
    		NRF_TEMP->EVENTS_DATARDY = 0;
    		printk("Temperature measurement time = %lld ns\n", timing_cycles_to_ns(timing_cycles_get(&start_time, &end_time)));
    		tmp = (int32_t)NRF_TEMP->TEMP / 4;
    		printk("SoC temperature = %d\n", tmp);
    		NRF_TEMP->TASKS_STOP = 1;
    		k_msleep(5000);
    	}
    	return 0;
    }
    

     

    This will print approx. 35 us:

    Temperature measurement time = 35437 ns

     

    Kind regards,

    Håkon

  • Hi Håkon. Thank you for your reply.

    Yeah, your advice worked. When I include "nrf.h" I get the temperature calculation in 35 ns.

    Could you please answer my first question. How can I select an external generator as HFCLK and be sure that the temperature measurement performance will improve?

    Thanks.

  • Either use clock_control module (recommended approach, as other modules might also request HFCLK):

    https://github.com/nrfconnect/sdk-nrf/blob/v2.5.0/samples/cellular/at_client/src/main.c#L16-L24

     

    Or, you can directly start it via the registers:

    NRF_CLOCK->TASKS_HFCLKSTART = 1;

    while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);

    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

     

    Kind regards,

    Håkon

Related