-
-
Notifications
You must be signed in to change notification settings - Fork 80
[EV3] Implement reset via watchdog timer #343
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
Changes from all commits
b55bc7e
0a10550
5cbd1a5
e6d35a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| // Copyright (c) 2025 The Pybricks Authors | ||
|
|
||
| // The EV3 requires a GPIO pin to be set in order to stay powered on. | ||
| // We want to be able to do this as early as possible. | ||
|
|
||
| #ifndef _INTERNAL_PBDRV_RESET_EV3_H_ | ||
| #define _INTERNAL_PBDRV_RESET_EV3_H_ | ||
|
|
||
| void pbdrv_reset_ev3_early_init(void); | ||
|
|
||
| #endif // _INTERNAL_PBDRV_RESET_EV3_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| // Copyright (c) 2025 The Pybricks Authors | ||
|
|
||
| // Watchdog timer driver for EV3. | ||
|
|
||
| #include <pbdrv/config.h> | ||
|
|
||
| #if PBDRV_CONFIG_WATCHDOG_EV3 | ||
|
|
||
| #include <tiam1808/hw/soc_AM1808.h> | ||
| #include <tiam1808/timer.h> | ||
|
|
||
| // The input to Timer1 is PLL0_AUXCLK which is 24 MHz | ||
| // Configure the timeout to be 3 seconds | ||
| #define WDT_TIMEOUT_SECONDS 3ull | ||
| #define WDT_PERIOD_LSB ((WDT_TIMEOUT_SECONDS * SOC_ASYNC_2_FREQ) & 0xffffffff) | ||
| #define WDT_PERIOD_MSB (((WDT_TIMEOUT_SECONDS * SOC_ASYNC_2_FREQ) >> 32) & 0xffffffff) | ||
|
|
||
| void pbdrv_watchdog_init(void) { | ||
| TimerDisable(SOC_TMR_1_REGS, TMR_TIMER_BOTH); | ||
| TimerConfigure(SOC_TMR_1_REGS, TMR_CFG_64BIT_WATCHDOG); | ||
| TimerPeriodSet(SOC_TMR_1_REGS, TMR_TIMER12, WDT_PERIOD_LSB); | ||
| TimerPeriodSet(SOC_TMR_1_REGS, TMR_TIMER34, WDT_PERIOD_MSB); | ||
| TimerWatchdogActivate(SOC_TMR_1_REGS); | ||
| } | ||
|
|
||
| void pbdrv_watchdog_update(void) { | ||
| TimerWatchdogReactivate(SOC_TMR_1_REGS); | ||
| } | ||
|
|
||
| #endif // PBDRV_CONFIG_WATCHDOG_EV3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| // Copyright (c) 2025 The Pybricks Authors | ||
|
|
||
| #ifndef _PBDRV_COMPILER_H_ | ||
|
|
||
| // Marks a switch case that intentionally falls through to the next one | ||
| #define PBDRV_FALL_THROUGH __attribute__((fallthrough)) | ||
|
|
||
| // Forces the compiler to not reorder memory access around this line | ||
| #define pbdrv_compiler_memory_barrier() __asm__ volatile ("" ::: "memory") | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,7 @@ | |
| #include <tiam1808/hw/soc_AM1808.h> | ||
| #include <tiam1808/i2c.h> | ||
| #include <tiam1808/psc.h> | ||
| #include <tiam1808/timer.h> | ||
| #include <tiam1808/uart.h> | ||
|
|
||
| #include <umm_malloc.h> | ||
|
|
@@ -64,8 +65,8 @@ | |
| #include "../../drv/led/led_dual.h" | ||
| #include "../../drv/led/led_pwm.h" | ||
| #include "../../drv/pwm/pwm_ev3.h" | ||
| #include "../../drv/reset/reset_ev3.h" | ||
| #include "../../drv/uart/uart_ev3.h" | ||
| #include "../../drv/reset/reset.h" | ||
|
|
||
| enum { | ||
| LED_DEV_0_STATUS, | ||
|
|
@@ -489,6 +490,12 @@ void ev3_panic_handler(int except_type, ev3_panic_ctx *except_data) { | |
| panic_putu32(except_data->spsr); | ||
|
|
||
| panic_puts("\r\nSystem will now reboot...\r\n"); | ||
|
|
||
| // Poke the watchdog timer with a bad value to immediately trigger it | ||
| // if it has already been configured. If it has *not* been configured, | ||
| // that means we are crashing in early boot, and we let the jump back | ||
| // to the reset vector take care of rebooting the system. | ||
| HWREG(SOC_TMR_1_REGS + TMR_WDTCR) = 0; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a new
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need one? It currently reports as a watchdog reset
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if it is worth it or not. That is why I ask. 😄 There is a slight difference in that the true watchdog reset only happens if the event loops stops running while a panic is a different mode of failure. So could be potentially useful for getting info on the cause of a crash. But would anyone ever actually do that? Maybe not very likely.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't seem too likely, since right now crash dumps aren't saved anywhere and you need to have the debug console connected to see them. Perhaps we can change "watchdog" to a generic "fatal error"?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, we'll leave it the way it is. I would prefer to stick with calling it watchdog and add a new reason if we need to differentiate. |
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -663,7 +670,7 @@ void SystemInit(void) { | |
|
|
||
| // Must set the power enable bin before disabling the pull up on the power | ||
| // pin below, otherwise the hub will power off. | ||
| pbdrv_reset_init(); | ||
| pbdrv_reset_ev3_early_init(); | ||
|
|
||
| // Disable all pull-up/pull-down groups. | ||
| HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_ENA) &= ~0xFFFFFFFF; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.