cancel
Showing results for 
Search instead for 
Did you mean: 

Building 0s/03 doubles timer speed?

mwp
Senior
Posted on January 24, 2013 at 14:48

Hi all,

My TIM3 timer is setup to run at 10Khz which it does when i compile with -O0.

When i compile with -03 or -Os, the timer speed increases to 20khz.

All other build configs (gcc, linker, libs, etc) stay the same.

The compiler is ''arm-none-eabi-gcc (Sourcery CodeBench Lite 2012.03-56) 4.6.3''.

Can anyone hazard a guess as to why this might happen?

Ive looked at everything i can think of with no result.

Thanks!!
7 REPLIES 7
Posted on January 24, 2013 at 15:02

Which device?

Post a minimal but complete compilable code (a blinky perhaps), exhibiting the problem.

JW
Posted on January 24, 2013 at 17:43

Can anyone hazard a guess as to why this might happen?

 

You fail to completely initialize auto/local variables/structures, which now contain random junk on the stack.

If you post code it might be obvious.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
mwp
Senior
Posted on January 25, 2013 at 11:45

Yup, sorry, its a STM32F103RC.

TIM3 init looks like:

static void GPIO_TIM3_Setup()
{
// Setup 10KHz TIM3 timer
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
// TIM3 periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// Set up the TIM3 UP Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //top priority
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Time Base configuration. The timer input clock is 36MHz on APB1. We
// need to divide this by 3600 in order to get the 10kHz interrupt.
TIM_TimeBaseStructure.TIM_Prescaler = 3600;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//start
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}

Thanks for the help...
frankmeyer9
Associate II
Posted on January 25, 2013 at 12:08

Referring to your example code, that means for instance to call

TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);

before starting to initialize it.

Local variables are place on the stack, which contains junk from former usage. with different optimization levels, the stack usage may change. If no interrupts are involved up to that point, the ''junk'' could be the same every time, giving you a consistant misbehavior.

You wouldn't be the first one to stumble across that ...

zzdz2
Associate II
Posted on January 25, 2013 at 13:15

''The counter clock frequency CK_CNT is equal to ***_PSC / (PSC[15:0] + 1).''

You would rather use this:

// need to divide this by 3600 in order to get the 10kHz interrupt.

TIM_TimeBaseStructure.TIM_Prescaler = 3600 - 1;

10/20 kHz problem bay be related to the fact that TIM clock equals APB1 if ABP1 prescaler==1, otherwise TIM clock is APB1 x2.
Posted on January 25, 2013 at 13:22

A better way to do 10 KHz 

TIM_TimeBaseStructure.TIM_Prescaler = 1;

// APB1 at 36MHz, TIMCLK at 72MHz 

TIM_TimeBaseStructure.TIM_Period = 3600 - 1;

Remember they that N-1 parameters, and you want the Counter portion to count, which means a Period >0

The problem I suspect however is in your IRQ code, it is important that you clear the pending IRQ first, if you do it as the last thing before you leave you expose a pipeline/race condition in the core, and it immediately tail-chains into your routine for a second time. Clear it as you enter.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
mwp
Senior
Posted on January 31, 2013 at 04:25

Clearing the IRQ on entering was the fix.

Thanks Clive, and others!