Timestamp with capture does not seem realistic Timer0_capture2 LPC4370

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Timestamp with capture does not seem realistic Timer0_capture2 LPC4370

Jump to solution
1,097 Views
Gaico
Contributor II

Hello,

I am currently trying to have a simple duty cycle measurement functionality using Timer0 capture 2.

Initialization /code

I have initialized the timer as follows:

 

 

 

//defines
#define SMT_timer LPC_TIMER0
#define SMT_IRQ	  TIMER0_IRQn
#define SMT_RGU	  RGU_TIMER0_RST
#define SMT_timerNR 0
#define SMT_capNR 2
#define SMT_CLK_MX CLK_MX_TIMER0

#define TIMER0TICKRATEHZ 30000000 //try to be at least 2x7 kHz

 

 

 

 

 

 

/* Enable timer clock and reset it */
	Chip_TIMER_Init( SMT_timer );
	Chip_RGU_TriggerReset(SMT_RGU);
	while (Chip_RGU_InReset(SMT_RGU)) {}

	/* Get timer 0 peripheral	 clock rate */
	uint32_t timerFreq;
	timerFreq = Chip_Clock_GetRate(SMT_CLK_MX);

	/* Timer setup for match and interrupt at TIMER0TICKRATE_HZ */
	Chip_TIMER_Reset(SMT_timer);
	Chip_TIMER_MatchEnableInt(SMT_timer, SMT_timerNR);
	Chip_TIMER_SetMatch(SMT_timer, SMT_timerNR, (timerFreq / TIMER0TICKRATEHZ));//SMT_timerNR could need to be 1
	Chip_TIMER_ResetOnMatchEnable(SMT_timer, SMT_timerNR);
//	Chip_TIMER_Enable(LPC_TIMER0); //only done during measurement

	/* Set input capture */
//	Chip_TIMER_Reset( SMT_timer );
	Chip_TIMER_CaptureEnableInt(SMT_timer, SMT_capNR); //Capture on T0_CAP2 (BUSY_SMT)
//	LPC_GIMA->CAP0_IN[SMT_timerNR][SMT_capNR] = 3<<4 | 1<<2; //capture source T3_CAP2
	LPC_GIMA->CAP0_IN[SMT_timerNR][SMT_capNR] =  0x20; //0x20 = the T0Cap2 pin in input selection

	/* Set interrupt priority */
	NVIC_SetPriority(SMT_IRQ, 2);

 

 

 

The timer only gets started when I want to measure the duty cycle in this manner:

 

 

/* Enable Timer */
	Chip_TIMER_Reset( SMT_timer );

	Chip_TIMER_CaptureRisingEdgeDisable(SMT_timer, 2);//start looking for a falling edge
	Chip_TIMER_CaptureFallingEdgeEnable(SMT_timer, 2);

	Chip_TIMER_ClearCapture(SMT_timer, 2);
	Chip_TIMER_Enable( SMT_timer );

	/* Enable interrupt */
	NVIC_EnableIRQ(SMT_IRQ);
	NVIC_ClearPendingIRQ(SMT_IRQ);

 

 

From then on, the IRQ handles the measurement.

 

 

 

void  SMT_IRQ_handler()
{
	if (Chip_TIMER_CapturePending(SMT_timer, 2))//if something was captured
	{
		Chip_TIMER_ClearCapture(SMT_timer, 2);

		capvalue0_SMT = Chip_TIMER_ReadCapture(SMT_timer, 2);

/* ........... */
          }
}

 

 

 

The issue

The capvalue keeps finding very odd numbers, which do not line up sequentially. E.g capture value 1 = 5, then the next captured value is 1, etc. 

The captured edges are correct as I have checked this on an oscilloscope, adding an external trigger (channel 1) pin that is set high when a measurement starts, and gets pulled low when 8 periods are measured (this signal is connected to channel 2). I can count the 8 periods that I wish to measure.

I do not think the unsigned int holding the time is flipping inbetween each capture as even at the highest frequency (204MHz) the timer should still be able to track 21s before flipping. But I am completely lost as to what could be my issue here.

Is there a way for the timestamps to be overwritten somehow?

I hope my question was somewhat clear and I appreciate any form of tips and help I can get!

Labels (1)
0 Kudos
1 Solution
1,080 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

It appears I get the cause.

Pls try to compute the value:

#define TIMER0TICKRATEHZ 30000000 //try to be at least 2x7 kHz
Chip_TIMER_SetMatch(SMT_timer, SMT_timerNR, (timerFreq / TIMER0TICKRATEHZ));

The TIMER0TICKRATEHZ is 30Mhz, the timerfFreq is 204MHz at most, pls check yourself in debugger,

so  SMT_timeNR match register will be 6 or 7, which determine the CTimer0 counter overflowing value(in other words, it determines the cycle time of CTimer0).

Pls try to set

#define TIMER0TICKRATEHZ 2 //try to be at least 2x7 kHz

 

what is the result?

Hope it can help you

BR

XiangJun Rong

View solution in original post

0 Kudos
4 Replies
1,081 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

It appears I get the cause.

Pls try to compute the value:

#define TIMER0TICKRATEHZ 30000000 //try to be at least 2x7 kHz
Chip_TIMER_SetMatch(SMT_timer, SMT_timerNR, (timerFreq / TIMER0TICKRATEHZ));

The TIMER0TICKRATEHZ is 30Mhz, the timerfFreq is 204MHz at most, pls check yourself in debugger,

so  SMT_timeNR match register will be 6 or 7, which determine the CTimer0 counter overflowing value(in other words, it determines the cycle time of CTimer0).

Pls try to set

#define TIMER0TICKRATEHZ 2 //try to be at least 2x7 kHz

 

what is the result?

Hope it can help you

BR

XiangJun Rong

0 Kudos
1,074 Views
Gaico
Contributor II

the timerfFreq is 204MHz at most, pls check yourself in debugger

I agree, checked in the debugger to be sure and it agrees as well (the timerFreq is set to 204000000).

SMT_timeNR match register will be 6 or 7 which determine the CTimer0 counter overflowing value(in other words, it determines the cycle time of CTimer0).

I see what you mean. You're mentioning that the CTimer0 counter will reset at a count of 102.000.000 (timerFreq/ TIMER0TICKRATE of 2). I am also seeing this in the eventually received pointers using the TIMER0TICKRATE of 2:

'old' timestamp from last trigger (current-1):        101507533 (noted as f)

'new' timestamp from the latest trigger (current): 17360670 (noted as r)

So the calculation did 0xFFFFFFFF - (f-r); = 4294967295 – (101507533 – 17360670) = 4210820432. But this overcorrected and resulted in a value I did not expect at all.

I need to correct based on this match value, not the max value of a 32 bit unsigned int (which I am expecting the Timer0 counter to hold). After I did this, more stable results came in that seemed more reasonable.

I will update if this ends up not working, but I have good faith. Thank you for helping so far and giving me a nudge as to where I should be looking @xiangjun_rong !

 

Update

With changing the frequency to 2 and correction based on the matchvalue I seem to be getting decent timestamps, but I am not getting a stable reading of the periods. It seems like I am missing triggers, while I suppose the set frequency would now be 102.000.000 HZ? Or is it on 2Hz? ( I apologize, I am rather tired and cannot seem to find the direct link in my brain anymore...)

0 Kudos
1,058 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I suggest you enable the overflow interrupt, in other words, in can enable the capture interrupt and overflow interrupt.

In the ISR, you have to check the interrupt source, if it is an overflow interrupt, just set a overflow_flag as 1, if it is a capture interrupt, do measurement.

The duration of two consecutive edge is CaptureHold(n)+overflow_flag*match_register- CaptureHold(n-1).

Hope it can help you

BR

XiangJun Rong

0 Kudos
1,043 Views
Gaico
Contributor II

I found out the issue with the periods not being stable. That part was because my code was skipping one period every time it was measuring as it did not consider the falling edge after the first one as being the first falling edge for the next period.

I apologize, I did not directly share that code so no way to know! I am looking into what you said even if it's just to understand what you meant and learn.

0 Kudos