diff --git a/firmware/config/boards/proteus/board_configuration.cpp b/firmware/config/boards/proteus/board_configuration.cpp index 5c56db2a19..eef37b5c49 100644 --- a/firmware/config/boards/proteus/board_configuration.cpp +++ b/firmware/config/boards/proteus/board_configuration.cpp @@ -216,3 +216,26 @@ void setBoardDefaultConfiguration(void) { engineConfiguration->triggerSimulatorPins[1] = GPIOG_2; #endif } + +void boardPrepareForStop() { + // enable EXTI on PD0 - CAN RX pin + palSetPadMode(GPIOD, 0, PAL_MODE_INPUT); + palEnableLineEvent(PAL_LINE(GPIOD, 0), PAL_EVENT_MODE_RISING_EDGE); +} + +void boardPrepareForStandby() { + // We're out of luck trying to wake from standby on an F4, since it can only wake from PA0 + +#ifdef STM32F7XX + PWR->CSR2 |= PWR_CSR2_EWUP1; //EWUP1: Enable Wakeup pin for PA0 + PWR->CR2 |= PWR_CR2_CWUPF1; //Clear Wakeup Pin flag for PA0 +#endif + +#ifdef STM32H7XX + // Wake on wakeup pin 0 - PA0 + PWR->WKUPEPR = PWR_WKUPEPR_WKUPEN1; + + // clear all possible wakeup bits + PWR->WKUPCR = 0xFFFFFFFF; +#endif +} diff --git a/firmware/hw_layer/ports/stm32/port_mpu_util.h b/firmware/hw_layer/ports/stm32/port_mpu_util.h index 6000f1fbc2..8972dcd517 100644 --- a/firmware/hw_layer/ports/stm32/port_mpu_util.h +++ b/firmware/hw_layer/ports/stm32/port_mpu_util.h @@ -67,4 +67,10 @@ typedef enum { #ifdef __cplusplus void stm32_stop(); void stm32_standby(); + +// Called just before the MCU is put in stop mode +void boardPrepareForStop(); + +// Called just before the MCU is put in standby mode +void boardPrepareForStandby(); #endif diff --git a/firmware/hw_layer/ports/stm32/stm32_common.cpp b/firmware/hw_layer/ports/stm32/stm32_common.cpp index 7c7ca5ad32..f9e287ba9f 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_common.cpp @@ -796,4 +796,12 @@ CANDriver* detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx) { #endif /* EFI_CAN_SUPPORT */ +// Stubs for per-board low power helpers +__attribute__((weak)) void boardPrepareForStop() { + // Default implementation - wake up on PA0 - boards should override this + palEnableLineEvent(PAL_LINE(GPIOA, 0), PAL_EVENT_MODE_RISING_EDGE); +} + +__attribute__((weak)) void boardPrepareForStandby() { } + #endif // EFI_PROD_CODE diff --git a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp index 547814bec3..2b9fe19e86 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp +++ b/firmware/hw_layer/ports/stm32/stm32f7/mpu_util.cpp @@ -178,13 +178,15 @@ void sys_dual_bank(void) { void stm32_stop() { SysTick->CTRL = 0; SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // Turn off the LEDs, those use some power enginePins.errorLedPin.setValue(0); enginePins.runningLedPin.setValue(0); enginePins.communicationLedPin.setValue(0); enginePins.warningLedPin.setValue(0); - - palEnableLineEvent(PAL_LINE(GPIOA, 0), PAL_EVENT_MODE_RISING_EDGE); + // Do anything the board wants to prepare for stop mode - enabling wakeup sources! + boardPrepareForStop(); PWR->CSR1 |= PWR_CSR1_WUIF; PWR->CR1 &= ~PWR_CR1_PDDS; // cleared PDDS means stop mode (not standby) @@ -204,10 +206,12 @@ void stm32_stop() { void stm32_standby() { SysTick->CTRL = 0; SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - PWR->CR1 |= PWR_CR1_PDDS; // PDDS = use standby mode (not stop mode) - PWR->CSR2 |= PWR_CSR2_EWUP1; //EWUP1: Enable Wakeup pin for PA0 - PWR->CR2 |= PWR_CR2_CWUPF1; //Clear Wakeup Pin flag for PA0 - PWR->CR1 |= PWR_CR1_CSBF; //Clear standby flag + PWR->CR1 |= PWR_CR1_PDDS; // PDDS = use standby mode (not stop mode) + PWR->CR1 |= PWR_CR1_CSBF; // Clear standby flag + + // Do anything the board wants to prepare for standby mode - enabling wakeup sources! + boardPrepareForStandby(); + __disable_irq(); __WFI(); }