RTC XTAL 32k not working/broken after SW_Reset OR Deepsleep
Posted: Tue Jan 08, 2019 3:19 am
Hello, I require an external crystal for the RTC because I need accurate deepsleep times over several hours. I have started a project on the esp-idf using Platform.IO, please excuse the poor project layout if it is not esp-idf standard.
What I've done:
1. I have modified the sdkconfig to use the external 32k oscillator for RTC instead of the internal 150k oscillator.
2. I have added some basic calibration code taken from the RTC test file on Github to verify it is oscillating.
3. Added software reset and deepsleep to ensure the crystal still works after a reset.
Expected Behavior:
1. The RTC XTAL is still running after deepsleep or software reset (I expect the RTC crystal to run always)
Observed behavior:
1. The RTC XTAL is not running. Logs give error.
Code used:
app_main.cpp
Xtal_RTC.c
Program expected behavior:
1. After reset the ESP32 should start, and calibrate the slow clock, showing 32k oscillations.
2. After 3 seconds, it will enter deepsleep for 3 seconds.
3. After wake from deepsleep, it will calibrate the slow clock, showing 32k oscillations.
4. After 3 seconds it will software reset, and repeat from 1.
Observed:
1. The program correctly alternates between deepsleep and software reset.
2. The oscillator doesn't work after a soft reset
3. The oscillator seems to work after a hard reset (Reset button on board)
ESP32 UART Output:
sdkconfig.h diff
Please let me know if I can provide more information.
Kind regards, Josh.
Edit 1
I should add that yes I do have loading capacitors on my crystal, the crystal is also 32000Hz instead of 32768Hz, I will have the correct part shortly but for now I don't see any issue using a badly clocked crystal since I only want to ensure its always running, the frequency is irrelevant at this point.
What I've done:
1. I have modified the sdkconfig to use the external 32k oscillator for RTC instead of the internal 150k oscillator.
2. I have added some basic calibration code taken from the RTC test file on Github to verify it is oscillating.
3. Added software reset and deepsleep to ensure the crystal still works after a reset.
Expected Behavior:
1. The RTC XTAL is still running after deepsleep or software reset (I expect the RTC crystal to run always)
Observed behavior:
1. The RTC XTAL is not running. Logs give error.
Code used:
app_main.cpp
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_system.h"
- #include "rom/rtc.h"
- // Include private libraries.
- #include <Xtal_RTC.h>
- #define CPU_PRO 0
- #define CPU_APP 1
- RESET_REASON reset_reason;
- void app_restart(void* context) {
- printf("(app_restart) waiting 5 seconds...\n");
- vTaskDelay(5000 / portTICK_RATE_MS);
- if (reset_reason == DEEPSLEEP_RESET) {
- printf("(app_restart) immediate restart...\n");
- esp_restart();
- } else {
- printf("(app_restart) deepsleep for 3 seconds...\n");
- esp_sleep_enable_timer_wakeup(1000L * 3000L); // 3 seconds
- esp_deep_sleep_start();
- }
- }
- extern "C" void app_main(void) {
- reset_reason = rtc_get_reset_reason(CPU_PRO);
- printf("(app_main) Reset Reason: %u\n", (uint32_t)reset_reason);
- calibrate_slow_clk();
- printf("(app_main) Initialized.\n");
- uint32_t random = esp_random();
- printf("(app_main) Random Gen: %u\n", random);
- xTaskCreate( app_restart, "app_restart", 2048, 0, 9, NULL );
- }
- #include <stdio.h>
- #include "rom/ets_sys.h"
- #include "rom/uart.h"
- #include "soc/rtc.h"
- #include "soc/rtc_cntl_reg.h"
- #include "soc/rtc_io_reg.h"
- #include "soc/sens_reg.h"
- #include "soc/io_mux_reg.h"
- #include "driver/rtc_io.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/semphr.h"
- #include "../esp_clk_internal.h"
- #include "esp_clk.h"
- #include <Xtal_RTC.h>
- #define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
- static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char* name)
- {
- const uint32_t cal_count = 1000;
- const float factor = (1 << 19) * 1000.0f;
- uint32_t cali_val;
- printf("%s:\n", name);
- for (int i = 0; i < 5; ++i) {
- printf("calibrate (%d): ", i);
- cali_val = rtc_clk_cal(cal_clk, cal_count);
- printf("%.3f kHz\n", factor / (float) cali_val);
- }
- return cali_val;
- }
- static void pull_out_clk(int sel)
- {
- REG_SET_BIT(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M);
- REG_CLR_BIT(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RDE_M | RTC_IO_PDAC1_RUE_M);
- REG_SET_FIELD(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_FUN_SEL, 1);
- REG_SET_FIELD(SENS_SAR_DAC_CTRL1_REG, SENS_DEBUG_BIT_SEL, 0);
- REG_SET_FIELD(RTC_IO_RTC_DEBUG_SEL_REG, RTC_IO_DEBUG_SEL0, sel);
- }
- void calibrate_slow_clk(void) {
- rtc_clk_32k_enable(true);
- uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
- if (cal_32k == 0) {
- printf("32K XTAL OSC has not started up\n");
- } else {
- printf("switching to RTC_SLOW_FREQ_32K_XTAL: ");
- rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
- printf("done\n");
- CALIBRATE_ONE(RTC_CAL_RTC_MUX);
- }
- CALIBRATE_ONE(RTC_CAL_32K_XTAL);
- pull_out_clk(RTC_IO_DEBUG_SEL0_32K_XTAL);
- }
1. After reset the ESP32 should start, and calibrate the slow clock, showing 32k oscillations.
2. After 3 seconds, it will enter deepsleep for 3 seconds.
3. After wake from deepsleep, it will calibrate the slow clock, showing 32k oscillations.
4. After 3 seconds it will software reset, and repeat from 1.
Observed:
1. The program correctly alternates between deepsleep and software reset.
2. The oscillator doesn't work after a soft reset
3. The oscillator seems to work after a hard reset (Reset button on board)
ESP32 UART Output:
- rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
- flash read err, 1000
- ets_main.c 371
- ets Jun 8 2016 00:22:57
- rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
- configsip: 0, SPIWP:0xee
- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
- mode:DIO, clock div:2
- load:0x3fff0018,len:4
- load:0x3fff001c,len:4960
- ho 0 tail 12 room 4
- load:0x40078000,len:7768
- ho 0 tail 12 room 4
- load:0x40080000,len:6084
- entry 0x40080324
- I (32) boot: ESP-IDF 3.30101.0 2nd stage bootloader
- I (32) boot: compile time 12:59:10
- I (32) boot: Enabling RNG early entropy source...
- I (34) boot: SPI Speed : 40MHz
- I (37) boot: SPI Mode : DIO
- I (40) boot: SPI Flash Size : 4MB
- I (43) boot: Partition Table:
- I (46) boot: ## Label Usage Type ST Offset Length
- I (52) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (59) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (65) boot: 2 factory factory app 00 00 00010000 00100000
- I (72) boot: End of partition table
- I (75) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x05448 ( 21576) map
- I (91) esp_image: segment 1: paddr=0x00015470 vaddr=0x3ffc0000 size=0x01fe0 ( 8160) load
- I (94) esp_image: segment 2: paddr=0x00017458 vaddr=0x3ffc1fe0 size=0x00000 ( 0) load
- I (99) esp_image: segment 3: paddr=0x00017460 vaddr=0x40080000 size=0x00400 ( 1024) load
- I (107) esp_image: segment 4: paddr=0x00017868 vaddr=0x40080400 size=0x08510 ( 34064) load
- I (128) esp_image: segment 5: paddr=0x0001fd80 vaddr=0x400c0000 size=0x00064 ( 100) load
- I (129) esp_image: segment 6: paddr=0x0001fdec vaddr=0x50000000 size=0x00000 ( 0) load
- I (133) esp_image: segment 7: paddr=0x0001fdf4 vaddr=0x00000000 size=0x0021c ( 540)
- I (141) esp_image: segment 8: paddr=0x00020018 vaddr=0x400d0018 size=0x10c20 ( 68640) map
- I (178) boot: Loaded app from partition at offset 0x10000
- I (178) boot: Disabling RNG early entropy source...
- I (178) cpu_start: Pro cpu up.
- I (179) cpu_start: Starting app cpu, entry point is 0x40080f8c
- I (0) cpu_start: App cpu up.
- I (188) heap_init: Initializing. RAM available for dynamic allocation:
- I (194) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
- I (199) heap_init: At 3FFC3040 len 0001CFC0 (115 KiB): DRAM
- I (204) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
- I (210) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
- I (215) heap_init: At 40088910 len 000176F0 (93 KiB): IRAM
- I (220) cpu_start: Pro cpu start user code
- I (79) cpu_start: Starting scheduler on PRO CPU.
- I (0) cpu_start: Starting scheduler on APP CPU.
- (app_main) Reset Reason: 16
- RTC_CAL_32K_XTAL:
- calibrate (0): 31.998 kHz
- calibrate (1): 31.999 kHz
- calibrate (2): 31.998 kHz
- calibrate (3): 31.999 kHz
- calibrate (4): 31.998 kHz
- switching to RTC_SLOW_FREQ_32K_XTAL: done
- RTC_CAL_RTC_MUX:
- calibrate (0): 31.999 kHz
- calibrate (1): 31.998 kHz
- calibrate (2): 31.998 kHz
- calibrate (3): 31.999 kHz
- calibrate (4): 31.998 kHz
- RTC_CAL_32K_XTAL:
- calibrate (0): 31.999 kHz
- calibrate (1): 31.998 kHz
- calibrate (2): 31.999 kHz
- calibrate (3): 31.998 kHz
- calibrate (4): 31.998 kHz
- (app_main) Initialized.
- (app_main) Random Gen: 2955304622
- (app_restart) waiting 5 seconds...
- (app_restart) deepsleep for 3 seconds...
- ets Jun 8 2016 00:22:57
- rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
- configsip: 0, SPIWP:0xee
- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
- mode:DIO, clock div:2
- load:0x3fff0018,len:4
- load:0x3fff001c,len:4960
- ho 0 tail 12 room 4
- load:0x40078000,len:7768
- ho 0 tail 12 room 4
- load:0x40080000,len:6084
- entry 0x40080324
- I (33) boot: ESP-IDF 3.30101.0 2nd stage bootloader
- I (33) boot: compile time 12:59:10
- I (33) boot: Enabling RNG early entropy source...
- I (35) boot: SPI Speed : 40MHz
- I (38) boot: SPI Mode : DIO
- I (41) boot: SPI Flash Size : 4MB
- I (44) boot: Partition Table:
- I (47) boot: ## Label Usage Type ST Offset Length
- I (53) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (60) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (66) boot: 2 factory factory app 00 00 00010000 00100000
- I (73) boot: End of partition table
- I (76) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x05448 ( 21576) map
- I (91) esp_image: segment 1: paddr=0x00015470 vaddr=0x3ffc0000 size=0x01fe0 ( 8160) load
- I (95) esp_image: segment 2: paddr=0x00017458 vaddr=0x3ffc1fe0 size=0x00000 ( 0) load
- I (100) esp_image: segment 3: paddr=0x00017460 vaddr=0x40080000 size=0x00400 ( 1024) load
- I (108) esp_image: segment 4: paddr=0x00017868 vaddr=0x40080400 size=0x08510 ( 34064) load
- I (129) esp_image: segment 5: paddr=0x0001fd80 vaddr=0x400c0000 size=0x00064 ( 100)
- I (130) esp_image: segment 6: paddr=0x0001fdec vaddr=0x50000000 size=0x00000 ( 0)
- I (133) esp_image: segment 7: paddr=0x0001fdf4 vaddr=0x00000000 size=0x0021c ( 540)
- I (141) esp_image: segment 8: paddr=0x00020018 vaddr=0x400d0018 size=0x10c20 ( 68640) map
- I (178) boot: Loaded app from partition at offset 0x10000
- I (179) boot: Disabling RNG early entropy source...
- I (179) cpu_start: Pro cpu up.
- I (180) cpu_start: Starting app cpu, entry point is 0x40080f8c
- I (0) cpu_start: App cpu up.
- I (188) heap_init: Initializing. RAM available for dynamic allocation:
- I (194) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
- I (199) heap_init: At 3FFC3040 len 0001CFC0 (115 KiB): DRAM
- I (205) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
- I (210) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
- I (215) heap_init: At 40088910 len 000176F0 (93 KiB): IRAM
- I (221) cpu_start: Pro cpu start user code
- E (474) clk: RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain
- I (161) cpu_start: Starting scheduler on PRO CPU.
- I (0) cpu_start: Starting scheduler on APP CPU.
- (app_main) Reset Reason: 5
- RTC_CAL_32K_XTAL:
- calibrate (0): inf kHz
- calibrate (1): inf kHz
- calibrate (2): inf kHz
- calibrate (3): inf kHz
- calibrate (4): inf kHz
- 32K XTAL OSC has not started up
- RTC_CAL_32K_XTAL:
- calibrate (0): inf kHz
- calibrate (1): inf kHz
- calibrate (2): inf kHz
- calibrate (3): inf kHz
- calibrate (4): inf kHz
- (app_main) Initialized.
- (app_main) Random Gen: 405345985
- (app_restart) waiting 5 seconds...
- (app_restart) immediate restart...
- ets Jun 8 2016 00:22:57
- rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
- configsip: 0, SPIWP:0xee
- clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
- mode:DIO, clock div:2
- load:0x3fff0018,len:4
- load:0x3fff001c,len:4960
- ho 0 tail 12 room 4
- load:0x40078000,len:7768
- ho 0 tail 12 room 4
- load:0x40080000,len:6084
- entry 0x40080324
- I (32) boot: ESP-IDF 3.30101.0 2nd stage bootloader
- I (32) boot: compile time 12:59:10
- I (32) boot: Enabling RNG early entropy source...
- I (35) boot: SPI Speed : 40MHz
- I (38) boot: SPI Mode : DIO
- I (41) boot: SPI Flash Size : 4MB
- I (44) boot: Partition Table:
- I (47) boot: ## Label Usage Type ST Offset Length
- I (53) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (59) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (66) boot: 2 factory factory app 00 00 00010000 00100000
- I (72) boot: End of partition table
- I (76) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x05448 ( 21576) map
- I (91) esp_image: segment 1: paddr=0x00015470 vaddr=0x3ffc0000 size=0x01fe0 ( 8160) load
- I (95) esp_image: segment 2: paddr=0x00017458 vaddr=0x3ffc1fe0 size=0x00000 ( 0) load
- I (99) esp_image: segment 3: paddr=0x00017460 vaddr=0x40080000 size=0x00400 ( 1024) load
- I (108) esp_image: segment 4: paddr=0x00017868 vaddr=0x40080400 size=0x08510 ( 34064) load
- I (129) esp_image: segment 5: paddr=0x0001fd80 vaddr=0x400c0000 size=0x00064 ( 100) load
- I (129) esp_image: segment 6: paddr=0x0001fdec vaddr=0x50000000 size=0x00000 ( 0) load
- I (134) esp_image: segment 7: paddr=0x0001fdf4 vaddr=0x00000000 size=0x0021c ( 540)
- I (142) esp_image: segment 8: paddr=0x00020018 vaddr=0x400d0018 size=0x10c20 ( 68640) map
- I (179) boot: Loaded app from partition at offset 0x10000
- I (179) boot: Disabling RNG early entropy source...
- I (179) cpu_start: Pro cpu up.
- I (180) cpu_start: Starting app cpu, entry point is 0x40080f8c
- I (170) cpu_start: App cpu up.
- I (189) heap_init: Initializing. RAM available for dynamic allocation:
- I (195) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
- I (200) heap_init: At 3FFC3040 len 0001CFC0 (115 KiB): DRAM
- I (205) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
- I (210) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
- I (216) heap_init: At 40088910 len 000176F0 (93 KiB): IRAM
- I (221) cpu_start: Pro cpu start user code
- E (475) clk: RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain
- I (161) cpu_start: Starting scheduler on PRO CPU.
- I (0) cpu_start: Starting scheduler on APP CPU.
- (app_main) Reset Reason: 12
- RTC_CAL_32K_XTAL:
- calibrate (0): inf kHz
- calibrate (1): inf kHz
- calibrate (2): inf kHz
- calibrate (3): inf kHz
- calibrate (4): inf kHz
- 32K XTAL OSC has not started up
- RTC_CAL_32K_XTAL:
- calibrate (0): inf kHz
- calibrate (1): inf kHz
- calibrate (2): inf kHz
- calibrate (3): inf kHz
- calibrate (4): inf kHz
- (app_main) Initialized.
- (app_main) Random Gen: 4108722250
- (app_restart) waiting 5 seconds...
sdkconfig.h diff
- - #define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1
- + #define CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL 1
- - #define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024
- + #define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 300
- + #define CONFIG_ESP32_RTC_XTAL_BOOTSTRAP_CYCLES 5
- - #define CONFIG_LOG_COLORS 1
- + #define CONFIG_LOG_COLORS 0
Kind regards, Josh.
Edit 1
I should add that yes I do have loading capacitors on my crystal, the crystal is also 32000Hz instead of 32768Hz, I will have the correct part shortly but for now I don't see any issue using a badly clocked crystal since I only want to ensure its always running, the frequency is irrelevant at this point.