ESP32 RTC External Wakeup

来自Jack's Lab
跳转到: 导航, 搜索

目录

1 Overview

Quantum-7-1024.jpg



2 Quick Start

In Linux:

2.1 Install ESP-IDF

$ sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial
$ wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux32-1.22.0-59.tar.gz
$ mkdir -p toolchain
$ tar zxf xtensa-esp32-elf-linux32-1.22.0-59.tar.gz -C toolchain
$ export PATH=$PATH:`pwd`/toolchain/xtensa-esp32-elf/bin
$
$ git clone --recursive git://github.com/icamgo/esp-idf.git
$ export IDF_PATH=`pwd`/esp-idf



2.2 Compile

$ cd esp-idf/examples/20_ext_wakeup
$ make menuconfig
$ make flash -j2



2.3 Upload

$ make flash

You need to press the RST buttom after uploading the firmware into flash. If you guys do not like to do this please patch the /path/to/esp-idf/components/esptool_py/esptool/esptool.py :

diff --git a/esptool.py b/esptool.py
index 755f4cb..ff92c91 100755
--- a/esptool.py
+++ b/esptool.py
@@ -197,6 +197,12 @@ class ESPLoader(object):
               + '\xc0'
         self._port.write(buf)
 
+    def reset_to_app(self):
+        self._port.setDTR(False)
+        self._port.setRTS(True)
+        time.sleep(0.05)
+        self._port.setRTS(True)
+
     """ Calculate checksum of a blob, as it is defined by the ROM """
     @staticmethod
     def checksum(data, state=ESP_CHECKSUM_MAGIC):
@@ -1421,7 +1427,6 @@ def dump_mem(esp, args):
         sys.stdout.flush()
     print 'Done!'
 
-
 def write_flash(esp, args):
     """Write data to flash
     """
@@ -1503,6 +1508,7 @@ def write_flash(esp, args):
     if args.verify:
         print 'Verifying just-written flash...'
         verify_flash(esp, args, header_block)
+    esp.reset_to_app()
 
 
 def image_info(args):

Then Quantum can reset to run your app automatically after uploading the firmware into flash



2.4 Connections

Connect a Blue/Yellow LED from Quantum_D7_GPIO27 to GND:

  • LED_Anode <-----> Quantum_D7_GPIO27
  • LED_Cathode <----> Quantum_GND


The LED would flash two times when the board boot up and then enter deep sleep mode. Connecting the GPIO35 (RTC_IO5) to 3V3 when you guys need to wakeup the ESP32



3 API

From investigation of ESP32 RTC

#define DEEP_SLEEP_PD_NORMAL         BIT(0)   /* Base deep sleep mode */
#define DEEP_SLEEP_PD_RTC_PERIPH     BIT(1)   /* Power down RTC peripherals */
#define DEEP_SLEEP_PD_RTC_SLOW_MEM   BIT(2)   /* Power down RTC SLOW memory */
#define DEEP_SLEEP_PD_RTC_FAST_MEM   BIT(3)   /* Power down RTC FAST memory */

/*
 * @brief Prepare for entering sleep mode
 * @param deep_slp   DEEP_SLEEP_PD_ flags combined with OR (DEEP_SLEEP_PD_NORMAL must be included)
 * @param cpu_lp_mode  for deep sleep, should be 0
 */
void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode);

#define RTC_EXT_EVENT0_TRIG     BIT(0)
#define RTC_EXT_EVENT1_TRIG     BIT(1)
#define RTC_GPIO_TRIG           BIT(2)          /* Only available in light sleep */
#define RTC_TIMER_EXPIRE        BIT(3)
#define RTC_SDIO_TRIG           BIT(4)
#define RTC_MAC_TRIG            BIT(5)
#define RTC_UART0_TRIG          BIT(6)
#define RTC_UART1_TRIG          BIT(7)
#define RTC_TOUCH_TRIG          BIT(8)                                 
#define RTC_SAR_TRIG            BIT(9)                                 
#define RTC_BT_TRIG             BIT(10)                                

/*
 * @brief Enter sleep mode for given number of cycles
 * @param cycles_h  higher 32 bit part of number of slow clock cycles
 * @param cycles_l  lower 32 bit part of number of slow clock cycles
 * @param wakeup_opt  wake up reason to enable (RTC_xxx_TRIG flags combined with OR)
 * @param reject_opt  reserved, should be 0
 * @return TBD
 */
uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt);

typedef enum {
    RTC_GPIO0_SEL = BIT(0),
    RTC_GPIO1_SEL = BIT(1),
    RTC_GPIO2_SEL = BIT(2),
    RTC_GPIO3_SEL = BIT(3),
    RTC_GPIO4_SEL = BIT(4),
    RTC_GPIO5_SEL = BIT(5),
    RTC_GPIO6_SEL = BIT(6),
    RTC_GPIO7_SEL = BIT(7),
    RTC_GPIO8_SEL = BIT(8),
    RTC_GPIO9_SEL = BIT(9),
    RTC_GPIO10_SEL = BIT(10),
    RTC_GPIO11_SEL = BIT(11),
    RTC_GPIO12_SEL = BIT(12),
    RTC_GPIO13_SEL = BIT(13),
    RTC_GPIO14_SEL = BIT(14),
    RTC_GPIO15_SEL = BIT(15),
    RTC_GPIO16_SEL = BIT(16),
    RTC_GPIO17_SEL = BIT(17)
} rtc_gpio_sel_t;

void rtc_pads_muxsel(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_funsel(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_slpsel(rtc_gpio_sel_t rtc_io_sel, uint8_t set);

void rtc_pads_hold(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_pu(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_pd(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_slpie(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_slpoe(rtc_gpio_sel_t rtc_io_sel, uint8_t set);
void rtc_pads_funie(rtc_gpio_sel_t rtc_io_sel, uint8_t set);

/*
 * Using the EXT_WAKEUP0 slot. So you need to enable the RTC_EXT_EVENT0_TRIG
 * in rtc_sleep()
 *
 * rtc_io_num is the number of rtc_pad. e.g. The number of RTC_GPIO5 is 5
 * wakeup_level = 0: external wakeup at low level
 * wakeup_level = 1: external wakeup at high level
 */
void rtc_pad_ext_wakeup(rtc_gpio_sel_t rtc_io_sel, uint8_t rtc_io_num, uint8_t wakeup_level);



4 Code

4.1 Using EXT_WAKEUP0

void deep_sleep_ext_wakeup(uint8_t rtc_gpio_num)
{
    if (esp_get_deep_sleep_wake_stub() == NULL) {
        esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
    }

    rtc_pad_ext_wakeup(1 << rtc_gpio_num, rtc_gpio_num, 1);

    /* fixed bug of rtc_pad_slpie() for RTC_GPIO4 */
    //REG_SET_BIT(RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_SLP_IE);

    /* fixed bug of rtc_pad_slpie() for RTC_GPIO5 */
    REG_SET_BIT(RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_SLP_IE);

    rtc_slp_prep_lite(DEEP_SLEEP_PD_NORMAL, 0);

    rtc_sleep(0, 0, RTC_EXT_EVENT0_TRIG, 0);

    while (1) {
        ;
    }
}

#define BLINK_GPIO 27

void study_task(void *pvParameters)
{
    gpio_pad_select_gpio(BLINK_GPIO);
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

    while (1) {
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(1000 / portTICK_RATE_MS);
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(1000 / portTICK_RATE_MS);
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(1000 / portTICK_RATE_MS);
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(1000 / portTICK_RATE_MS);

        /* pull up the RTC_GPIO5 (GPIO35) to wakeup */
        deep_sleep_ext_wakeup(5);
    }
}

void app_main()
{
    printf("Welcome to Noduino Quantum\r\n");
    printf("Try to investigate the ULP/RTC of ESP32 ... \r\n");
    xTaskCreatePinnedToCore(&study_task, "study_task", 1024, NULL, 5, NULL, 0);
}


4.2 Using EXT_WAKEUP1

/* use the rtc_gpio5 (pull up) to wakeup */
void ext_wakeup_rtc_io5_setup()
{
    rtc_pads_muxsel(1<<5, 1);
    rtc_pads_funsel(1<<5, 0);
    rtc_pads_slpsel(1<<5, 1);

    REG_SET_BIT(RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_SLP_IE);

#if USE_EXT_WAKEUP0
    REG_SET_BIT(RTC_CNTL_EXT_WAKEUP_CONF_REG, RTC_CNTL_EXT_WAKEUP0_LV);
    REG_WRITE(RTC_IO_EXT_WAKEUP0_REG, 5<<RTC_IO_EXT_WAKEUP0_SEL_S);
#else
    REG_SET_BIT(RTC_CNTL_EXT_WAKEUP_CONF_REG, RTC_CNTL_EXT_WAKEUP1_LV);
    REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, 1<<5);
#endif
}

void deep_sleep_ext_wakeup(uint8_t rtc_gpio_num)
{
    if (esp_get_deep_sleep_wake_stub() == NULL) {
        esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
    }

    ext_wakeup_rtc_io5_setup();

    rtc_slp_prep_lite(DEEP_SLEEP_PD_NORMAL, 0);
    rtc_sleep(0, 0, RTC_EXT_EVENT1_TRIG, 0);

    while (1) {
        ;
    }
}



5 Reference

For more information please refer to





















个人工具
名字空间

变换
操作
导航
工具箱