From dbb55cb1f4322cd78d180c25ceeda43439766e40 Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Wed, 11 Jun 2014 14:12:58 -0700 Subject: [PATCH] Keyborg: implement system reboot In case the slave got into a bad state, we may need a way to reboot the slave from the master. The protocol must not involve SPI communication; otherwise this will fail if the slave SPI module is in a bad state. This CL implements this using SPI_NSS. In normal SPI communication, the master pulls SPI_NSS low and immediately sync with the slave. To reboot the slave, the master pulls SPI_NSS low without the following sync. BUG=None TEST=Reboots the slave from the master. BRANCH=None Change-Id: I947523e1d86fb2332b87fbfa3dab73cba958fb72 Signed-off-by: Vic Yang Reviewed-on: https://chromium-review.googlesource.com/203485 Reviewed-by: Vincent Palatin --- board/keyborg/board.h | 3 +++ board/keyborg/runtime.c | 18 ++++++++++++++++++ board/keyborg/spi_comm.c | 7 ++++++- 3 files changed, 27 insertions(+), 1 deletion(-) 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))