diff options
-rw-r--r-- | board/keyborg/board.h | 3 | ||||
-rw-r--r-- | board/keyborg/runtime.c | 18 | ||||
-rw-r--r-- | board/keyborg/spi_comm.c | 7 |
3 files changed, 27 insertions, 1 deletions
diff --git a/board/keyborg/board.h b/board/keyborg/board.h index b1750575a6..5d63551d33 100644 --- a/board/keyborg/board.h +++ b/board/keyborg/board.h @@ -40,6 +40,9 @@ enum gpio_signal; /* Initialize all useful registers */ void hardware_init(void); +/* On the master, reboot both chips. On the slave, reboot itself. */ +void system_reboot(void); + #endif /* !__ASSEMBLER__ */ #endif /* __BOARD_H */ diff --git a/board/keyborg/runtime.c b/board/keyborg/runtime.c index c7c619c46c..e335442398 100644 --- a/board/keyborg/runtime.c +++ b/board/keyborg/runtime.c @@ -8,6 +8,7 @@ #include "cpu.h" #include "debug.h" #include "irq_handler.h" +#include "master_slave.h" #include "registers.h" #include "timer.h" #include "util.h" @@ -109,6 +110,23 @@ uint32_t task_wait_event(int timeout_us) return evt; } +void system_reboot(void) +{ + if (master_slave_is_master()) { + /* Ask the slave to reboot as well */ + STM32_GPIO_BSRR(GPIO_A) = 1 << (6 + 16); + udelay(10 * MSEC); /* The slave reboots in 5 ms */ + } + + /* Ask the watchdog to trigger a hard reboot */ + STM32_IWDG_KR = 0x5555; + STM32_IWDG_RLR = 0x1; + STM32_IWDG_KR = 0xcccc; + /* wait for the watchdog */ + while (1) + ; +} + /* --- stubs --- */ void __hw_timer_enable_clock(int n, int enable) { /* Done in hardware init */ } diff --git a/board/keyborg/spi_comm.c b/board/keyborg/spi_comm.c index 380ab6906b..4c5c729e7b 100644 --- a/board/keyborg/spi_comm.c +++ b/board/keyborg/spi_comm.c @@ -408,7 +408,12 @@ static void spi_nss_interrupt(void) if (spi->sr & STM32_SPI_SR_RXNE) in_msg[0] = spi->dr; - master_slave_sync(5); + /* + * SPI_NSS is also used for the master to reboot the slave. + * If SPI_NSS goes low without a sync in time, reboots. + */ + if (master_slave_sync(5)) + system_reboot(); /* Read in the packet size */ while (!(spi->sr & STM32_SPI_SR_RXNE)) |