Page 1 of 1

ULP RISC-V temperature sensor configuration

Posted: Mon Apr 26, 2021 3:23 pm
by bitmandu
I am trying to take periodic temperature measurements from the ULP RISC-V coprocessor on the ESP32-s2.

The following code reads the on-chip temperature sensor from the ULP and is based on section 30.4.3 of the technical reference.

Code: Select all

static uint32_t read_temperature(void)
{
    uint32_t temp, ready;

    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP_FORCE);
    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);

    /* Wait for a while and then configure the register
     * SENS_TSENS_DUMP_OUT. The output value gradually approaches the
     * actual temperature linearly as the measurement time increases.
     */
    for (volatile int i = 0; i < 0xff; ++i)
	;

    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);

    ready = 0;
    while (!ready) {
	ready = REG_GET_FIELD(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_READY);
    }

    temp = REG_GET_FIELD(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_OUT);
    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);

    return temp;
}
The problem is that I don't know how to configure the temperature sensor on the ULP. The above code works ONCE if I have the following
in my application code.

Code: Select all

    temp_sensor_config_t config = {
	.dac_offset = TSENS_DAC_L2, // -10 to 80°C, error < 1°C
	.clk_div = 6};

    temp_sensor_set_config(config);
    temp_sensor_start();
Once the main processor goes into deep sleep, the FIRST call to read_temperature() is fine. I believe this works because the main
processor calls temp_sensor_set_config() before going into deep sleep.

However, subsequent calls to read_temperature() fail — SENS_TSENS_READY is never set. Again, I think these fail, because the temperature sensor is no longer configured when the ULP wakes up at the period set by ulp_set_wakeup_period().

Does anybody know how to configure the temperature sensor on the ULP? I don't see anything in the technical reference on this beyond section 30.4.3.

I looked into $IDF_PATH/components/driver/esp32s2/rtc_tempsensor.c, but if I try to call

Code: Select all

	REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SARADC_TSENS_DAC, 15);
in my ULP code, I get a linker error
main.c:(.text.startup.main+0x66): undefined reference to `i2c_rtc_write_reg_mask'
Thanks in advance for any help!