summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian J. Nemec <bnemec@chromium.org>2019-11-11 23:51:35 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-07 22:20:18 +0000
commite18c87761b40ef1aabc6d7c0fda3fd1c64f343f4 (patch)
treedbb539e237d0f039d49289ccbc92c460d06dff4e
parentfe271c67d2b690014e347cb7cddde2a1f8ac3017 (diff)
downloadchrome-ec-e18c87761b40ef1aabc6d7c0fda3fd1c64f343f4.tar.gz
ServoMicro: Enable Brownout detection with PVD circuit
Enables the programmable voltage detector (PVD) interrupt in ServoMicro. This interrupt fires when the supply voltage drops from the expected 3.3V to under 2.3V after power on. This gives several hundred microseconds of time for the device to respond to the power reduction. In order to ensure that the ServoMicro does not enter a non-responsive state, it triggers a reboot of the system to restore it to a good configuration. BRANCH=servo BUG=chromium:1023715 TEST=Configured GPIO output to trigger on pvd_interrupt() and verified the interrupt fires during the following situations using Saleae analyzer: * USB Power removed from working device * Ramping supply voltage from 1.5V to 5V with a DC supply * Repoducing failure condition from crbug/1016051 1 Connect ServoMicro to Cyan board 2 dut-control power_state:on 3 dut-control fw_wp_vref:pp3300 4 dut-control power_state:off 5 GPIO toggles and system reset occurs Change-Id: I721f48ab84b01d52a5f98747cc9d879ff2876a07 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1911759 Reviewed-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org> Tested-by: Brian Nemec <bnemec@chromium.org> Commit-Queue: Brian Nemec <bnemec@chromium.org> Auto-Submit: Brian Nemec <bnemec@chromium.org> (cherry picked from commit 771dd33b149fb94725edf0e29670207b9a013cb6) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2044707 Reviewed-by: Brian Nemec <bnemec@google.com> Commit-Queue: Brian Nemec <bnemec@google.com> Tested-by: Brian Nemec <bnemec@google.com>
-rw-r--r--board/servo_micro/board.c10
-rw-r--r--board/servo_micro/board.h4
-rw-r--r--board/servo_v4/board.c9
-rw-r--r--board/servo_v4/board.h4
-rw-r--r--chip/stm32/registers-stm32f0.h14
-rw-r--r--chip/stm32/registers.h1
-rw-r--r--chip/stm32/system.c36
-rw-r--r--include/config.h8
8 files changed, 82 insertions, 4 deletions
diff --git a/board/servo_micro/board.c b/board/servo_micro/board.c
index 6524b31442..d8611fd493 100644
--- a/board/servo_micro/board.c
+++ b/board/servo_micro/board.c
@@ -13,6 +13,7 @@
#include "queue_policies.h"
#include "registers.h"
#include "spi.h"
+#include "system.h"
#include "task.h"
#include "timer.h"
#include "update_fw.h"
@@ -673,6 +674,15 @@ const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
int usb_i2c_board_is_enabled(void) { return 1; }
+void pvd_interrupt(void) {
+ /* Clear Pending Register */
+ STM32_EXTI_PR = EXTI_PVD_EVENT;
+ /* Handle recovery by rebooting the system */
+ system_reset(0);
+}
+
+DECLARE_IRQ(STM32_IRQ_PVD, pvd_interrupt, HOOK_PRIO_FIRST);
+
/******************************************************************************
* Initialize board.
*/
diff --git a/board/servo_micro/board.h b/board/servo_micro/board.h
index 99fa722fb4..9a0ca5824d 100644
--- a/board/servo_micro/board.h
+++ b/board/servo_micro/board.h
@@ -32,6 +32,10 @@
/* Optional features */
#define CONFIG_STM_HWTIMER32
#define CONFIG_HW_CRC
+#define CONFIG_PVD
+/* See 'Programmable voltage detector characteristics' in the STM32F072x8 Datasheet.
+ PVD Threshold 1 corresponds to a falling voltage threshold of min:2.09V, max:2.27V. */
+#define PVD_THRESHOLD (1)
/* USB Configuration */
#define CONFIG_USB
diff --git a/board/servo_v4/board.c b/board/servo_v4/board.c
index bf1c51e267..7661cee20c 100644
--- a/board/servo_v4/board.c
+++ b/board/servo_v4/board.c
@@ -410,6 +410,15 @@ int board_get_version(void)
return ver;
}
+void pvd_interrupt(void) {
+ /* Clear Pending Register */
+ STM32_EXTI_PR = EXTI_PVD_EVENT;
+ /* Handle recovery by rebooting the system */
+ system_reset(0);
+}
+
+DECLARE_IRQ(STM32_IRQ_PVD, pvd_interrupt, HOOK_PRIO_FIRST);
+
static void board_init(void)
{
/* USB to serial queues */
diff --git a/board/servo_v4/board.h b/board/servo_v4/board.h
index 274aa8d6a8..ff46ae13e4 100644
--- a/board/servo_v4/board.h
+++ b/board/servo_v4/board.h
@@ -32,6 +32,10 @@
/* Optional features */
#define CONFIG_STM_HWTIMER32
#define CONFIG_HW_CRC
+#define CONFIG_PVD
+/* See 'Programmable voltage detector characteristics' in the STM32F072x8 Datasheet.
+ PVD Threshold 1 corresponds to a falling voltage threshold of min:2.09V, max:2.27V. */
+#define PVD_THRESHOLD (1)
/* USB Configuration */
#define CONFIG_USB
diff --git a/chip/stm32/registers-stm32f0.h b/chip/stm32/registers-stm32f0.h
index 72d3cdb7a6..442edaed9a 100644
--- a/chip/stm32/registers-stm32f0.h
+++ b/chip/stm32/registers-stm32f0.h
@@ -277,6 +277,11 @@
/* --- Power / Reset / Clocks --- */
+#define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00)
+#define STM32_PWD_PVD_LS_MASK (0x07 << 5)
+#define STM32_PWD_PVD_LS(n) ((n & 0x07) << 5)
+#define STM32_PWR_PVDE BIT(4)
+
#define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04)
#define STM32_PWR_CSR_EWUP1 BIT(8)
@@ -382,8 +387,8 @@
#define RESET_CAUSE_OTHER 0xfe000000
#define RESET_CAUSE_RMVF 0x01000000
/* Power cause in PWR CSR register */
-#define STM32_PWR_RESET_CAUSE STM32_PWR_CSR
-#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CR
+#define STM32_PWR_RESET_CAUSE STM32_PWR_CSR
+#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CR
#define RESET_CAUSE_SBF 0x00000002
#define RESET_CAUSE_SBF_CLR 0x00000004
@@ -528,8 +533,9 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_EXTI_SWIER REG32(STM32_EXTI_BASE + 0x10)
#define STM32_EXTI_PR REG32(STM32_EXTI_BASE + 0x14)
-#define EXTI_RTC_ALR_EVENT BIT(17)
-#define EXTI_COMP2_EVENT BIT(22)
+#define EXTI_PVD_EVENT BIT(16)
+#define EXTI_RTC_ALR_EVENT BIT(17)
+#define EXTI_COMP2_EVENT BIT(22)
/* --- ADC --- */
#define STM32_ADC_ISR REG32(STM32_ADC1_BASE + 0x00)
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 08b9d61e20..5926dda278 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -229,6 +229,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_PB1_USART3 BIT(18)
#define STM32_RCC_PB1_USART4 BIT(19)
#define STM32_RCC_PB1_USART5 BIT(20)
+#define STM32_RCC_PB1_PWREN BIT(28)
#define STM32_RCC_PB2_SPI1 BIT(12)
/* Reset causes definitions */
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index 4b0dada71d..3f08e4ef80 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -271,6 +271,38 @@ void chip_pre_init(void)
STM32_DBGMCU_APB2FZ |= apb2fz_reg;
}
+#ifdef CONFIG_PVD
+/* Configures the programmable voltage detector to monitor for brown out conditions. */
+static void configure_pvd(void)
+{
+ /* Clear Interrupt Enable Mask Register. */
+ STM32_EXTI_IMR &= ~EXTI_PVD_EVENT;
+
+ /* Clear Rising and Falling Trigger Selection Registers. */
+ STM32_EXTI_RTSR &= ~EXTI_PVD_EVENT;
+ STM32_EXTI_FTSR &= ~EXTI_PVD_EVENT;
+
+ /* Clear the value of the PVD Level Selection. */
+ STM32_PWR_CR &= ~STM32_PWD_PVD_LS_MASK;
+
+ /* Set the new value of the PVD Level Selection. */
+ STM32_PWR_CR |= STM32_PWD_PVD_LS(PVD_THRESHOLD);
+
+ /* Enable Power Clock. */
+ STM32_RCC_APB1ENR |= STM32_RCC_PB1_PWREN;
+
+ /* Configure the NVIC for PVD. */
+ task_enable_irq(STM32_IRQ_PVD);
+
+ /* Configure interrupt mode. */
+ STM32_EXTI_IMR |= EXTI_PVD_EVENT;
+ STM32_EXTI_RTSR |= EXTI_PVD_EVENT;
+
+ /* Enable the PVD Output. */
+ STM32_PWR_CR |= STM32_PWR_PVDE;
+}
+#endif
+
void system_pre_init(void)
{
#ifdef CONFIG_SOFTWARE_PANIC
@@ -349,6 +381,10 @@ void system_pre_init(void)
bkpdata_write(BKPDATA_INDEX_SAVED_PANIC_EXCEPTION, 0);
}
#endif
+
+#ifdef CONFIG_PVD
+ configure_pvd();
+#endif
}
void system_reset(int flags)
diff --git a/include/config.h b/include/config.h
index 6d34b5e5aa..ab6a60e8df 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3009,6 +3009,14 @@
*/
#undef CONFIG_CPU_PROCHOT_ACTIVE_LOW
+/*
+ * Define this option to enable programmable voltage detector which will
+ * trigger an interrupt when the voltage drops below a threshold specified
+ * by the PVD_THRESHOLD which is a chip specific voltage threshold that
+ * must be defined in board.h.
+ */
+#undef CONFIG_PVD
+
/*****************************************************************************/
/* Support PWM control */
#undef CONFIG_PWM