ESP32-C3 get RTC time in wakeup stub
Posted: Sun Aug 14, 2022 1:15 pm
Good afternoon,
I am putting the ESP32-C3 to (deep) sleep for a preset period of time and monitoring a sensor while it sleeps. I only want to fully wake it up when the timer runs out and handle the sensor impulses in a wakeup stub (basically just wake up, increment a timer and go back to sleep).
What i got stuck on is trying to put together a wakeup stub that reads current RTC time, desired wakeup time from RTC_IRAM_ATTR memory, calculates necessary time to sleep and goes back to sleep.
I found a snippet for putting the MCU to sleep from wakeup stub for ESP32:
However this does not compile for ESP32-C3, i am getting lots of not declared in this scope errors. These are the relevant includes i am using:
Maybe i am looking at the wrong place but i am unable to find anything helpful in the ESP32-C3 docs.
Thank you for your help.
I am putting the ESP32-C3 to (deep) sleep for a preset period of time and monitoring a sensor while it sleeps. I only want to fully wake it up when the timer runs out and handle the sensor impulses in a wakeup stub (basically just wake up, increment a timer and go back to sleep).
What i got stuck on is trying to put together a wakeup stub that reads current RTC time, desired wakeup time from RTC_IRAM_ATTR memory, calculates necessary time to sleep and goes back to sleep.
I found a snippet for putting the MCU to sleep from wakeup stub for ESP32:
Code: Select all
RTC_IRAM_ATTR void deepsleep_for_us(uint64_t duration_us) {
// Feed watchdog
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
// Get RTC calibration
uint32_t period = REG_READ(RTC_SLOW_CLK_CAL_REG);
// Calculate sleep duration in microseconds
int64_t sleep_duration = (int64_t)duration_us - (int64_t)DEEP_SLEEP_TIME_OVERHEAD_US;
if (sleep_duration < 0) {
sleep_duration = 0;
}
// Convert microseconds to RTC clock cycles
int64_t rtc_count_delta = (sleep_duration << RTC_CLK_CAL_FRACT) / period;
// Feed watchdog
REG_WRITE(TIMG_WDTFEED_REG(0), 1);
// Get current RTC time
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
ets_delay_us(1);
}
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
uint64_t now = READ_PERI_REG(RTC_CNTL_TIME0_REG);
now |= ((uint64_t)READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
// Set wakeup time
uint64_t future = now + rtc_count_delta;
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, future & UINT32_MAX);
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, future >> 32);
// Start RTC deepsleep timer
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, RTC_TIMER_TRIG_EN); // Wake up on timer
// WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, 0); // Clear sleep rejection cause
// Go to sleep
CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
}
Code: Select all
#include "hal/wdt_hal.h"
#include "esp_task_wdt.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "esp_attr.h"
#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/reset_reasons.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/timer_group_struct.h"
#include "soc/uart_reg.h"
#include "soc/soc_ulp.h"
#include "rom/ets_sys.h"
#include "rom/rtc.h"
#include <stdio.h>
#include <string.h>
Thank you for your help.