using lptim1 to wake from stop2
Posted: Fri Mar 26, 2021 12:25 pm
This isn't an issue, more of a topic for more discussion. I've been building sub-gram dataloggers with stm32l4 processors for biologists studying songbirds. As you might image the biggest issue is energy -- getting a year out of a 5.5mAh battery is hard. A common use case is to power up a sensor, kick off a measurement and then wait for time to pass. During that waiting stop2 is ideal, the issue is waking. To do that I've been using the low power timer to trigger the wake up. Here's a code fragment illustrating how this works:
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
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