Page 1 of 1

Deep sleep wake up problem <SOLVED>

Posted: Fri May 17, 2019 4:41 pm
by chriselef
Hello all,

The problem I am going to describe have been tested on both the latest IDF and the stable 3.2
We got a batch of a hundred boards that we designed around the ESP32.
The modules that are populated, are marked as ESP32-WROOM-32.
The problem we are facing is that when the module wakes up from deep sleep (either from timer timeout or EXT1 event ) the cause is always 0 and reset reason always 7.

Output 1 (assembled boards):

Code: Select all

I (0) cpu_start: App cpu up.
I (80) heap_init: Initializing. RAM available for dynamic allocation:
I (80) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (80) heap_init: At 3FFB22E0 len 0002DD20 (183 KiB): DRAM
I (81) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (81) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (81) heap_init: At 4008877C len 00017884 (94 KiB): IRAM
I (82) cpu_start: Pro cpu start user code
I (43) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (44) Main: Woke up times : 0
I (44) Main: Reset Reason (7): 
I (44) Main: Timer Group0 Watch dog reset digital core
I (44) Main: Wake Cause :(0) - rtc_get_wakeup_cause() : (903) 
I (45) Main: Undefined wakeup cause.
I (45) Main: Enabling timer wakeup seconds : 10 - clock source : 1 - value : 0x00000000
I (45) Main: Enabling EXT1 wakeup on pins GPIO39, GPIO36, GPIO35
I (79) cpu_start: Pro cpu up.
I (79) cpu_start: Starting app cpu, entry point is 0x40080dc8
0x40080dc8: call_start_cpu1 at /data/esp/esp-idf/components/esp32/cpu_start.c:246
I (0) cpu_start: App cpu up.
I (80) heap_init: Initializing. RAM available for dynamic allocation:
I (80) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (80) heap_init: At 3FFB22E0 len 0002DD20 (183 KiB): DRAM
I (81) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (81) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (81) heap_init: At 4008877C len 00017884 (94 KiB): IRAM
I (82) cpu_start: Pro cpu start user code
I (43) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (44) Main: Woke up times : 0
I (44) Main: Reset Reason (7): 
I (44) Main: Timer Group0 Watch dog reset digital core
I (44) Main: Wake Cause :(0) - rtc_get_wakeup_cause() : (903) 
I (45) Main: Undefined wakeup cause.
I (45) Main: Enabling timer wakeup seconds : 10 - clock source : 1 - value : 0x00000000
I (45) Main: Enabling EXT1 wakeup on pins GPIO39, GPIO36, GPIO35
The same code on the modules that we used for the development works fine.
This module also is marked as ESP32-WROOM-32 but has more labels written on the shield metal plate.

Output 2 (development prototypes):

Code: Select all

I (0) cpu_start: App cpu up.
I (175) heap_init: Initializing. RAM available for dynamic allocation:
I (175) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (175) heap_init: At 3FFB22E0 len 0002DD20 (183 KiB): DRAM
I (175) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (176) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (176) heap_init: At 4008877C len 00017884 (94 KiB): IRAM
I (176) cpu_start: Pro cpu start user code
I (138) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (138) Main: Woke up times : 0
I (138) Main: Reset Reason (1): 
I (138) Main: Vbat power on reset
I (138) Main: Wake Cause :(0) - rtc_get_wakeup_cause() : (897) 
I (139) Main: Undefined wakeup cause.
I (139) Main: Enabling timer wakeup seconds : 10 - clock source : 1 - value : 0x00000000
I (139) Main: Enabling EXT1 wakeup on pins GPIO39, GPIO36, GPIO35
I (79) cpu_start: Pro cpu up.
I (79) cpu_start: Starting app cpu, entry point is 0x40080dc8
0x40080dc8: call_start_cpu1 at /data/esp/esp-idf/components/esp32/cpu_start.c:246
I (0) cpu_start: App cpu up.
I (80) heap_init: Initializing. RAM available for dynamic allocation:
I (80) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (80) heap_init: At 3FFB22E0 len 0002DD20 (183 KiB): DRAM
I (81) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (81) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (81) heap_init: At 4008877C len 00017884 (94 KiB): IRAM
I (82) cpu_start: Pro cpu start user code
I (43) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (44) Main: Woke up times : 1
I (44) Main: Reset Reason (5): 
I (44) Main: Deep Sleep reset digital core
I (44) Main: Wake Cause :(3) - rtc_get_wakeup_cause() : (901) 
I (45) Main: Wakeup caused by external signal using RTC_CNTL
I (45) Main: Wake up from GPIO 39
I (45) Main: Enabling timer wakeup seconds : 10 - clock source : 1 - value : 0x00000000
I (46) Main: Enabling EXT1 wakeup on pins GPIO39, GPIO36, GPIO35
The code that does this is quite trivial.

Code: Select all

static const char *TAG = "Main";

static RTC_DATA_ATTR uint32_t iWakeUpTimesCounter;

static void RTC_IRAM_ATTR run_after_wake()
{
	iWakeUpTimesCounter++;
}


RESET_REASON getResetReason(bool bLogResetReason)
{
	RESET_REASON reset_reason = rtc_get_reset_reason(0);
	if (!bLogResetReason)
	{
		return reset_reason;
	}

	ESP_LOGI(TAG, "Reset Reason (%d): ", reset_reason);

	switch (reset_reason)
	{
	case POWERON_RESET:
		ESP_LOGI(TAG, "Vbat power on reset");
		break;
	case SW_RESET:
		ESP_LOGI(TAG, "Software reset digital core");
		break;
	case OWDT_RESET:
		ESP_LOGI(TAG, "Legacy watch dog reset digital core");
		break;
	case DEEPSLEEP_RESET:
		ESP_LOGI(TAG, "Deep Sleep reset digital core");
		break;
	case SDIO_RESET:
		ESP_LOGI(TAG, "Reset by SLC module, reset digital core");
		break;
	case TG0WDT_SYS_RESET:
		ESP_LOGI(TAG, "Timer Group0 Watch dog reset digital core");
		break;
	case TG1WDT_SYS_RESET:
		ESP_LOGI(TAG, "Timer Group1 Watch dog reset digital core");
		break;
	case RTCWDT_SYS_RESET:
		ESP_LOGI(TAG, "RTC Watch dog Reset digital core");
		break;
	case INTRUSION_RESET:
		ESP_LOGI(TAG, "Intrusion tested to reset CPU");
		break;
	case TGWDT_CPU_RESET:
		ESP_LOGI(TAG, "Time Group reset CPU");
		break;
	case SW_CPU_RESET:
		ESP_LOGI(TAG, "Software reset CPU");
		break;
	case RTCWDT_CPU_RESET:
		ESP_LOGI(TAG, "RTC Watch dog Reset CPU");
		break;
	case EXT_CPU_RESET:
		ESP_LOGI(TAG, "for APP CPU, reseted by PRO CPU");
		break;
	case RTCWDT_BROWN_OUT_RESET:
		ESP_LOGI(TAG, "Reset when the vdd voltage is not stable");
		break;
	case RTCWDT_RTC_RESET:
		ESP_LOGI(TAG, "RTC Watch dog reset digital core and rtc module");
		break;
	default:
		ESP_LOGI(TAG, "No mean reset reason");
		break;
	}
	return reset_reason;
}

esp_sleep_wakeup_cause_t getWakeUpCause(bool bLogCause)
{
	WAKEUP_REASON rtcWakeUpCause = 0;
	rtcWakeUpCause = rtc_get_wakeup_cause();
	esp_sleep_wakeup_cause_t wake_cause = esp_sleep_get_wakeup_cause();
	if (!bLogCause)
	{
		return wake_cause;
	}
	ESP_LOGI(TAG, "Wake Cause :(%d) - rtc_get_wakeup_cause() : (%d) ", wake_cause, rtcWakeUpCause);

	switch (wake_cause)
	{
		case ESP_SLEEP_WAKEUP_EXT0:
			ESP_LOGI(TAG, "Wakeup caused by external signal using RTC_IO");

			break;
		case ESP_SLEEP_WAKEUP_EXT1:
		{
			ESP_LOGI(TAG, "Wakeup caused by external signal using RTC_CNTL");
			uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();
			if (wakeup_pin_mask != 0)
			{
				int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
				ESP_LOGI(TAG, "Wake up from GPIO %d", pin);
			}
			else
			{
				ESP_LOGI(TAG, "Wake up from GPIO");
			}
			break;
		}
		case ESP_SLEEP_WAKEUP_TIMER:
			ESP_LOGI(TAG, "Wakeup caused by timer");
			break;
		case ESP_SLEEP_WAKEUP_TOUCHPAD:
			ESP_LOGI(TAG, "Wakeup caused by touchpad");
			break;
		case ESP_SLEEP_WAKEUP_ULP:
			ESP_LOGI(TAG, "Wakeup caused by ULP program");
			break;
		default:
			ESP_LOGI(TAG, "Undefined wakeup cause.");
			break;
	}
	return wake_cause;
}



void app_main()
{
	ESP_LOGI(TAG, "Woke up times : %d", iWakeUpTimesCounter);
	uint64_t wakeup_time_sec = 10;

	getResetReason(true);
	getWakeUpCause(true);

	int sourceClock = rtc_clk_slow_freq_get();
	esp_err_t err;
	err = esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
	ESP_LOGI(TAG, "Enabling timer wakeup seconds : %lld - clock source : %d - value : 0x%08x", wakeup_time_sec, sourceClock, err);
	const int ext_wakeup_pin_1 = BT1;
	const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
	const int ext_wakeup_pin_2 = BT2;
	const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2;
	const int ext_wakeup_pin_3 = BT3;
	const uint64_t ext_wakeup_pin_3_mask = 1ULL << ext_wakeup_pin_3;
	ESP_LOGI(TAG, "Enabling EXT1 wakeup on pins GPIO%d, GPIO%d, GPIO%d", ext_wakeup_pin_1, ext_wakeup_pin_2, ext_wakeup_pin_3);
	esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask | ext_wakeup_pin_3_mask, ESP_EXT1_WAKEUP_ANY_HIGH);
	esp_set_deep_sleep_wake_stub(&run_after_wake);

	esp_deep_sleep_start();
}
We have de soldered the ESP32 from one assembled board and soldered a ESP32 module from the batch that we used on the development
and it worked as it should..

We suspect that the assembled modules are older version. maybe?

Is there any other reason that the assembled modules have this behaviour in comparison to the modules we used to develop the firmware ?
Have someone came across a similar thing?

Thanks,
Chris

Re: Deep sleep wake up problem

Posted: Fri May 17, 2019 7:37 pm
by WiFive
Yes rev0 silicon has a bug where you have to run the default wake stub when coming out of deepsleep. So if you set a custom stub you should call the default from it.

Re: Deep sleep wake up problem <SOLVED>

Posted: Thu May 23, 2019 2:05 pm
by chriselef
Thanks WiFive...
That was the problem