STM32 hangs when >100khz signal applied to input

Post here first, or if you can't find a relevant section!
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

OK. here is a quick test on a PY32F002A - the numbers would be similar, if not identical, on other chips.

I used TIM1 overflow as a test interrupt

Code: Select all

	tmr1Init(1); tmr1OVFAttachISR(pwm_tks);
pwm_tks() is structured as:

Code: Select all

void pwm_tks(void) {
	t1 = TIM1->CNT;									//read the counter
	pwm_t2 = TIM1->CCR1;								//save the capture
	pwm_pr = pwm_t2 - pwm_t0;						//calculate pwm period
	pwm_dc = pwm_t1 - pwm_t0;						//calculate pwm duty cycle
	pwm_t0 = pwm_t2;								//update pwm rising edge
	pwm_flg= 1;										//setup the pwm flag
	t2 = TIM1->CNT;									//time stamp t2
}
I then printed out t0 (should always be zero), t1 (~52 - 53) and t2 (103 - 104).

t1 is a little bit on the high side - it is measuring the first user instruction executed, not true isr latency as I have some fluff in the isr:

Code: Select all

//isr for timer1 ovf
void TIM1_BRK_UP_TRG_COM_IRQHandler(void) {
	//t1 = TIM1->CNT;
	//tmr1 ovf isr
	if (TIM1->SR & TIM_SR_UIF) {TIM1->SR &=~TIM_SR_UIF; _tim1_ovfisrptr();}
}
so if I uncomment "t1 = TIM1->CNT;", and re-run the code, t1 goes down to 23 - 25.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

I looked up ARM's documentation and it says that CM0 isr latency can be as low as 16 ticks (vs. low 20s I got), and CM3 isr latency can be as low as 12 ticks.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

I looked up ARM's documentation and it says that CM0 isr latency can be as low as 16 ticks (vs. low 20s I got), and CM3 isr latency can be as low as 12 ticks.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

I then printed out t0 (should always be zero), t1 (~52 - 53) and t2 (103 - 104).
the equivalent of those numbers on a dsPIC33 (I happened to have it in front of me) would be t0 (always 0), t1 (~21), and t2 (~37).
ozcar
Posts: 143
Joined: Wed Apr 29, 2020 9:07 pm
Answers: 5

Re: STM32 hangs when >100khz signal applied to input

Post by ozcar »

dannyf wrote: Wed Feb 28, 2024 3:56 pm
for around 5µs
that's too long. your ISR overhead will be 20 ticks. Hard to imagine this thing goes over 100 ticks end-to-end. I will do some testing later on as well.
I would be interested to see what you find. I've done tests like that before, and the result is not out of line with what I have seen before. Well, in one thread here the total "out to lunch" time was measured at around 600ns, but that was on a 168MHz F407, and not actually using STM32DUINO! (viewtopic.php?t=357&start=20)

I tried again now to measure it a different way which does not need a DSO, and I got a time of around 4.9µs compiled with optimisation Os, and around 4.4µs with O3.

I did find that the mainline code does not get totally locked out until a much higher frequency than the "out to lunch" time alone would indicate though.

BTW, I found a way to eliminate the falling edge interrupt. All it takes is to move the HardwareTimer attachInterrupt to after the resume(), like this:

Code: Select all

  FRQ = new HardwareTimer(FR);
  FRQ->setMode(channelRising, TIMER_INPUT_FREQ_DUTY_MEASUREMENT, anpin);
  uint32_t PrescalerFactor = 1;
  FRQ->setPrescaleFactor(PrescalerFactor);
  FRQ->setOverflow(0x10000); // Max Period value to have the largest possible time to detect rising edge and avoid timer rollover
  FRQ->resume();
  FRQ->attachInterrupt(channelRising, TIMINPUT_Capture_Rising_IT_callback);
  input_freq = FRQ->getTimerClkFreq() / FRQ->getPrescaleFactor();
I still don't know why the resume() code does what I found there.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

to further speed up the isr execution, you can move the pwm period / dc calculation out of the isr and into the main loop -> it has its own downside but I was able to reduce the isr execution time from just over 100 ticks to just shy of 70 ticks, inclusive of the isr latency.

Code: Select all

void pwm_tks(void) {
	//t1 = TIM1->CNT;									//read the counter
	pwm_t2 = TIM1->CCR1;								//save the capture
	//pwm_pr = pwm_t2 - pwm_t0;						//calculate pwm period
	//pwm_dc = pwm_t1 - pwm_t0;						//calculate pwm duty cycle
	//pwm_t0 = pwm_t2;								//update pwm rising edge
	pwm_flg= 1;										//setup the pwm flag
	t2 = TIM1->CNT;									//time stamp t2
}
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

I would be interested to see what you find.
a couple differences that I can see:
1. my code doesn't rely on the stm32duino core(s): it uses a version of stm32duino-like core that I wrote myself and it is very lightweight and much faster.
2. in my test, I even pared down my code base to a customized version of the isr: i often use a pointer to a function in the isr for callback but for speed reasons i didn't go down that route.

still, 5us = 300+ instructions on this chip. I will try something later on to see if I can replicate that on my stm32f103.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

so if I uncomment "t1 = TIM1->CNT;", and re-run the code, t1 goes down to 23 - 25.
I tested on a stm32f103:

t0: always 0-> isr is triggered when the TIM1 rolls over to 0.
t1: 19 ticks. quite close to the ARM specification (of 12 ticks minimum).
t2: 133 ticks. meaningfully above my estimate earlier. and considerably higher than the 107 ticks for PY32F002A (CM0+).
ozcar
Posts: 143
Joined: Wed Apr 29, 2020 9:07 pm
Answers: 5

Re: STM32 hangs when >100khz signal applied to input

Post by ozcar »

Dannyf, I missed your updates on the second page previously.

It is a very different situation if you can avoid the STM32DUINO and maybe HAL code as well, but this could be easier said than done depending on what other parts of STM32DUINO need to be used in the final project. Maybe your "cut down" version would be OK.

Funguamongu has not come back to spell out the requirements, but there are probably many ways forward. Is it really necessary to measure each and every cycle of the waveform? As it stands, the loop() routine prints the last calculated results only twice per second. With a say 20kHz signal, that means 9999 measurements out of 10000 are just discarded. A "one-shot" measurement might be possible instead.
dannyf
Posts: 446
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 hangs when >100khz signal applied to input

Post by dannyf »

but this could be easier said than done depending on what other parts of STM32DUINO need to be used in the final project.
even when you use stm32duino cores, you can still write your own isr routines and toggle register bits...
Is it really necessary to measure each and every cycle of the waveform?
I think that's an excellent question. many ways to do this:
1. you can split this into counting frequencies -> which can be done easily; or measuring the duty cycle -> which can be done easily via adc for example.
2. or to use input filters...
...

but if coded carefully, this can be done on a stm32 -> something like this is done routinely on lower-spec 8-bit MCUs.
Post Reply

Return to “General discussion”