summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/keyborg/board.h3
-rw-r--r--board/keyborg/runtime.c18
-rw-r--r--board/keyborg/spi_comm.c7
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))