RTC GPIO hold enable from wake stub
Posted: Tue Apr 30, 2019 8:42 pm
Hi,
I'm having an issue with my wake stub.
My wakestub basically checks a few conditions on GPIO and ADC, and then puts the chip back to sleep if none of the conditions are met. Because of the RTC IRAM limitation of the wake stub, I basically took all of the IDF code relevant to me, and put it in a new file, called stub_sdk.c with some butchering to make things simple/work. This contains the idf functions to manipulate peripherals, but with the RTC_IRAM attrib so that they are loaded into IRAM and can be used in the wake stub. My first question is, is there a better way to do this? At least, maybe this will help someone who also wants to use these high level functions to configure their ESP32 peripherals.
I'm having an issue trying to set and hold an RTC io. It doesn't seem like the IO is getting held out of the wake stub. The IDF functions use some external macros/defines, some of which I have dragged to RTC ram to make them available to my "mini RTC IRAM idf". I'm wondering if there is anything in this file I have not caught which must be dragged to RTC IRAM?
This should keep the IO held after the chip goies back into deep sleep, correct?
This is stub_sdk.c file:
I'm having an issue with my wake stub.
My wakestub basically checks a few conditions on GPIO and ADC, and then puts the chip back to sleep if none of the conditions are met. Because of the RTC IRAM limitation of the wake stub, I basically took all of the IDF code relevant to me, and put it in a new file, called stub_sdk.c with some butchering to make things simple/work. This contains the idf functions to manipulate peripherals, but with the RTC_IRAM attrib so that they are loaded into IRAM and can be used in the wake stub. My first question is, is there a better way to do this? At least, maybe this will help someone who also wants to use these high level functions to configure their ESP32 peripherals.
I'm having an issue trying to set and hold an RTC io. It doesn't seem like the IO is getting held out of the wake stub. The IDF functions use some external macros/defines, some of which I have dragged to RTC ram to make them available to my "mini RTC IRAM idf". I'm wondering if there is anything in this file I have not caught which must be dragged to RTC IRAM?
This should keep the IO held after the chip goies back into deep sleep, correct?
Code: Select all
stub_rtc_gpio_hold_dis(GPIO_NUM_32);
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = ((uint64_t)1 << GPIO_NUM_32);
io_conf.pull_down_en = 1;
io_conf.pull_up_en = 0;
stub_gpio_config(&io_conf);
stub_gpio_set_level(GPIO_NUM_32, true);
stub_rtc_gpio_hold_en(GPIO_NUM_32);
Code: Select all
#include "soc/rtc.h"
#include "soc/rtc_gpio_channel.h"
#include "soc/rtc_periph.h"
#include "esp_sleep.h"
#include "PowerDefs.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/uart_reg.h"
#include "soc/timer_group_reg.h"
#include "esp_sleep.h"
#include "esp_attr.h"
#include "esp32/rom/rtc.h"
#include "esp32/rom/gpio.h"
#include "esp32/rom/ets_sys.h"
#include "soc/gpio_periph.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "driver/adc.h"
#include "StubSdk.h"
#include "soc/rtc_periph.h"
const RTC_DATA_ATTR uint32_t STUB_GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
IO_MUX_GPIO0_REG,
IO_MUX_GPIO1_REG,
IO_MUX_GPIO2_REG,
IO_MUX_GPIO3_REG,
IO_MUX_GPIO4_REG,
IO_MUX_GPIO5_REG,
IO_MUX_GPIO6_REG,
IO_MUX_GPIO7_REG,
IO_MUX_GPIO8_REG,
IO_MUX_GPIO9_REG,
IO_MUX_GPIO10_REG,
IO_MUX_GPIO11_REG,
IO_MUX_GPIO12_REG,
IO_MUX_GPIO13_REG,
IO_MUX_GPIO14_REG,
IO_MUX_GPIO15_REG,
IO_MUX_GPIO16_REG,
IO_MUX_GPIO17_REG,
IO_MUX_GPIO18_REG,
IO_MUX_GPIO19_REG,
0,
IO_MUX_GPIO21_REG,
IO_MUX_GPIO22_REG,
IO_MUX_GPIO23_REG,
0,
IO_MUX_GPIO25_REG,
IO_MUX_GPIO26_REG,
IO_MUX_GPIO27_REG,
0,
0,
0,
0,
IO_MUX_GPIO32_REG,
IO_MUX_GPIO33_REG,
IO_MUX_GPIO34_REG,
IO_MUX_GPIO35_REG,
IO_MUX_GPIO36_REG,
IO_MUX_GPIO37_REG,
IO_MUX_GPIO38_REG,
IO_MUX_GPIO39_REG,
};
//Reg,Mux,Fun,IE,Up,Down,Rtc_number
const RTC_DATA_ATTR rtc_gpio_desc_t __rtc_gpio_desc[GPIO_PIN_COUNT] = {
{RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, RTC_IO_TOUCH_PAD1_HOLD_M, RTC_CNTL_TOUCH_PAD1_HOLD_FORCE_M, RTC_IO_TOUCH_PAD1_DRV_V, RTC_IO_TOUCH_PAD1_DRV_S, RTCIO_GPIO0_CHANNEL}, //0
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //1
{RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, RTC_IO_TOUCH_PAD2_SLP_SEL_M, RTC_IO_TOUCH_PAD2_SLP_IE_M, RTC_IO_TOUCH_PAD2_HOLD_M, RTC_CNTL_TOUCH_PAD2_HOLD_FORCE_M, RTC_IO_TOUCH_PAD2_DRV_V, RTC_IO_TOUCH_PAD2_DRV_S, RTCIO_GPIO2_CHANNEL}, //2
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //3
{RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, RTC_IO_TOUCH_PAD0_SLP_SEL_M, RTC_IO_TOUCH_PAD0_SLP_IE_M, RTC_IO_TOUCH_PAD0_HOLD_M, RTC_CNTL_TOUCH_PAD0_HOLD_FORCE_M, RTC_IO_TOUCH_PAD0_DRV_V, RTC_IO_TOUCH_PAD0_DRV_S, RTCIO_GPIO4_CHANNEL}, //4
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //5
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //6
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //7
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //8
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //9
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //10
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //11
{RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, RTC_IO_TOUCH_PAD5_SLP_SEL_M, RTC_IO_TOUCH_PAD5_SLP_IE_M, RTC_IO_TOUCH_PAD5_HOLD_M, RTC_CNTL_TOUCH_PAD5_HOLD_FORCE_M, RTC_IO_TOUCH_PAD5_DRV_V, RTC_IO_TOUCH_PAD5_DRV_S, RTCIO_GPIO12_CHANNEL}, //12
{RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, RTC_IO_TOUCH_PAD4_SLP_SEL_M, RTC_IO_TOUCH_PAD4_SLP_IE_M, RTC_IO_TOUCH_PAD4_HOLD_M, RTC_CNTL_TOUCH_PAD4_HOLD_FORCE_M, RTC_IO_TOUCH_PAD4_DRV_V, RTC_IO_TOUCH_PAD4_DRV_S, RTCIO_GPIO13_CHANNEL}, //13
{RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, RTC_IO_TOUCH_PAD6_SLP_SEL_M, RTC_IO_TOUCH_PAD6_SLP_IE_M, RTC_IO_TOUCH_PAD6_HOLD_M, RTC_CNTL_TOUCH_PAD6_HOLD_FORCE_M, RTC_IO_TOUCH_PAD6_DRV_V, RTC_IO_TOUCH_PAD6_DRV_S, RTCIO_GPIO14_CHANNEL}, //14
{RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, RTC_IO_TOUCH_PAD3_SLP_SEL_M, RTC_IO_TOUCH_PAD3_SLP_IE_M, RTC_IO_TOUCH_PAD3_HOLD_M, RTC_CNTL_TOUCH_PAD3_HOLD_FORCE_M, RTC_IO_TOUCH_PAD3_DRV_V, RTC_IO_TOUCH_PAD3_DRV_S, RTCIO_GPIO15_CHANNEL}, //15
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //16
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //17
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //18
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //19
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //20
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //21
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //22
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //23
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //24
{RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, RTC_IO_PDAC1_SLP_SEL_M, RTC_IO_PDAC1_SLP_IE_M, RTC_IO_PDAC1_HOLD_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, RTC_IO_PDAC1_DRV_V, RTC_IO_PDAC1_DRV_S, RTCIO_GPIO25_CHANNEL}, //25
{RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, RTC_IO_PDAC2_SLP_SEL_M, RTC_IO_PDAC2_SLP_IE_M, RTC_IO_PDAC2_HOLD_M, RTC_CNTL_PDAC2_HOLD_FORCE_M, RTC_IO_PDAC2_DRV_V, RTC_IO_PDAC2_DRV_S, RTCIO_GPIO26_CHANNEL}, //26
{RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, RTC_IO_TOUCH_PAD7_SLP_SEL_M, RTC_IO_TOUCH_PAD7_SLP_IE_M, RTC_IO_TOUCH_PAD7_HOLD_M, RTC_CNTL_TOUCH_PAD7_HOLD_FORCE_M, RTC_IO_TOUCH_PAD7_DRV_V, RTC_IO_TOUCH_PAD7_DRV_S, RTCIO_GPIO27_CHANNEL}, //27
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //28
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //29
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //30
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //31
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, RTC_IO_X32P_SLP_SEL_M, RTC_IO_X32P_SLP_IE_M, RTC_IO_X32P_HOLD_M, RTC_CNTL_X32P_HOLD_FORCE_M, RTC_IO_X32P_DRV_V, RTC_IO_X32P_DRV_S, RTCIO_GPIO32_CHANNEL}, //32
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, RTC_IO_X32N_SLP_SEL_M, RTC_IO_X32N_SLP_IE_M, RTC_IO_X32N_HOLD_M, RTC_CNTL_X32N_HOLD_FORCE_M, RTC_IO_X32N_DRV_V, RTC_IO_X32N_DRV_S, RTCIO_GPIO33_CHANNEL}, //33
{RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, RTC_IO_ADC1_SLP_SEL_M, RTC_IO_ADC1_SLP_IE_M, RTC_IO_ADC1_HOLD_M, RTC_CNTL_ADC1_HOLD_FORCE_M, 0, 0, RTCIO_GPIO34_CHANNEL}, //34
{RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, RTC_IO_ADC2_SLP_SEL_M, RTC_IO_ADC2_SLP_IE_M, RTC_IO_ADC2_HOLD_M, RTC_CNTL_ADC2_HOLD_FORCE_M, 0, 0, RTCIO_GPIO35_CHANNEL}, //35
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, RTC_IO_SENSE1_SLP_SEL_M, RTC_IO_SENSE1_SLP_IE_M, RTC_IO_SENSE1_HOLD_M, RTC_CNTL_SENSE1_HOLD_FORCE_M, 0, 0, RTCIO_GPIO36_CHANNEL}, //36
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, RTC_IO_SENSE2_SLP_SEL_M, RTC_IO_SENSE2_SLP_IE_M, RTC_IO_SENSE2_HOLD_M, RTC_CNTL_SENSE2_HOLD_FORCE_M, 0, 0, RTCIO_GPIO37_CHANNEL}, //37
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, RTC_IO_SENSE3_SLP_SEL_M, RTC_IO_SENSE3_SLP_IE_M, RTC_IO_SENSE3_HOLD_M, RTC_CNTL_SENSE3_HOLD_FORCE_M, 0, 0, RTCIO_GPIO38_CHANNEL}, //38
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, RTC_IO_SENSE4_SLP_SEL_M, RTC_IO_SENSE4_SLP_IE_M, RTC_IO_SENSE4_HOLD_M, RTC_CNTL_SENSE4_HOLD_FORCE_M, 0, 0, RTCIO_GPIO39_CHANNEL}, //39
};
static RTC_IRAM_ATTR bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num);
static RTC_IRAM_ATTR bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
{
return gpio_num < GPIO_PIN_COUNT
&& rtc_gpio_desc[gpio_num].reg != 0;
}
#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid_gpio(gpio_num) // Deprecated, use rtc_gpio_is_valid_gpio()
RTC_IRAM_ATTR void stub_rtc_gpio_deinit(gpio_num_t gpio_num)
{
//Select Gpio as Digital Gpio
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L240
RTC_IRAM_ATTR void stub_gpio_config(const gpio_config_t *pGPIOConfig)
{
uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask);
uint32_t io_reg = 0;
uint32_t io_num = 0;
do {
io_reg = STUB_GPIO_PIN_MUX_REG[io_num];
if (((gpio_pin_mask >> io_num) & BIT(0))) {
if(RTC_GPIO_IS_VALID_GPIO(io_num)){
stub_rtc_gpio_deinit(io_num);
}
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
PIN_INPUT_ENABLE(STUB_GPIO_PIN_MUX_REG[io_num]);
} else {
PIN_INPUT_DISABLE(STUB_GPIO_PIN_MUX_REG[io_num]);
}
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */
} else {
GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */
}
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
//gpio_output_enable(io_num);
stub_gpio_output_enable(io_num);
} else {
//gpio_output_disable(io_num);
stub_gpio_output_disable(io_num);
}
if (pGPIOConfig->pull_up_en) {
stub_gpio_pullup_en(io_num);
} else {
stub_gpio_pullup_dis(io_num);
}
if (pGPIOConfig->pull_down_en) {
stub_gpio_pulldown_en(io_num);
} else {
stub_gpio_pulldown_dis(io_num);
}
PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */
}
io_num++;
} while (io_num < GPIO_PIN_COUNT);
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L75
RTC_IRAM_ATTR void stub_gpio_pulldown_dis(gpio_num_t gpio_num)
{
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
stub_rtc_gpio_pulldown_dis(gpio_num);
} else {
REG_CLR_BIT(STUB_GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
}
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L323
RTC_IRAM_ATTR void stub_rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown);
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L64
RTC_IRAM_ATTR void stub_gpio_pulldown_en(gpio_num_t gpio_num)
{
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
stub_rtc_gpio_pulldown_en(gpio_num);
} else {
REG_SET_BIT(STUB_GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
}
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L293
RTC_IRAM_ATTR void stub_rtc_gpio_pulldown_en(gpio_num_t gpio_num)
{
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown);
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L53
RTC_IRAM_ATTR void stub_gpio_pullup_dis(gpio_num_t gpio_num)
{
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
stub_rtc_gpio_pullup_dis(gpio_num);
} else {
REG_CLR_BIT(STUB_GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
}
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L308
RTC_IRAM_ATTR void stub_rtc_gpio_pullup_dis(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup);
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L42
RTC_IRAM_ATTR void stub_gpio_pullup_en(gpio_num_t gpio_num)
{
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
stub_rtc_gpio_pullup_en(gpio_num);
} else {
REG_SET_BIT(STUB_GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
}
}
// https://github.com/espressif/esp-idf/blob/e7f85f1987aa9479c2dbab638ca83bcaef99be00/components/driver/gpio.c#L128
RTC_IRAM_ATTR void stub_gpio_output_disable(gpio_num_t gpio_num)
{
if (gpio_num < 32) {
GPIO.enable_w1tc = (0x1 << gpio_num);
} else {
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
}
// Ensure no other output signal is routed via GPIO matrix to this pin
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), SIG_GPIO_OUT_IDX);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1805
RTC_IRAM_ATTR void stub_dac1_output_enable()
{
stub_rtc_gpio_init(GPIO_NUM_25);
stub_rtc_gpio_output_disable(GPIO_NUM_25);
stub_rtc_gpio_input_disable(GPIO_NUM_25);
// Float the GPIO
CLEAR_PERI_REG_MASK(rtc_gpio_desc[GPIO_NUM_25].reg, rtc_gpio_desc[GPIO_NUM_25].pulldown);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[GPIO_NUM_25].reg, rtc_gpio_desc[GPIO_NUM_25].pullup);
RTCIO.pad_dac[DAC_CHANNEL_1].dac_xpd_force = true;
RTCIO.pad_dac[DAC_CHANNEL_1].xpd_dac = true;
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1826
RTC_IRAM_ATTR void stub_dac1_output_voltage(uint8_t dac_value)
{
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, dac_value, RTC_IO_PDAC1_DAC_S); //dac_output
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1469
RTC_IRAM_ATTR void stub_adc1_config_width()
{
SENS.sar_start_force.sar1_bit_width = ADC_WIDTH_BIT_12;
SENS.sar_read_ctrl.sar1_sample_bit = ADC_WIDTH_BIT_12;
SENS.sar_read_ctrl.sar1_data_inv = true;
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L140
RTC_IRAM_ATTR void stub_rtc_gpio_init(gpio_num_t gpio_num)
{
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
//0:RTC FUNCIOTN 1,2,3:Reserved
SET_PERI_REG_BITS(rtc_gpio_desc[gpio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0x0, rtc_gpio_desc[gpio_num].func);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L174
RTC_IRAM_ATTR void stub_rtc_gpio_output_disable(gpio_num_t gpio_num)
{
int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TS_S)));
SET_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TC_REG, (1 << ( rtc_gpio_num + RTC_GPIO_ENABLE_W1TC_S)));
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L194
RTC_IRAM_ATTR void stub_rtc_gpio_input_disable(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1125
RTC_IRAM_ATTR void stub_adc_set_atten(adc_unit_t adc_unit, adc_channel_t channel, adc_atten_t atten)
{
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, SENS_SAR1_ATTEN_VAL_MASK, atten, (channel * 2));
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1460
RTC_IRAM_ATTR void stub_adc1_config_channel_atten(adc1_channel_t channel, gpio_num_t gpio_num, adc_atten_t atten)
{
stub_rtc_gpio_init(gpio_num);
stub_rtc_gpio_output_disable(gpio_num);
stub_rtc_gpio_input_disable(gpio_num);
// Float the GPIO
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup);
stub_adc_set_atten(ADC_UNIT_1, channel, atten);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1318
RTC_IRAM_ATTR int stub_adc_convert(const int channel)
{
SENS.sar_meas_start1.sar1_en_pad = (1 << channel); //only one channel is selected.
while (SENS.sar_slave_addr1.meas_status != 0);
SENS.sar_meas_start1.meas1_start_sar = 0;
SENS.sar_meas_start1.meas1_start_sar = 1;
while (SENS.sar_meas_start1.meas1_done_sar == 0);
return SENS.sar_meas_start1.meas1_data_sar;
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c#L1531
RTC_IRAM_ATTR int stub_adc1_get_raw(adc1_channel_t channel)
{
SENS.sar_read_ctrl.sar1_dig_force = 0;
//channel is set in the convert function
SENS.sar_meas_wait2.force_xpd_amp = SENS_FORCE_XPD_AMP_PD;
//disable FSM, it's only used by the LNA.
SENS.sar_meas_ctrl.amp_rst_fb_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0;
SENS.sar_meas_wait1.sar_amp_wait1 = 1;
SENS.sar_meas_wait1.sar_amp_wait2 = 1;
SENS.sar_meas_wait2.sar_amp_wait3 = 1;
//set controller
SENS.sar_read_ctrl.sar1_dig_force = false; //RTC controller controls the ADC, not digital controller
SENS.sar_meas_start1.meas1_start_force = true; //RTC controller controls the ADC,not ulp coprocessor
SENS.sar_meas_start1.sar1_en_pad_force = true; //RTC controller controls the data port, not ulp coprocessor
SENS.sar_touch_ctrl1.xpd_hall_force = true; // RTC controller controls the hall sensor power,not ulp coprocessor
SENS.sar_touch_ctrl1.hall_phase_force = true; // RTC controller controls the hall sensor phase,not ulp coprocessor
//start conversion
return stub_adc_convert(channel);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c
RTC_IRAM_ATTR void stub_rtc_gpio_hold_en(gpio_num_t gpio_num)
{
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].hold);
}
RTC_IRAM_ATTR void stub_gpio_output_enable(gpio_num_t gpio_num)
{
if (gpio_num < 32) {
GPIO.enable_w1ts = (0x1 << gpio_num);
} else {
GPIO.enable1_w1ts.data = ((uint64_t)0x1 << (gpio_num - 32));
}
gpio_matrix_out(gpio_num, SIG_GPIO_OUT_IDX, false, false);
}
RTC_IRAM_ATTR void stub_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
if (level) {
if (gpio_num < 32) {
GPIO.out_w1ts = (1 << gpio_num);
} else {
GPIO.out1_w1ts.data = ((uint64_t)1 << (gpio_num - 32));
}
} else {
if (gpio_num < 32) {
GPIO.out_w1tc = (1 << gpio_num);
} else {
GPIO.out1_w1tc.data = ((uint64_t)1 << (gpio_num - 32));
}
}
}
// https://github.com/espressif/esp-idf/blob/a20d02b7f196c407bc9f39b781e31a0a4f665968/components/esp32/sleep_modes.c
RTC_IRAM_ATTR void stub_ext0_wakeup_prepare(const uint32_t gpio, const int level)
{
// Set GPIO to be used for wakeup
REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, gpio);
// Set level which will trigger wakeup
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, level, RTC_CNTL_EXT_WAKEUP0_LV_S);
// Find GPIO descriptor in the rtc_gpio_desc table and configure the pad
for (size_t gpio_num = 0; gpio_num < GPIO_PIN_COUNT; ++gpio_num) {
const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio_num];
if (desc->rtc_num == gpio) {
REG_SET_BIT(desc->reg, desc->mux);
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func);
REG_SET_BIT(desc->reg, desc->ie);
break;
}
}
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c
RTC_IRAM_ATTR void stub_rtc_gpio_pullup_en(gpio_num_t gpio_num)
{
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup);
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/driver/rtc_module.c
RTC_IRAM_ATTR void stub_rtc_gpio_hold_dis(gpio_num_t gpio_num)
{
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].hold);
}
// https://github.com/espressif/esp-idf/blob/a20d02b7f196c407bc9f39b781e31a0a4f665968/components/esp32/sleep_modes.c
RTC_IRAM_ATTR void stub_ext1_wakeup_prepare(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)
{
uint32_t rtc_gpio_mask = 0;
// Translate bit map of GPIO numbers into the bit map of RTC IO numbers
for (int gpio = 0; mask; ++gpio, mask >>= 1) {
rtc_gpio_mask |= BIT(rtc_gpio_desc[gpio].rtc_num);
}
// Configure all RTC IOs selected as ext1 wakeup inputs
for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) {
int rtc_pin = rtc_gpio_desc[gpio].rtc_num;
if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) {
continue;
}
const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio];
// Route pad to RTC
REG_SET_BIT(desc->reg, desc->mux);
SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func);
// set input enable in sleep mode
REG_SET_BIT(desc->reg, desc->ie);
// Pad configuration depends on RTC_PERIPH state in sleep mode
/*if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
// RTC_PERIPH will be powered down, so RTC_IO_ registers will
// loose their state. Lock pad configuration.
// Pullups/pulldowns also need to be disabled.
REG_CLR_BIT(desc->reg, desc->pulldown);
REG_CLR_BIT(desc->reg, desc->pullup);
REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force);
}*/
REG_CLR_BIT(desc->reg, desc->pulldown);
REG_CLR_BIT(desc->reg, desc->pullup);
REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force);
// Keep track of pins which are processed to bail out early
rtc_gpio_mask &= ~BIT(rtc_pin);
}
// Clear state from previous wakeup
REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
// Set pins to be used for wakeup
REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, rtc_gpio_mask);
// Set logic function (any low, all high)
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
}
// https://github.com/espressif/esp-idf/blob/a20d02b7f196c407bc9f39b781e31a0a4f665968/components/esp32/sleep_modes.c
RTC_IRAM_ATTR esp_sleep_wakeup_cause_t stub_esp_sleep_get_wakeup_cause()
{
uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
if (wakeup_cause & RTC_EXT0_TRIG_EN) {
return ESP_SLEEP_WAKEUP_EXT0;
} else if (wakeup_cause & RTC_EXT1_TRIG_EN) {
return ESP_SLEEP_WAKEUP_EXT1;
} else if (wakeup_cause & RTC_TIMER_TRIG_EN) {
return ESP_SLEEP_WAKEUP_TIMER;
} else if (wakeup_cause & RTC_TOUCH_TRIG_EN) {
return ESP_SLEEP_WAKEUP_TOUCHPAD;
} else if (wakeup_cause & RTC_ULP_TRIG_EN) {
return ESP_SLEEP_WAKEUP_ULP;
} else {
return ESP_SLEEP_WAKEUP_UNDEFINED;
}
}
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/soc/esp32/rtc_time.c
RTC_IRAM_ATTR uint64_t stub_rtc_time_get()
{
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); // might take 1 RTC slowclk period, don't flood RTC bus
}
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
return t;
}
RTC_IRAM_ATTR void stub_rtc_sleep_set_wakeup_time(uint64_t t)
{
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
}
// https://github.com/espressif/esp-idf/blob/a20d02b7f196c407bc9f39b781e31a0a4f665968/components/esp32/sleep_modes.c
RTC_IRAM_ATTR void stub_timer_wakeup_prepare(const uint64_t sleep_duration)
{
// https://github.com/espressif/esp-idf/blob/3bb7dba9957ee71a236058322ae5e70f96f9a104/components/newlib/time.c
uint32_t period = REG_READ(RTC_SLOW_CLK_CAL_REG);
// https://github.com/espressif/esp-idf/blob/9f3b550ff4df63d0787f5ae6499eb97e13b954b9/components/soc/esp32/rtc_time.c
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
int64_t rtc_count_delta = (sleep_duration << RTC_CLK_CAL_FRACT) / period;
stub_rtc_sleep_set_wakeup_time(stub_rtc_time_get() + rtc_count_delta);
}