From 048017e07a1ca47a89a7debc8016d831c2261aef Mon Sep 17 00:00:00 2001 From: Jaroslav Malec Date: Sat, 24 Apr 2021 20:35:13 +0200 Subject: [PATCH] Add theoretical-ish ALARM handling --- fw/rbcx-coprocessor/include/Bsp_v10.hpp | 6 ++--- fw/rbcx-coprocessor/include/Bsp_v11.hpp | 6 ++--- fw/rbcx-coprocessor/platformio.ini | 2 +- fw/rbcx-coprocessor/src/Power.cpp | 29 +++++++++++++++++++---- fw/rbcx-coprocessor/src/RtcController.cpp | 21 ++++++++++++++-- fw/rbcx-coprocessor/src/main.cpp | 14 +++++++---- 6 files changed, 60 insertions(+), 18 deletions(-) diff --git a/fw/rbcx-coprocessor/include/Bsp_v10.hpp b/fw/rbcx-coprocessor/include/Bsp_v10.hpp index e0a149e0..3811076a 100644 --- a/fw/rbcx-coprocessor/include/Bsp_v10.hpp +++ b/fw/rbcx-coprocessor/include/Bsp_v10.hpp @@ -178,10 +178,10 @@ inline void reinitEspStrappingPins() { } inline void pinsInit() { - pinInit(ledPins, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + // pinInit(ledPins, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); - pinWrite(powerPin, 1); - pinInit(powerPin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + // pinWrite(powerPin, 1); + // pinInit(powerPin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); for (auto button : buttonPin) pinInit(button, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_LOW); diff --git a/fw/rbcx-coprocessor/include/Bsp_v11.hpp b/fw/rbcx-coprocessor/include/Bsp_v11.hpp index 3aaf6b03..eca95121 100644 --- a/fw/rbcx-coprocessor/include/Bsp_v11.hpp +++ b/fw/rbcx-coprocessor/include/Bsp_v11.hpp @@ -175,10 +175,10 @@ inline void reinitEspStrappingPins() { } inline void pinsInit() { - pinInit(ledPins, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + // pinInit(ledPins, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); - pinWrite(powerPin, 1); - pinInit(powerPin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + // pinWrite(powerPin, 1); + // pinInit(powerPin, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); for (auto button : buttonPin) pinInit(button, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_LOW); diff --git a/fw/rbcx-coprocessor/platformio.ini b/fw/rbcx-coprocessor/platformio.ini index c340d2af..87ce69ba 100644 --- a/fw/rbcx-coprocessor/platformio.ini +++ b/fw/rbcx-coprocessor/platformio.ini @@ -17,7 +17,7 @@ platform = ststm32@~7.0.0 board = genericSTM32F103VC framework = stm32cube lib_deps = - https://github.com/RoboticsBrno/RB3204-RBCX-coproc-comm/archive/fa79ee92b39527ac0ff988277efaa71a09e9cad3.zip + https://github.com/RoboticsBrno/RB3204-RBCX-coproc-comm/archive/81dae0effc201174b9e55c9702d58f80d51b720b.zip build_flags = -Iinclude diff --git a/fw/rbcx-coprocessor/src/Power.cpp b/fw/rbcx-coprocessor/src/Power.cpp index a8243eee..0a028abc 100644 --- a/fw/rbcx-coprocessor/src/Power.cpp +++ b/fw/rbcx-coprocessor/src/Power.cpp @@ -107,33 +107,52 @@ extern "C" void PVD_IRQHandler() { pinWrite(powerPin, 0); // Blink red LED "pretty fast" + // Only blink for a limited time because we don't want to cause a denial of service + // if we're powered from a different source (which?) uint32_t leds = 0; - while (true) { + for (int blink = 0; blink < 10; blink++) { leds ^= CoprocReq_LedsEnum_L3; setLeds(leds); for (volatile int i = 0; i < 200000; i++) ; } + + // Reset program if power still present (powered from elsewhere) + HAL_NVIC_SystemReset(); } void powerEarlyInit() { + pinWrite(powerPin, true); __HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_BKP_CLK_ENABLE(); - // Enable PVD - will generate EXTI16(PVD_IRQn) when VDD drops. - // Done before disabling ALARM output to eliminate race + // Enable PVD - we want EXTI16(PVD_IRQn) interrupt when VDD drops. + // Enabled before disabling ALARM output to eliminate race // that could result in ALARM deactivation. LL_PWR_EnableBkUpAccess(); - LL_PWR_SetPVDLevel(LL_PWR_PVDLEVEL_7); + // Level 7 is the highest and seems too intolerant. + LL_PWR_SetPVDLevel(LL_PWR_PVDLEVEL_4); LL_PWR_EnablePVD(); + setLeds(0x1); + + // Attempt to survive a transient power-up period when PVD output may fluctuate. + while (LL_PWR_IsActiveFlag_PVDO()) + ; + __HAL_PWR_PVD_EXTI_CLEAR_FLAG(); + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); + __HAL_PWR_PVD_EXTI_ENABLE_IT(); + + HAL_NVIC_ClearPendingIRQ(PVD_IRQn); HAL_NVIC_SetPriority(PVD_IRQn, 0, 0); HAL_NVIC_EnableIRQ(PVD_IRQn); + setLeds(0x3); + // Disable potential RTC ALARM -> powerPin override. // This way we keep VCC powered upon board power-up. - // This must be done very early at power-up. + // This must be done early at power-up. LL_RTC_SetOutputSource(BKP, LL_RTC_CALIB_OUTPUT_NONE); } diff --git a/fw/rbcx-coprocessor/src/RtcController.cpp b/fw/rbcx-coprocessor/src/RtcController.cpp index 0a832787..facaed72 100644 --- a/fw/rbcx-coprocessor/src/RtcController.cpp +++ b/fw/rbcx-coprocessor/src/RtcController.cpp @@ -8,13 +8,25 @@ #include "stm32f1xx_ll_rtc.h" static void ensureInitialized() { - // Ensure RTC is running (noop in case it is) + // We use DR3 to indicate that RTC was already initialized in a prior life. + bool initialized = LL_RTC_BKP_GetRegister(BKP, LL_RTC_BKP_DR3); + if (initialized) { + // RTC clock selected signifies RTC already initialized. + return; + } + + while (!LL_RCC_LSE_IsReady()) { + } + LL_RTC_InitTypeDef init = { .AsynchPrescaler = 0x7FFF, // 32kHz crystal -> 1s tick .OutPutSource = LL_RTC_CALIB_OUTPUT_NONE, }; + LL_RCC_EnableRTC(); + LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); LL_RTC_Init(RTC, &init); + LL_RTC_BKP_SetRegister(BKP, LL_RTC_BKP_DR3, 0x1); } void rtcInit() { @@ -27,13 +39,17 @@ void rtcInit() { bool rtcInitReady() { return LL_RCC_LSE_IsReady(); } +uint32_t rtcFlags() { + return (!rtcInitReady()) | (LL_RTC_IsActiveFlag_ALR(RTC) << 1); +} + static void sendStatus() { CoprocStat status; status.which_payload = CoprocStat_rtcStat_tag, status.payload.rtcStat = CoprocStat_RtcStat { .time = rtcGetTime(), .alarm = rtcGetAlarm(), - .notReady = !rtcInitReady(), + .flags = CoprocStat_RtcFlags(rtcFlags()), }; controlLinkTx(status); } @@ -74,6 +90,7 @@ uint32_t rtcGetAlarm() { void rtcSetAlarm(uint32_t seconds) { ensureInitialized(); + LL_RTC_ClearFlag_ALR(RTC); LL_RTC_ALARM_SetCounter(RTC, seconds); // We mirror the value into DR1 and DR2 16-bit regs diff --git a/fw/rbcx-coprocessor/src/main.cpp b/fw/rbcx-coprocessor/src/main.cpp index 54dc5a82..b924d134 100644 --- a/fw/rbcx-coprocessor/src/main.cpp +++ b/fw/rbcx-coprocessor/src/main.cpp @@ -23,14 +23,20 @@ static TaskWrapper<3072> mainTask; int main() { - powerEarlyInit(); - clocksInit(); - HAL_Init(); - #ifdef RBCX_VECT_TAB_OFFSET SCB->VTOR = FLASH_BASE | RBCX_VECT_TAB_OFFSET; #endif + // Allow POWER and LEDs drive in powerEarlyInit + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + pinInit(powerPin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + pinInit(ledPins, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); + + powerEarlyInit(); + clocksInit(); + HAL_Init(); + pinsInit(); mainTask.start("main", 1, []() {