diff options
-rw-r--r-- | board/servo_micro/board.c | 10 | ||||
-rw-r--r-- | board/servo_micro/board.h | 4 | ||||
-rw-r--r-- | board/servo_v4/board.c | 9 | ||||
-rw-r--r-- | board/servo_v4/board.h | 4 | ||||
-rw-r--r-- | chip/stm32/registers-stm32f0.h | 14 | ||||
-rw-r--r-- | chip/stm32/registers.h | 1 | ||||
-rw-r--r-- | chip/stm32/system.c | 36 | ||||
-rw-r--r-- | include/config.h | 8 |
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 |