cancel
Showing results for 
Search instead for 
Did you mean: 

compensating latencies on STM32F4 interrupts

xavier2399
Associate II
Posted on September 14, 2012 at 14:29

I'm working on a project on a STM32F4 CPU, generating signals (VGA) with DMA.

I have a generic timer on CPU clock (no prescaler) on a STM32 triggering interrupts on overflow, to generate a periodic signal with GPIO afterwards.

I need to trigger thr GPIO at a very regular time (basically down to a CPU cycle precision). I've managed to reduce this jitter to +-5 cycles by setting priorities & al, but this jitter exists, depending on what the CPU was doing and the interrupted instruction.

I need to compensate this few cycles jitter. Adding a few cycles more latency isn't a problem as long as I toggle GPIOs always at the same counter cycle.

My idea was to read the current value of the counter after the interrupt, and have an active loop of (FIXED_NUMBER-CNT->VAL) time, ensuring I would exit the loop at precise times.

However, doing a simple loop in C - being a FOR loop, or a while(counter->value < TARGET); doesn't work as it ADDS jitter instead of reducing it.

I ensured with empty, non optimized but not hitting memory loop body (asm(''''))

See this example on AVR (more predictable timings) See by example

http://lucidscience.com/pro-vga video generator-7.aspx

(search for ''jitter'')

I tried a simple loop in assembly such as (r0 has the number of cycles to wait to compensate counter value)

loop : SUBS r0,#1 ; tried with 2 also BGE loop 

and, again, jitter is better without it.

To sum it up, I already know how much I should delay. Unfortunately, branches alone don't seem to work (nondeterminisctic pipeline refill ?) and IT conditional expressions don't either because they always take the same number of cycles (sometimes doing nothing).

Would running from RAM instead of flash improve consistency ?

Maybe I'm out of my league here ... any help would appreciated, thanks! (crosspost from stackoverflow as I think I'd have more success here than there, sorry) #interrupts-counter
23 REPLIES 23
tim239955_stm1_stmicro
Associate II
Posted on January 30, 2013 at 03:53

Okay, I've monitored the timings with the scope, toggling a pin on and off ussing BSRRH/BSRL, and found the following:

1. The moment of endering the 1st interrupt (EXTI, falling edge of sync pulse, by design can be preempted by second interrupt) is really indeterministic, the window is ~10 CPU cycles.

2. Having simple loop cycle with fixed amount of loops in 1st interrupt allows the 2nd interrupt to kick at extremely deterministic time.

2nd interrupt is TIM3 CC1 interrupt, kicks in X TIM3 counter ticks after rising edge of hsync pulse. The pulse is falling edge, 4 usec, then raising edge.

The 2nd interrupt starts in 10nsec timeframe window, which is roughly 1 CPU clock cycle (CPU runs at 108 MHz in my case), which is perfect for my needs and I can't get better precision ebven theoretically 🙂

3. I had to remove any reads of the interrupt flags and any register/memory reads atr all and start shifting out immediatelly after TIM3 CC1 ISR starts.

 Reading the flags adds 2 CPU clock cycles to window of indeterministic behavior. So I just clear all the flags in the end of TIM3 CC1 ISR and it works perfect.

henryryq
Associate II
Posted on May 03, 2013 at 23:41

hello, 

can i use this DWT delay for grab the data from dht22 (temp/hum sensor) ?? or any another way to grab the data

thx

ricky

Posted on May 04, 2013 at 01:11

can i use this DWT delay for grab the data from dht22 (temp/hum sensor) ?? or any another way to grab the data

Probably, it has reasonably fine granularity, and predictability (sans interrupts). Signal placement can also be measured with a TIM in input capture mode, or using the DWT as a timestamp for transitions you watch on GPIO pins.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
henryryq
Associate II
Posted on May 27, 2013 at 10:40

thx for replay andsuggestion.

next question, any problem with my code?

/* data DHT 22*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE, GPIO_Pin_0);
EnableTiming();
Delay250Ms();
Delay250Ms();
GPIO_ResetBits(GPIOE, GPIO_Pin_0);
EnableTiming();
Delay500Us();
GPIO_SetBits(GPIOE, GPIO_Pin_0);
EnableTiming();
Delay40Us();
//Delay1500Ms(); // <------ this line what i mean
/* data DHT 22*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

focus on ''

<------ this line what i mean''

i dont have any data if i commend the line, but if uncommand the line the output pin do not change to input pin. any next suggestion, or any example if i choice to use

TIM in input capture mode...?

thx ricky
Posted on May 27, 2013 at 14:12

I wouldn't be calling

RCC_AHB1PeriphClockCmd

() and EnableTiming() multiple times. I'd be looking at the signal on a scope, confirm the timing, and compare it to a working implementation of a DHT22 reader, and the available documentation.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
henryryq
Associate II
Posted on May 27, 2013 at 14:52

thx for fast replay,

iam use scope too, its a reason why i know the DHT22 is respons the signal from uC. but if i change the pin from output to input, the data can visual on scope (logic ''0'').

suggest ? 

Posted on May 27, 2013 at 15:02

If you switch to an input, with a pull-up, and you are seeing a zero on the line it would be because the DHT22 is driving it there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
henryryq
Associate II
Posted on May 27, 2013 at 15:35

henryryq
Associate II
Posted on May 27, 2013 at 15:36

https://www.facebook.com/photo.php?fbid=10200596337445441&l=6c84729d63

it is the photo of scope and part of code like above.... i wish it can solve my problem
Posted on May 27, 2013 at 15:49

i wish it can solve my problem

I've never found wishing to be an effective debugging strategy.

Are you sure you want to be using GPIO_OType_PP, I'd think OD (Open Drain) mode would be far more effective for a single wire protocol.

You should be able to attach PNG images directly here, as well as larger file attachments. The images are a bit fuzzy.The one with modulated signal does not appear to get low enough to read a zero state.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..