Code: Select all
// enable lptim1
// Enter Stop2 mode
RCC->APB1ENR1 |= (1 << 31);
LPTIM1->CR = 1;
// Set up compare,count registers
LPTIM1->ARR = ms + 1;
LPTIM1->CMP = ms; // set compare register
LPTIM1->CNT = 0; // reset counter
// enable external event
EXTI->EMR2 |= STM32_EXT_LPTIM1_LINE;
// enable interrupts in lptim1
LPTIM1->IER = STM32_LPTIM_IER_CMPMIE;
LPTIM1->CFGR = 0;
// Start the counter in single mode
LPTIM1->CR |= STM32_LPTIM_CR_SNGSTRT;
// go into stop2 mode
DBGMCU->CR = 0;
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP2);
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
__SEV();
__WFE();
__WFE();
// disable lptim and interrupt/event
EXTI->EMR2 &= ~STM32_EXT_LPTIM1_LINE;
LPTIM1->IER = 0;
LPTIM1->ICR = 1;
LPTIM1->CR = 0;
RCC->APB1ENR1 &= ~(1 << 31);
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
I should note that stop2 isn't perfect. I've found it necessary to disable/enable the SPI device before entering stop2. For reasons that I don't understand, i2c doesn't seem to require this. Also, I don't use the HAL spi driver with dma and all that -- in my application, the small amount of data transferred doesn't justify the overhead of setting up dma.
This seems to be a useful technique, but I admit my approach is completely ad-hoc and ripe for improvements
Geoffrey