On the Kinetis K61 processor I am using Flex Timer Module 2, FTM2, to count time between hardware events. FTM2 Channel 0 is configured for Input Capture Mode using CMP0_OUT for input capture (SIM_SOPT4_FTM2CH0SRC_CMP0). I have interrupts enabled as well for 2 reasons: (1) wraparound on FTM2 count, and (2) channel 0 flag.
How can I configure FTM2 so that it's count is re-initialized at the same time that channel 0 stores the value into FTM2_C0V?
Hi, Andrejs,
Regarding your question, I do not think it is necessary to reinitialize the FTM counter once the capture event happens on the FTM input channel pin FTM_CHx. This is the general method to measure the ticks between two capture events:
1)set the FTM_MOD register to a large value for example 0xFFFF
2)configure the capture mode for FTM.
3)when the edge is detected on FTM_CHx, the current FTM counter value is latched into FTM_CxV register, while an interrupt is triggered. In the ISR, you can define two global variables, one save the previous value of FTM_CxV, another save the current value of FTM_CxV register. You can figure out the difference of the two variables which is the number of ticks between the two capture events.
4)You can define the two variable in unsigned int type, which is 32 bits instead of 16 bits, and enable FTM overflow interrupt(when the FTM counter counts from 0xFFFF to 0), because all the FTM interrupt source share the same interrupt vector, in each FTM ISR, you can check the overflow flag bit, if it is set, you can add 0x10000 to FTM_CxV and assign the result to variable.
I do not think there is any setting of FTM register which can make the capture event reinitialize the FTM_CNT with FTM_CNTIN, the FTM_CNT continues to count.
Hope it can help you.
BR
XiangJun Rong
If you only need 'time' less than the possible 16-bit count (at your FTM frequency) you don't need anything 'special', just a static 'time save' and a simple unsigned-int 16-bit difference. Let the counter 'free run' with 'no' mod (0xFFFF) for simple rollover. The difference-math will 'ignore overflow/underflow' and give you exactly the right time difference. I do this from a continuous stream to measure a varying PWM from the one capture-interrupt:
static uint16_t time_saved = 0;
void TPM_DRV_IRQHandler( )
{
uint16_t time_dif;
uint16_t time_cnt;
time_cnt = TPM_HAL_GetChnCountVal( tpmBase, channel );
//Counts are of 1.5MHz (48MHz/2/16), or 667ns. Max diff 43.69ms
time_dif = ( time_cnt - time_saved );
time_saved = time_cnt;
...
So if the 'saved' count was 0xFFFD (-3, three counts up will include the next 'zero'), and the next time_cnt is 6, then 6-0xFFFD is the correct 9 in unsigned 16-bit math, ignoring the underflow. By a similar token, 6-7 yields 0xFFFF: 65535 counts, the max possible difference.
I suppose if 16bit resolution is NOT going to do it, then by all means also run that 'overflow' interrupt, BUT you will have to handle some 'special cases' right around overflow. That is, if the 'time_cnt' is NOT a 'very low' number, then the overflow happened AFTER the count-trigger, and you will have to 'save' this overflow indication for the NEXT interrupt and 'add' 1<<16 to the now-32bit-time_saved value after THAT time. Else, process said overflow interrupt first here by appending the updated upper-16bits to the captured count.
By NOT trying to 'modify' any FTM registers 'on the fly' this will ALWAYS give you the exact time (down to FTM-clock-rate-resolution of course) between interrupt edges, assuming that your overall interrupt environment allows you to service the interrupt 'at some point' between every pair of edges.