2011-12-06 01:12 AM
The follow ISR capture an event incoming on TIM4_CCP2, and
each 8 of this events the register oldCCP is subtracted from CCR2, this value is strored in loop_buf[cyc][lb_index], the value of CCR2 updates oldCCP, and also cyc and lb_index are updated. Each update event the counter cntr0 increase of 0x00010000, in order to manage time intervals greater than 16bits. Sometimes a missed rollover event occur, so losing the MSB of the captured value. I' ve tried to swap the ISR each other, without fixing the problem. brief hardware and settings description: microcontroller: STM32F103V8Tb compiler: IAR 5.4_2 (maximum balanced compression) Incoming signal: square wawe at 30KHz and dutycycle 23% interrupts enabled: - Systick every 50 microseconds preemption pr. 1, subpriority 0 - Adconv1 watchdog preemption pr. 1, subpriority 0 - TIM4 preemption pr. 0, subpriority 0 TIM4 settings: TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); TIM_SetClockDivision(TIM4,TIM_CKD_DIV1); TIM_UpdateDisableConfig(TIM4, DISABLE); TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV8; TIM_ICInitStruct.TIM_ICFilter = 5; TIM_ICInit(TIM4, &TIM_ICInitStruct); /******************************************************************* unsigned int loop_buf[2][8]; //2-dimensions filtering vector unsigned int lb_index[2]; //pointer index on loop_buf unsigned int oldCCP[2]; //previous CCP value char s_frq[2] = {2, 1}; //frequency selection (don't care) int cyc =0; //allowed values: 0 and 1 void TIM4_IRQHandler(void) { static int contaeventi=, cntRO[2]={0,0}; short pinO; //ISR for capture event if(TIM_GetFlagStatus(TIM4, TIM_FLAG_CC2)) { TIM4->SR = 0xFFFB; if(--contaeventi<N_meas[cyc]) { if(contaeventi==0) { cntRO[cyc]=cntRO[cyc+TIM4->CCR2; if(TIM4->CCR2==0) cntRO[cyc]=cntRO[cyc]+0x00010000; loop_buf[cyc][lb_index[cyc]]=(cntRO[cyc]-oldCCP[cyc]); cntRO[cyc]=0; lb_index[cyc]=(lb_index[cyc]+1)&7; cyc = (~cyc)&1; pinO = ((short)((~s_frq[cyc])&3)<<11)|((short)((2-cyc)&3)<<9); GPIOD->BRR = pinO; GPIOD->BSRR = (~pinO)&0x1E00; contaeventi=((3*N_meas[cyc])>>1)+2; } } else oldCCP[cyc]=TIM4->CCR2; } //ISR for TIM4_CNT rollover event if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update)) { TIM4->SR=0xFFFE); cntRO[cyc]=cntRO[cyc]+0x00010000; if(cntRO[cyc]==0) cntRO[cyc]=0xFFFF0000; } } #tim4-missing-update-interrupt2011-12-08 01:47 AM
I hope you are providing proper clock to TIM4?
2011-12-08 07:01 AM
Wow, that's some fugly code, and badly pasted.
Yeah, you're going to have some serious problems with that as CCR approaches within a few dozen cycles of the update point, with a particularity nasty race condition. Does it really make sense to ping-pong between two variables holding state information? How are you determining if the CCR event occurs before/after the Update? You don't seem to be accounting for any window for that to be occurring.2011-12-08 07:02 AM
Double post, forum choked!
2011-12-08 11:33 PM
what does it means?
2011-12-09 12:37 AM
This is the system clock settings:
/*******************************************************************************
* Function Name : InitRCC * Description : Configures the different system clocks. * Input : None * Output : None * Return : None *******************************************************************************/ void InitRCC(void) { // RCC system reset RCC_DeInit(); // 1: clocking the controller from internal HSI RC (8 MHz) RCC_HSICmd(ENABLE); // wait until the HSI is ready while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); // selezione del clock come clock di sistema RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); // 2: enable ext. high frequency OSC RCC_HSEConfig(RCC_HSE_ON); // wait until the HSE is ready while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); // 3: init Embedded Flash // ENABLE Prefetch buffer FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // SET FLASH latency // Flash wait state // Zero wait state, if 0 < HCLK 24 MHz // --> One wait state, if 24 MHz < HCLK 56 MHz // Two wait states, if 56 MHz < HCLK 72 MHz FLASH_SetLatency(FLASH_Latency_2); // Half cycle access disabled FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable); // 4: init PLL RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); // 72MHz RCC_PLLCmd(ENABLE); // PLL enable // wait until the PLL is ready while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // 5: Set system clock dividers RCC_HCLKConfig(RCC_SYSCLK_Div1);//AHB clock-->72MHz RCC_PCLK1Config(RCC_HCLK_Div2); //APB1 clock(36MHz)-->TIM4:36*2=72MHz RCC_PCLK2Config(RCC_HCLK_Div1); //APB2 clock(72MHz)-->TIM1 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //clock ADC(72MHz/6)=12MHz RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); //clock USB-->48MHz // 6: Clock system from PLL RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() != 0x08); }2011-12-09 07:17 AM
what does it means?
It means the forum is flaky, and crashed/accepted the same post twice, the second of which was edited to indicate that occurred. OR It means you have failed to understand that your interrupt handler can/will enter under 3 conditions : CC UPDATE CC+UPDATE For example consider this subset for CCR values FFFC FFFF 0000 0004 In all these cases *BOTH* CC and UPDATE will be signalled on entry, what do you do now?2011-12-09 08:03 AM
OK,
how I should do
todetect
clearly
the two
interrupts
?
2011-12-09 08:39 AM
Well, I'd start be reading the timer's complete interrupt flag register, and time stamp the entry.
I would deal with the unambiguous conditions first. And I'd read the CCR and CNT registers for the ambiguous case and determine which side of the update the compare occurred. I would also look to use the free running 32-bit counter to count the overflows. And I'd significantly simplify the logic of the code, but I'm not sure what characteristics/aspects of the signal you are actually trying to measure. Also, remember you are clocking the counter at 72 MHz, from what I can see, so you're likely to encounter a window of a hundred or so cycles. The current code structure compounds this problem.2011-12-12 02:46 AM
to explain as well the task:
I want to measure a time interval; this time interval could be longer of a rollover period of the cnt register, so I need to count also the rollover events in order to manage time measures greater of 16 bits. the rollover ISR will only increment a register representing the most significant part of the measured interval, while the ccr ISR measure the time duration between n (n will be variable) events by subtracting the old ccr value from the actual ccr value; then, the obtained value will be stored into a 8-wide circular buffer. I agree with the need to correctly manage all the possible event sequence, and maybe the present code don't do the job properly, but my actual problem is simpler: sometimes the update event ISR don't execute, even though there is no ccr ISR executing. I tried to disable the ccr interrupt and the update event work properly; also enabling ccr interrupt but executing a very short ISR dummy routine the update event work properly; only trying to execute the whole ccr ISR result in missing rollover event.