FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

mimxrt/modmachine: Fix reset_cause and add HARD/DEEPSLEEP constants. by dpgeorge · Pull Request #19619 · micropython/micropython · GitHub

mimxrt/modmachine: Fix reset_cause and add HARD/DEEPSLEEP constants. - #19619

Open
dpgeorge wants to merge 1 commit into
micropython:masterfrom
dpgeorge:mimxrt-fix-reset-cause
Open

mimxrt/modmachine: Fix reset_cause and add HARD/DEEPSLEEP constants.#19619
dpgeorge wants to merge 1 commit into
micropython:masterfrom
dpgeorge:mimxrt-fix-reset-cause

Conversation

Copy link
Copy Markdown
Member

Summary

The machine.reset_cause() function was only partially working on mimxrt. This commit fixes it so that all five reset causes now work correctly:

  • SOFT_RESET is now set only after a soft reset at the REPL.
  • HARD_RESET is now set correctly (previously it used SOFT_RESET), and this constant is exposed to Python.
  • DEEPSLEEP_RESET is now set when the timer alarm wakes the device, and this constant is exposed to Python.

Testing

Tested on TEENSY40, using this helper script:

# cause.py
import machine

reason = {}
for g in machine.__dict__:
    if g.endswith("_RESET"):
        reason[getattr(machine, g)] = g
print("cause =", machine.reset_cause(), reason[machine.reset_cause()])

Run that via mpremote resume run cause.py to check the reset cause.

Tested all 5 cases, using machine.reset(), machine.deepsleep(1000) and machine.WDT(timeout=1000) to trigger the cases.

Generative AI

I did not use generative AI tools when creating this PR.

Copy link
Copy Markdown
Member Author

@robert-hh would appreciate if you could take a look at this change, see if it makes sense to you. Thanks!

github-actions Bot commented Aug 14, 2026
edited
Loading

Copy link
Copy Markdown

Code size report:

Reference:  examples/rp2: Add PIO example for quadrature encoding. [9b2d80c]
Comparison: mimxrt/modmachine: Fix reset_cause and add HARD/DEEPSLEEP constants. [merge of a056c59]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:  +104 +0.026% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

Copy link
Copy Markdown
Contributor

Thank you!

Copy link
Copy Markdown
Contributor

Will do.

Copy link
Copy Markdown
Contributor

Tested with MIMXRT1011 (Adafruit Metro M7), MIMXRT1020 (MIMXRT1020-EVK), MIMXRT1062 (Teensy 4.1 and OpenMV RT1060), MIMXRT1176 (MIMXRT1170-EVK).

PWRON_RESET, WDT_RESET, DEEPSLEEP_RESET and SOFT_RESET are reliably detected. HARD_RESET is reported only immediately after firmware upload by the Adafruit and MIMXRT1020-EVK board. The MIMXRT MCUs do not have a dedicated hard reset Pin. Some board have a reset button, but that causes a power cycle.

There is an irregularity with the MIMXRT1170-EVK board.

  1. It does not reset reliably after machine.deepsleep(). Sometimes the board just locks up.
  2. If it proceeds to a reset with machine.deepsleep(), it shows DEEPSLEEP_RESET for all following resets done with the board's reset button until e.g. a soft reset is performed..

Copy link
Copy Markdown
Member Author

Thanks for testing!

HARD_RESET is reported only immediately after firmware upload by the Adafruit and MIMXRT1020-EVK board. The MIMXRT MCUs do not have a dedicated hard reset Pin. Some board have a reset button, but that causes a power cycle.

I tested this by issuing machine.reset() at the REPL, then when it came back up as a USB device, checked the reset cause. It was HARD_RESET.

  1. It does not reset reliably after machine.deepsleep(). Sometimes the board just locks up.

OK. That seems unrelated to this PR.

2. If it proceeds to a reset with machine.deepsleep(), it shows DEEPSLEEP_RESET for all following resets done with the board's reset button until e.g. a soft reset is performed..

I pushed a commit which should resolve that issue: clearing the LPTA bit if it's set. Could you please retest on that board?

octoprobe-bot commented Aug 14, 2026
edited
Loading

Copy link
Copy Markdown

Octoprobe PR report

Test Tests
passed
Tests
skipped
Tests
xfailed
Tests
failed
format flash 1
run-tests.py 935 95
run-tests.py --via-mpy --emit native 922 108
run-tests.py --via-mpy 935 95
run-perfbench.py 24
run-natmodtests.py 37 4
run-mpremote-tests.sh 21 6
run-tests.py --test-dirs=extmod_hardware 18 9 3
run-tests.py --test-dirs=extmod_hardware --emit-native 18 9 3
Total 2910 321 6 6
Failures

Group: run-mpremote-tests.sh

Test mimxrt
1133-
TEENSY40
test_unicode.sh FAIL FAIL FAIL
test_mount.sh FAIL FAIL FAIL

Copy link
Copy Markdown
Contributor

OK. That seems unrelated to this PR.

It is a different issue- Deepsleep seem generally strange.

I pushed a commit which should resolve that issue: clearing the LPTA bit if it's set. Could you please retest on that board?

No change. Maybe one should fix the deepsleep() behavior first.

Copy link
Copy Markdown
Contributor

At least, replacing
SNVS->LPSR &= ~SNVS_LPSR_LPTA_MASK;
with
machine_rtc_irq_deinit();
fixes the behavior of a sticky DEEPSLEEP_RESET.

machine.deepsleep() itself still behaves wrong. Either it resets immediately or not at all and the board freezes. But that's another story.

Comment thread ports/mimxrt/modmachine.c Outdated
reset_cause = MP_DEEPSLEEP_RESET;
} else if (SNVS->LPSR & SNVS_LPSR_LPTA_MASK) {
// Device was reset due to low-power timer alarm.
SNVS->LPSR &= ~SNVS_LPSR_LPTA_MASK;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Better call instead machine_rtc_irq_deinit();. That fixes the sticky DEEPSLEEP_RESET state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

You can call as well machine_rtc_alarm_off(true), which is called by machine_rtc_irq_deinit(), but it requires a declaration in modmachine.c, and an extra push of the argument.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

OK, thanks for that. I've now applied your suggestion to call machine_rtc_alarm_off(true) (that function is independent of the Python bindings/state, so a better fit).

Tested on TEENSY40 and it still works.

The `machine.reset_cause()` function was only partially working on mimxrt.
This commit fixes it so that all five reset causes now work correctly:
- SOFT_RESET is now set only after a soft reset at the REPL.
- HARD_RESET is now set correctly (previously it used SOFT_RESET), and this
  constant is exposed to Python.
- DEEPSLEEP_RESET is now set when the timer alarm wakes the device, and
  this constant is exposed to Python.

Signed-off-by: Damien George <damien@micropython.org>
dpgeorge force-pushed the mimxrt-fix-reset-cause branch from 7456a79 to a056c59 Compare August 17, 2026 07:35

Copy link
Copy Markdown
Member Author

machine.deepsleep() itself still behaves wrong. Either it resets immediately or not at all and the board freezes.

What argument are you using? I'm calling machine.deepsleep(1000).

But regardless, that needs to be fixed in a separate PR.

Copy link
Copy Markdown
Contributor

using machine.deepsleep(timeout) works with MIMXRT10xx, but not with MIMXRT117x. And machine.deepsleep() with a wakeup by low at the WAKEUP pin does not work at all.

But regardless, that needs to be fixed in a separate PR.

For RT117x, using rtc.alarm() fails as well. The respective IRQ is simply not configured. I got to that because machine.deepsleep(timeout) uses the rtc alarm for the timeout. I'm working on it at the moment. rtc.alarm() and machine.deepsleep(timeout) for RT1176 are fine now, Pin wakeup from machine.deepsleep() is still due.
Looking into the code of machine.deepsleep() it looks wrong. It should configure the wakeup source either from the rtc alarm, if a timeout is set, of from the WAKEUP pin. But the code path for the wakeup pin is always executed. b.t.w: Wakeup by Pin seems not possible for Teensy, because the pin is not wired at the board. Maybe any Pin interrupt could be used, but that is a larger change.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants


Back | FazBrowse Home | New Git URL