Page 2 of 2

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

Posted: Wed Feb 28, 2024 4:11 pm
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.

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

Posted: Wed Feb 28, 2024 5:54 pm
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.

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

Posted: Wed Feb 28, 2024 6:09 pm
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.

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

Posted: Wed Feb 28, 2024 6:40 pm
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).

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

Posted: Wed Feb 28, 2024 9:07 pm
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.

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

Posted: Wed Feb 28, 2024 11:32 pm
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
}

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

Posted: Wed Feb 28, 2024 11:37 pm
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.

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

Posted: Thu Feb 29, 2024 12:08 am
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+).

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

Posted: Thu Feb 29, 2024 1:48 am
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.

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

Posted: Thu Feb 29, 2024 1:15 pm
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.