summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-10-27 16:30:08 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-28 06:12:33 +0000
commit682f7aabda3bc55854c1df8fd2757e4d600832f1 (patch)
tree080bdda86e20f40cf055416b2cf9b302c75915dc
parent5f4ea79bb19df9e0595f2011663587fe6ae736cd (diff)
downloadchrome-ec-682f7aabda3bc55854c1df8fd2757e4d600832f1.tar.gz
stm32f0: stm32f3: Wake from STOP mode on UART start bit
By default, UART wakes the chip up on RXNE interrupt. This means when the chip wakes up, RDR is full and only the shift register is empty, and this leaves us only the time of a single character to process the character in RDR. On some system, this is not enough and the first (or even the second) character is overrun, and thus any multi-character keys (e.g. arrow keys) break. To avoid this problem, let's change the wake source to wake on start bit detection. This gives us the time for one more character to wake up and process the console input. BRANCH=None BUG=chrome-os-partner:33219 TEST=Enable low power mode on Ryu P2. In STOP mode, hit up arrow key and see the last command show up. Change-Id: Idce4c0bdfcf3e04ad84152ba525f704a0909f115 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/225771 Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@google.com>
-rw-r--r--chip/stm32/clock-stm32f0.c6
-rw-r--r--chip/stm32/registers.h5
-rw-r--r--chip/stm32/uart.c13
3 files changed, 20 insertions, 4 deletions
diff --git a/chip/stm32/clock-stm32f0.c b/chip/stm32/clock-stm32f0.c
index ac5e153209..4272349971 100644
--- a/chip/stm32/clock-stm32f0.c
+++ b/chip/stm32/clock-stm32f0.c
@@ -328,15 +328,17 @@ void clock_refresh_console_in_use(void)
#define UARTN_BASE STM32_USART_BASE(CONFIG_UART_CONSOLE)
static void enable_serial_wakeup(int enable)
{
- if (enable)
+ if (enable) {
/*
* Allow UART wake up from STOP mode. Note, UART clock must
* be HSI(8MHz) for wakeup to work.
*/
STM32_USART_CR1(UARTN_BASE) |= STM32_USART_CR1_UESM;
- else
+ STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_WUFIE;
+ } else {
/* Disable wake up from STOP mode. */
STM32_USART_CR1(UARTN_BASE) &= ~STM32_USART_CR1_UESM;
+ }
}
#else
static void enable_serial_wakeup(int enable)
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 37f907f9b8..fd1fc984f5 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -176,7 +176,7 @@
#define STM32_USART4_BASE 0x40004c00
#define STM32_USART_BASE(n) CONCAT3(STM32_USART, n, _BASE)
-#define STM32_USART_REG(base, offset) REG16((base) + (offset))
+#define STM32_USART_REG(base, offset) REG32((base) + (offset))
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
#define STM32_USART_CR1(base) STM32_USART_REG(base, 0x00)
@@ -190,9 +190,12 @@
#define STM32_USART_CR1_OVER8 (1 << 15)
#define STM32_USART_CR2(base) STM32_USART_REG(base, 0x04)
#define STM32_USART_CR3(base) STM32_USART_REG(base, 0x08)
+#define STM32_USART_CR3_EIE (1 << 0)
#define STM32_USART_CR3_DMAR (1 << 6)
#define STM32_USART_CR3_DMAT (1 << 7)
#define STM32_USART_CR3_ONEBIT (1 << 11)
+#define STM32_USART_CR3_WUS_START_BIT (2 << 20)
+#define STM32_USART_CR3_WUFIE (1 << 22)
#define STM32_USART_BRR(base) STM32_USART_REG(base, 0x0C)
#define STM32_USART_GTPR(base) STM32_USART_REG(base, 0x10)
#define STM32_USART_RTOR(base) STM32_USART_REG(base, 0x14)
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c
index 170f30a745..d0240966f2 100644
--- a/chip/stm32/uart.c
+++ b/chip/stm32/uart.c
@@ -282,6 +282,15 @@ void uart_init(void)
/* Configure GPIOs */
gpio_config_module(MODULE_UART, 1);
+#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+ /*
+ * Wake up on start bit detection. WUS can only be written when UE=0,
+ * so clear UE first.
+ */
+ STM32_USART_CR1(UARTN_BASE) &= ~STM32_USART_CR1_UE;
+ STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_WUS_START_BIT;
+#endif
+
/*
* UART enabled, 8 Data bits, oversampling x16, no parity,
* TX and RX enabled.
@@ -297,7 +306,9 @@ void uart_init(void)
STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_DMAT;
#else
/* DMA disabled, special modes disabled, error interrupt disabled */
- STM32_USART_CR3(UARTN_BASE) = 0x0000;
+ STM32_USART_CR3(UARTN_BASE) &= ~STM32_USART_CR3_DMAR &
+ ~STM32_USART_CR3_DMAT &
+ ~STM32_USART_CR3_EIE;
#endif
#ifdef CONFIG_UART_RX_DMA