Skip to content

Commit 1e1388f

Browse files
ArcaneNibbledlech
authored andcommitted
pbio/drv/reset/reset_ev3: Implement reset via watchdog
The watchdog is the only way to reset *everything* on the AM1808. It performs the same function as a power-on reset.
1 parent 45d91fa commit 1e1388f

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

lib/pbio/drv/reset/reset_ev3.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,32 @@
1212

1313
#include "../drv/gpio/gpio_ev3.h"
1414

15+
#include <tiam1808/hw/soc_AM1808.h>
1516
#include <tiam1808/hw/hw_syscfg0_AM1808.h>
17+
#include <tiam1808/hw/hw_types.h>
18+
#include <tiam1808/timer.h>
19+
20+
#define BOOTLOADER_UPDATE_MODE_VALUE 0x5555AAAA
21+
22+
typedef struct {
23+
// 0xffff1ff0
24+
uint32_t _dummy0;
25+
// 0xffff1ff4
26+
// Pybricks uses this flag to determine software reset vs other resets
27+
uint32_t reset_reason_flag;
28+
// 0xffff1ff8
29+
// Have not fully investigated this, but the bootloader seems to store
30+
// the result of (DDR) memory testing at 0xffff1ffa and 0xffff1ffb
31+
uint32_t _bootloader_unk_ram_test;
32+
// 0xffff1ffc
33+
uint32_t bootloader_update_flag;
34+
} persistent_data_t;
35+
// This is defined as an extern variable so that its address can be specified
36+
// in the platform.ld linker script. This means that the linker script
37+
// contains information about *all* fixed memory locations.
38+
//
39+
// This lives at the very end of the ARM local RAM.
40+
extern volatile persistent_data_t ev3_persistent_data;
1641

1742
static const pbdrv_gpio_t poweroff_pin = PBDRV_GPIO_EV3_PIN(13, 19, 16, 6, 11);
1843

@@ -23,11 +48,17 @@ void pbdrv_reset_init(void) {
2348
void pbdrv_reset(pbdrv_reset_action_t action) {
2449
for (;;) {
2550
switch (action) {
26-
case PBDRV_RESET_ACTION_RESET_IN_UPDATE_MODE:
27-
// TODO
51+
case PBDRV_RESET_ACTION_POWER_OFF:
52+
pbdrv_reset_power_off();
2853
break;
29-
// TODO: implement case PBDRV_RESET_ACTION_RESET
54+
case PBDRV_RESET_ACTION_RESET_IN_UPDATE_MODE:
55+
ev3_persistent_data.bootloader_update_flag = BOOTLOADER_UPDATE_MODE_VALUE;
56+
__attribute__((fallthrough));
3057
default:
58+
// PBDRV_RESET_ACTION_RESET
59+
60+
// Poke the watchdog timer with a bad value to immediately trigger it
61+
HWREG(SOC_TMR_1_REGS + TMR_WDTCR) = 0;
3162
break;
3263
}
3364
}

lib/pbio/platform/ev3/platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <tiam1808/hw/soc_AM1808.h>
5050
#include <tiam1808/i2c.h>
5151
#include <tiam1808/psc.h>
52+
#include <tiam1808/timer.h>
5253
#include <tiam1808/uart.h>
5354

5455
#include <umm_malloc.h>
@@ -489,6 +490,12 @@ void ev3_panic_handler(int except_type, ev3_panic_ctx *except_data) {
489490
panic_putu32(except_data->spsr);
490491

491492
panic_puts("\r\nSystem will now reboot...\r\n");
493+
494+
// Poke the watchdog timer with a bad value to immediately trigger it
495+
// if it has already been configured. If it has *not* been configured,
496+
// that means we are crashing in early boot, and we let the jump back
497+
// to the reset vector take care of rebooting the system.
498+
HWREG(SOC_TMR_1_REGS + TMR_WDTCR) = 0;
492499
}
493500

494501
/**

lib/pbio/platform/ev3/platform.ld

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ MEMORY
99
SRAM_PRU1 (rw) : ORIGIN = 0x80010000, LENGTH = 64K
1010
DDR_unused (rwx) : ORIGIN = 0xC0000000, LENGTH = 0x8000
1111
DDR (rwx) : ORIGIN = 0xC0008000, LENGTH = (64M - 0x8000)
12-
ARM_LRAM (rwx) : ORIGIN = 0xFFFF0000, LENGTH = 8K
12+
ARM_LRAM (rwx) : ORIGIN = 0xFFFF0000, LENGTH = (8K - 16)
1313
}
1414

1515
_minimal_stack_size = 4M;
1616
pbdrv_stack_end = ORIGIN(DDR) + LENGTH(DDR) - 4;
1717
/* Extra heap for large allocations (images, etc). */
1818
pb_umm_heap_size = 2M;
19+
/*
20+
We declare this in this style rather than creating a section.
21+
If we do create a section, the loader (U-boot) will always clear it.
22+
This defeats what we are trying to do to determine reset causes.
23+
*/
24+
ev3_persistent_data = ORIGIN(ARM_LRAM) + LENGTH(ARM_LRAM);
1925

2026
SECTIONS
2127
{

0 commit comments

Comments
 (0)