2020-08-07 08:34 AM
Hello,
my STM32L011's core is running at 32 MHz. I use systick for 1 ms interrupt. However, if i try to use the WFI inside my while loop in my delay function, the timebase changes from 1 ms to 6.28 ms. Any help is appreciated!
#include "user_systick.h"
volatile uint32_t coefficient_ms;
volatile uint32_t sys_ticks;
void SysTick_Handler(void){
sys_ticks++;
}
void user_systick_init(void){
coefficient_ms = 32000000 / 1000;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
}
void user_systick_start(void){
NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
}
void user_systick_stop(void){
SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
}
void user_systick_wait_ms(uint32_t delay_value){
SysTick->LOAD = (uint32_t)(coefficient_ms - 1UL);
SysTick->VAL = 1;
sys_ticks = 0;
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
while(sys_ticks < delay_value){
//__WFI(); //If I uncomment this, I get a 6.28 ms timebase which is wrong.
}
}
2020-08-07 09:26 AM
Try
__DSB();
__WFI();
__ISB();
Also it seems odd that the wait function starts the systick but doesn't call user_systick_start(), which doesn't start the systick. It also seems odd that the wait function doesn't stop the systick at the end.
2020-08-07 09:27 AM
OK, I found my problem - elsewhere in my code I was using:
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_ULP;
so before calling my user_systick_wait_ms( ) I put:
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= ~PWR_CR_ULP;
RCC->APB1ENR &= ~RCC_APB1ENR_PWREN;
This solved that issue.
Regards,
L. B.
2020-08-10 01:37 AM
I need the systick functionality only in certain parts of my code. The start function enables this functionality and the stop function disables it. The delay function does the actual blocking delay. If I had put the start functionality inside the delay, it would have been called every time when I called the delay. Time is power. I need low power firmware.
2020-08-10 06:09 AM
As it stands, the code allows SysTick interrupts every millisecond when they aren't being used. I think you could save some power by disabling the SysTick when you're not using it.
2020-08-10 06:57 AM
Oh, I've made a mistake, actually my code is like that:
#include "user_systick.h"
volatile uint32_t coefficient_ms;
volatile uint32_t sys_ticks;
void SysTick_Handler(void){
sys_ticks++;
}
void user_systick_init(void){
coefficient_ms = 32000000 / 1000;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
}
void user_systick_start(void){
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}
void user_systick_stop(void){
SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
}
void user_systick_wait_ms(uint32_t delay_value){
SysTick->LOAD = (uint32_t)(coefficient_ms - 1UL);
SysTick->VAL = 1;
sys_ticks = 0;
while(sys_ticks < delay_value){ }
}
And I'm using it like that:
user_systick_start();
user_systick_wait_ms(50);
....
user_systick_stop();