Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtctime_dsleep(_aligned) do not take in account sleep mode #1843

Closed
tardyp opened this issue Mar 7, 2017 · 4 comments
Closed

rtctime_dsleep(_aligned) do not take in account sleep mode #1843

tardyp opened this issue Mar 7, 2017 · 4 comments
Labels

Comments

@tardyp
Copy link

tardyp commented Mar 7, 2017

Expected behavior

when using rtctime_dsleep and rtctime_dsleep_aligned with option 4, I should get same power consumption as when using node.dsleep():

image

init.lua used:

deadbeef = rtcmem.read32(0)
if deadbeef == 0xdeadbeef then
    node.dsleep(3000000, 4)
else
    rtcmem.write32(0, 0xdeadbeef)
    -- wait a bit at boot to let the dev a chance to reprogram init.lua
    tmr.create():alarm(10000, tmr.ALARM_SINGLE, function()
        node.dsleep(3000000, 4)
    end)
end

wake up consumption is 2uAh

Actual behavior

image

wake up consumption is 4.57uAh (a bit more than double of waht is expected)

init.lua used is:

time, usec = rtctime.get()
if not (time == 0) then
    rtctime.dsleep_aligned(3000000, 1000000, 4)
else
    rtctime.set(1488882509,676812)
    -- wait a bit at boot to let the dev a chance to reprogram init.lua
    tmr.create():alarm(10000, tmr.ALARM_SINGLE, function()
        rtctime.dsleep_aligned(3000000, 1000000, 4)
    end)
end

Test code

time, usec = rtctime.get()
if not (time == 0) then
    rtctime.dsleep_aligned(3000000, 1000000, 4)
else
    rtctime.set(1488882509,676812)
    -- wait a bit at boot to let the dev a chance to reprogram init.lua
    tmr.create():alarm(10000, tmr.ALARM_SINGLE, function()
        rtctime.dsleep_aligned(3000000, 1000000, 4)
    end)
end

NodeMCU version

master

Hardware

tested with esp12e connected to https://www.msoon.com/LabEquipment/PowerMonitor/

I believe that rtctime is reimplementing its own deepsleep method, and probably it does not take in account the system_deep_sleep_set_option (which we dont have the source code)

Please let me know how I can help while I have access to the power monitor.

@jmattsson
Copy link
Member

Related to #1776 and #1472 . I have not yet had time to investigate replacing rtctime_deep_sleep_us() with system_deep_sleep_instant(), do feel free to have a play with that!

@tardyp
Copy link
Author

tardyp commented Mar 10, 2017

@jmattsson Thanks, I did not see #1472 . I dont think replacing
rtctime_deep_sleep_us (us); by system_deep_sleep_instant(us); will work as is, as it does not save the rtc time, which is the whole purpose of the module.

I am willing to make a bit more tests, but I could use a bit of guiding, as I found it quite difficult to find good documentation with ESP.

I have the feeling that the key is here:

https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/rtc/rtctime_internal.h#L403

but that looks like lots of magic peek pokes I am not very confortable to modify blindly.
I could look at the source code or disassembly or system_deep_sleep_instant. Could you suggest tools to reverse engineer system_deep_sleep_instant() ?

@jmattsson
Copy link
Member

xtensa-lx106-elf-gdb is the main tool for the job. A whole bunch of disass <function_name>, disass <hexaddr+100> for the unnamed functions, and x <hexaddr> to get the actual values loaded by the l32r before the callx0 to work out what's really being called.

I had a quick dig through system_deep_sleep_instant() and the IRAM'd function it calls at the end, system_deep_sleep_local_2(). The former appears to set the deep sleep option, wait for both UART output fifos to drain, then stash away a whole heap of stuff which I haven't even tried chasing down what it really is. I expect one of the things to be the boot reason though. After that, it calls the pm_rtc_clock_cali_proc() which we all know is not a brilliant move since the RTC is horribly temperature dependent and calibrating while the chip is hot for the time it's going to be cold is just a recipe for drift *sigh*. Anyway, after that, it calls pm_set_sleep_time(), before calling system_deep_sleep_local_2(). That function in turn disabled interrupts, disables the flash cache, sets up the GPIO for the wakeup, and finally does the RTC write which presumably puts the chip to sleep. It's quite similar to our rtc_time_enter_deep_sleep_final() function.

So, I guess what we'd like to try is to switch out our rtc_time_enter_deep_sleep() with what is largely a duplicate of system_deep_sleep_instant() but without their calibration nonsense and instead use our existing code for that part:

  uint32_t cycles=rtc_time_us_to_ticks(us);
  rtc_time_add_sleep_tracking(us,cycles);

and then use pm_set_sleep_cycles(us) rather than their pm_set_sleep_time() since we already have the compensated cycle count.

I don't have the time for (or means of testing) that at the moment however, but maybe that will give you something to run with?

If you want to be really sneaky you might even be able to supply an override for pm_rtc_clock_cali_proc() and have it do the add-sleep-tracking, and then return the suitable values to let the system_deep_sleep_instant() function to be used as-is. If you want to try that, look at how we let the linker do that for our _xtos_set_exception_handler override in app/Makefile. I'd still suggest starting with a copy of system_deep_sleep_instant() though, I suspect that's the easier path to at least get some understanding of what's going on.

@stale
Copy link

stale bot commented Jun 7, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 7, 2019
@stale stale bot closed this as completed Jun 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants