Thanks for putting this together… but this is pretty much just one of the examples from the G0 Software Framework, which I have already referenced. As far a I can tell, I’m already doing everything in this example, so I don’t know why it’s not working.
However, it doesn’t matter. I made my own shutdown mode! I manually turn off every clock I could find, disable the HSI48 and LSI manually, divide my HSI by 128 and then enter low power sleep mode. When I test that code against going into Shutdown mode, power consumption is approximately 1uA more, except I can wake up from standard EXTI interrupts and don’t have to rely purely on WKUP pins.
For anyone who stumbles across this and wants to get super low power, but wake up from EXTI interrupts (or events, I’m using events), here’s how to turn everything. (Note, depending on your chip and what you have initialized, your mileage may vary).
instance()->m_pUsbUtils->stop(); // This de-inits the USB code
HAL_SuspendTick();
HAL_ADC_Stop_DMA(&hadc1);
HAL_ADC_Stop_IT(&hadc1);
HAL_ADC_DeInit(&hadc1);
HAL_I2C_DeInit(&hi2c1);
HAL_I2C_DeInit(&hi2c2);
HAL_TIM_Base_MspDeInit(&htim2);
HAL_CRC_MspDeInit(&hcrc);
HAL_PWR_DisableBkUpAccess();
HAL_RTC_MspDeInit(&hrtc);
HAL_PWR_DisableSEVOnPend();
LL_UCPD_SetccEnable(UCPD1, LL_UCPD_CCENABLE_NONE);
LL_UCPD_TypeCDetectionCC1Disable(UCPD1);
LL_UCPD_TypeCDetectionCC2Disable(UCPD1);
LL_UCPD_RxDisable(UCPD1);
LL_UCPD_RxDMADisable(UCPD1);
LL_UCPD_Disable(UCPD1);
LL_UCPD_ForceClockDisable(UCPD1);
HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
// Disable ALL PINS
utl::STM32::ConfigureAnalog(GPIOA, GPIO_PIN_All);
utl::STM32::ConfigureAnalog(GPIOB, GPIO_PIN_All);
utl::STM32::ConfigureAnalog(GPIOC, GPIO_PIN_All);
utl::STM32::ConfigureAnalog(GPIOD, GPIO_PIN_All);
// Configure wakeup source
GPIO_InitTypeDef GPIO_InitStruct = {};
GPIO_InitStruct.Pin = nDisplay_Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(nDisplay_Button_GPIO_Port, &GPIO_InitStruct);
// Disable lots of clocks
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_ALL);
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_ALL);
LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_CRC);
LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_DMA1);
LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_DMA2);
LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOA);
LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOC);
LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOD);
LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOF);
LL_AHB1_GRP1_DisableClockStopSleep(LL_AHB1_GRP1_PERIPH_ALL);
HAL_PWREx_EnablePORMonitorSampling();
HAL_PWREx_DisableInternalWakeUpLine();
HAL_PWREx_DisableSRAMRetention();
HAL_PWREx_DisablePVD();
HAL_PWREx_DisablePVMUSB();
HAL_PWREx_DisableVddUSB();
HAL_PWREx_DisableVddIO2();
__HAL_RCC_SYSCFG_CLK_DISABLE();
__HAL_RCC_PWR_CLK_DISABLE();
__HAL_RCC_RTCAPB_CLK_DISABLE();
__HAL_RCC_HSI48_DISABLE();
__HAL_RCC_LSI_DISABLE();
LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_SRAM);
// Drop system clock speed
__HAL_RCC_HSI_CONFIG(RCC_HSI_DIV128);
SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFE);
HAL_NVIC_SystemReset();