summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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