AnsweredAssumed Answered

Timer Synchronization

Question asked by Joshua on Sep 23, 2014
Latest reply on Sep 26, 2014 by waclawek.jan
I'm trying to take advantage of the ability to synchronize two timers in a master/slave config. In my case, I'm using one timer as a PWM output, and would like to have a second timer track the first as closely as possible. I *think* I'm setting this up correctly to run these in parallel mode, but the second timer seems to lagging the first by ~175nS. 

Here's the timer config:
tmp = SystemCoreClock / 1000000;
tmp /= asic_clk;
 
TIM_DeInit(TIM_ASIC_SATCLK);
TIM_DeInit(TIM_ASIC_MAINCLK);
 
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_ICInit(TIM_ASIC_SATCLK,&TIM_ICInitStructure);
TIM_ICInit(TIM_ASIC_MAINCLK,&TIM_ICInitStructure);
 
/* Time base configuration for TIM 1 */  
TIM_TimeBaseStructure.TIM_Period = tmp-1;                                    //Value here should be 1 less than you would think, e.g. 8 rather than 9.  72/8 == 8mhz
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_ASIC_SATCLK, &TIM_TimeBaseStructure);
 
/* PWM1 Mode configuration: Channel 1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = tmp/2;                                       //Value here should be what you would think, e.g. 6/2 == 3
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM_ASIC_SATCLK, &TIM_OCInitStructure);
 
/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM_ASIC_SATCLK, TIM_MasterSlaveMode_Enable);
 
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM_ASIC_SATCLK, TIM_TRGOSource_Update);
 
/* Time base configuration for TIM 8 */  
TIM_TimeBaseStructure.TIM_Period = tmp-1;                                    //Value here should be 1 less than you would think, e.g. 8 rather than 9.  72/8 == 8mhz
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_ASIC_MAINCLK, &TIM_TimeBaseStructure);
 
/* PWM1 Mode configuration: Channel 4 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = tmp/2;                                       //Value here should be what you would think, e.g. 6/2 == 3
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;                             //Select Ch4 (otherwise CH 1 is default)
TIM_OC4Init(TIM_ASIC_MAINCLK, &TIM_OCInitStructure);
 
/* Slave Mode selection: TIM8 */
TIM_SelectSlaveMode(TIM_ASIC_MAINCLK, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM_ASIC_MAINCLK, TIM_TS_ITR0);
 
TIM_OC1PreloadConfig(TIM_ASIC_SATCLK, TIM_OCPreload_Enable);
TIM_OC1PreloadConfig(TIM_ASIC_MAINCLK, TIM_OCPreload_Enable);
 
TIM_ARRPreloadConfig(TIM_ASIC_SATCLK, ENABLE);
TIM_ARRPreloadConfig(TIM_ASIC_MAINCLK, ENABLE);
 
TIM_InternalClockConfig(TIM_ASIC_SATCLK);
TIM_InternalClockConfig(TIM_ASIC_MAINCLK);
 
TIM_CtrlPWMOutputs(TIM_ASIC_SATCLK, ENABLE);
TIM_CtrlPWMOutputs(TIM_ASIC_MAINCLK, ENABLE);
 
TIM_Cmd(TIM_ASIC_SATCLK, ENABLE);
TIM_Cmd(TIM_ASIC_MAINCLK, ENABLE);


Here's the GPIO config:
// Output ASIC satellite clock on TIM1 pin
GPIO_PinAFConfig(GPIO_SATCLK,GPIO_PinSource8,GPIO_AF_TIM1) ;
GPIO_InitStructure.GPIO_Pin = ASIC_SATCLK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
if ( g_blk6.asic_clk == 30 )
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
else
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIO_SATCLK, &GPIO_InitStructure);
 
// Output ASIC main board clock on TIM8 pin
GPIO_PinAFConfig(GPIO_MAINCLK,GPIO_PinSource9,GPIO_AF_TIM8) ; 
GPIO_InitStructure.GPIO_Pin = ASIC_MAINCLK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
if ( g_blk6.asic_clk == 30 )
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
else
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIO_MAINCLK, &GPIO_InitStructure);

Anyone have any ideas?

Thanks!

Outcomes