From 019f50590e5c0d49baaf9dbe980c22f8e1e19df1 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Thu, 9 Aug 2012 17:09:38 +0000 Subject: [PATCH] stm32: add wakeup from serial port as a debug feature When STOP mode is activated, the UART is not able to wakeup the EC when sleeping, preventing to enter commands on the EC serial console. Allow to switch the UART RX line as a GPIO connected to EXTINT10 to wakeup the system on incoming character. This is just a debug feature since EXTINT10 is normally used to scan the keyboard. Signed-off-by: Vincent Palatin BUG=chrome-os-partner:8866 TEST=on Snow, enable CONFIG_FORCE_CONSOLE_RESUME at build time and type "sleepmask 0" on the EC console, see I can get the serial console back by typing a character on the serial console. Change-Id: I936cbf13707ef8cde277f1053a4d35d23ff06511 Reviewed-on: https://gerrit.chromium.org/gerrit/29776 Reviewed-by: David Hendricks Commit-Ready: Vincent Palatin Tested-by: Vincent Palatin --- chip/stm32/clock-stm32f100.c | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/chip/stm32/clock-stm32f100.c b/chip/stm32/clock-stm32f100.c index bf70345157..e3ae933c6a 100644 --- a/chip/stm32/clock-stm32f100.c +++ b/chip/stm32/clock-stm32f100.c @@ -20,6 +20,9 @@ #include "timer.h" #include "util.h" +/* Allow serial console to wake up the EC from STOP mode */ +/* #define CONFIG_FORCE_CONSOLE_RESUME */ + /** * minimum delay to enter stop mode * STOP mode wakeup time with regulator in low power mode is 5 us. @@ -153,6 +156,36 @@ static void config_hispeed_clock(void) } #ifdef CONFIG_LOW_POWER_IDLE + +#ifdef CONFIG_FORCE_CONSOLE_RESUME +static void enable_serial_wakeup(int enable) +{ + static uint32_t save_crh, save_exticr; + + if (enable) { + /** + * allow to wake up from serial port (RX on pin PA10) + * by setting it as a GPIO with an external interrupt. + */ + save_crh = STM32_GPIO_CRH_OFF(GPIO_A); + save_exticr = STM32_AFIO_EXTICR(10 / 4); + STM32_GPIO_CRH_OFF(GPIO_A) = (save_crh & ~0xf00) | 0x400; + STM32_AFIO_EXTICR(10 / 4) = (save_exticr & ~(0xf << 8)); + } else { + /* serial port wake up : don't go back to sleep */ + if (STM32_EXTI_PR & (1 << 10)) + disable_sleep(SLEEP_MASK_FORCE); + /* restore keyboard external IT on PC10 */ + STM32_GPIO_CRH_OFF(GPIO_A) = save_crh; + STM32_AFIO_EXTICR(10 / 4) = save_exticr; + } +} +#else +static void enable_serial_wakeup(int enable) +{ +} +#endif + /* Idle task. Executed when no tasks are ready to be scheduled. */ void __idle(void) { @@ -169,6 +202,8 @@ void __idle(void) if (!sleep_mask && (next_delay > STOP_MODE_LATENCY)) { /* deep-sleep in STOP mode */ + enable_serial_wakeup(1); + /* set deep sleep bit */ CPU_SCB_SYSCTRL |= 0x4; @@ -176,6 +211,9 @@ void __idle(void) asm("wfi"); CPU_SCB_SYSCTRL &= ~0x4; + + enable_serial_wakeup(0); + /* re-lock the PLL */ config_hispeed_clock();