How to accurately convert TPM capture ticks (CnV) to time in microseconds?

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

How to accurately convert TPM capture ticks (CnV) to time in microseconds?

591 Views
Manjunathb
Contributor II

 

Hi,
I'm using the TPM module in input capture mode on [your MCU name here – e.g., MCIMX9353], and I’m measuring the time between rising and falling edges (like from an ultrasonic sensor). I get the captured values using:

uint32_t ticks = (fallingTime >= risingTime) ? (fallingTime - risingTime) : ((TPM_MAX_COUNTER_VALUE - risingTime) + fallingTime);

 

I want to convert this tick value into microseconds.
My question is:

  1. What is the correct way to calculate time in microseconds from the captured ticks?

  2. Which TPM clock frequency should I use in the calculation?

  3. Is CLOCK_GetIpFreq(LPTPM_CLOCK_ROOT) or CLOCK_GetFreq(kCLOCK_Tpm0) the correct API to use?

  4. Does the prescaler affect this, and how should I include it in the conversion?

Here’s the formula I’m currently using:

float timeUs = (ticks * 1.0f / tpmClk) * 1e6;

But the result seems too high in my case. Could you please confirm if this approach is correct or guide me on how to fix it?

Thanks in advance!

i.MX93 

Labels (1)
0 Kudos
Reply
3 Replies

571 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello,

To convert TPM capture ticks to time in microseconds on the MX93, you need to know the TPM clock source frequency and then use the following formula:
 
 
Time in microseconds = (Ticks * 1,000,000) / TPM_SOURCE_CLOCK 
 
 
Where: 
 
 
  • Ticks: is the difference between the captured falling and rising edge values (or the overflowed value in case of counter overflow) in TPM ticks.
  • TPM_SOURCE_CLOCK: is the frequency of the TPM clock source in Hz.
Example:
 
 
If the TPM clock source frequency is 48 MHz (48,000,000 Hz) and the difference in captured ticks is 2400, then the time in microseconds is:
 
 
Time = (2400 * 1,000,000) / 48,000,000 = 50 microseconds.
 
 
The TPM counter increments based on the TPM clock source. Each increment represents one tick. To convert ticks to time, you need to determine how much time a single tick represents. This is determined by the frequency of the TPM clock source. The formula essentially calculates the time by dividing the total number of ticks by the rate at which those ticks occur (the TPM clock frequency) and then scales it to microseconds. 
 
 
Important Considerations:
 
 
  1.   TPM Counter Overflow:
    If the TPM counter overflows during the measurement, you need to account for this by adding the maximum counter value to the difference between the rising and falling edges when calculating the ticks variable, as suggested in the NXP community thread.
      TPM Clock Source:
    Make sure you are using the correct TPM clock source frequency for your specific configuration. The NXP documentation or SDK examples should provide details on the available clock sources and how to configure them.
  2. Resolution:
    The resolution of the time measurement is limited by the TPM clock source frequency. Higher frequencies result in finer time resolution
     
    Regards
0 Kudos
Reply

552 Views
Manjunathb
Contributor II

Thank you for your response!
But i got stuck in the calculating distance from the sensor ?
I dont know if my question is correct or not ?
Is this my code flow was correct ?

/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "fsl_debug_console.h"
#include "board.h"
#include "app.h"
#include "fsl_tpm.h"
#include "fsl_rgpio.h"

/*******************************************************************************
* Definitions
******************************************************************************/

/*******************************************************************************
* Prototypes
******************************************************************************/
void SetUp(void);
void SendTrigPulse(void);
float CalculateDistance(void);

/*******************************************************************************
* Variables
******************************************************************************/
volatile uint32_t risingTime = 0;
volatile uint32_t fallingTime = 0;
volatile bool echoCaptured = false;
// volatile bool waitingForRise = true;
volatile bool gotRisingEdge = false;

/*******************************************************************************
* Code
******************************************************************************/
void SetUp(void)
{
rgpio_pin_config_t out_config ={
kRGPIO_DigitalOutput,
0,
};

// Trigger pin will find range
RGPIO_PinInit(BOARD_RGPIO,TRIG_PIN,&out_config);
RGPIO_PinWrite(BOARD_RGPIO,TRIG_PIN,0);

}

void SendTrigPulse(void)
{
RGPIO_PinWrite(BOARD_RGPIO, TRIG_PIN, 1);
SDK_DelayAtLeastUs(10, CLOCK_GetIpFreq(LPTPM_CLOCK_ROOT)); // 10us pulse
RGPIO_PinWrite(BOARD_RGPIO, TRIG_PIN, 0);
}

float CalculateDistance(void)
{
uint32_t ticks;
if (fallingTime >= risingTime)
ticks = fallingTime - risingTime;
else
ticks = (TPM_MAX_COUNTER_VALUE(DEMO_TPM_BASEADDR) - risingTime) + fallingTime; // Overflow handled

float tpmClk = CLOCK_GetIpFreq(LPTPM_CLOCK_ROOT); // You may adjust to TPM clock
float timeUs = (ticks * 1.0f / tpmClk) * 1e6f;
PRINTF("TPM Clock : %.2f\r\n",tpmClk);

float distanceCm = timeUs / 58.0f;

return distanceCm;
}


void TPM_INPUT_CAPTURE_HANDLER(void)
{
uint32_t status = TPM_GetStatusFlags(DEMO_TPM_BASEADDR);

if (status & TPM_CHANNEL_FLAG)
{
uint32_t capturedValue = TPM_GetChannelValue(DEMO_TPM_BASEADDR, BOARD_TPM_INPUT_CAPTURE_CHANNEL);

if (!gotRisingEdge)
{
risingTime = capturedValue;
gotRisingEdge = true;

// Switch to falling edge detection
TPM_SetupInputCapture(DEMO_TPM_BASEADDR,BOARD_TPM_INPUT_CAPTURE_CHANNEL,kTPM_FallingEdge);
}
else
{
fallingTime = capturedValue;
echoCaptured = true;
gotRisingEdge = false;

// Switch back to rising edge detection for next measurement
TPM_SetupInputCapture(DEMO_TPM_BASEADDR,BOARD_TPM_INPUT_CAPTURE_CHANNEL,kTPM_RisingEdge);
}

// Clear interrupt flag for this channel
TPM_ClearStatusFlags(DEMO_TPM_BASEADDR, TPM_CHANNEL_FLAG);
}

SDK_ISR_EXIT_BARRIER;
}

/*!
* @brief Main function
*/
int main(void)
{
tpm_config_t tpmInfo;

/* Board pin, clock, debug console init */
BOARD_InitHardware();

SetUp();

/* Print a note to terminal */
PRINTF("\r\nTPM input capture example\r\n");
PRINTF("\r\nOnce the input signal is received the input capture value is printed\r\n");

TPM_GetDefaultConfig(&tpmInfo);
/* Initialize TPM module */
TPM_Init(DEMO_TPM_BASEADDR, &tpmInfo);

/* Setup input capture on a TPM channel */
TPM_SetupInputCapture(DEMO_TPM_BASEADDR, BOARD_TPM_INPUT_CAPTURE_CHANNEL, kTPM_RisingEdge);

/* Set the timer to be in free-running mode */
TPM_SetTimerPeriod(DEMO_TPM_BASEADDR, TPM_MAX_COUNTER_VALUE(DEMO_TPM_BASEADDR));

/* Enable channel interrupt when the second edge is detected */
TPM_EnableInterrupts(DEMO_TPM_BASEADDR, TPM_CHANNEL_INTERRUPT_ENABLE);

/* Enable at the NVIC */
EnableIRQ(TPM_INTERRUPT_NUMBER);

TPM_StartTimer(DEMO_TPM_BASEADDR, kTPM_SystemClock);

while (1)
{
echoCaptured = false;

SendTrigPulse();

while (!echoCaptured)
{
__NOP(); // Wait for capture
}

float distance = CalculateDistance();
PRINTF("RisingTime : %u\r\n",risingTime);
PRINTF("FallingTime : %u\r\n",fallingTime);
PRINTF("Distance: %.2f cm\r\n", distance);

SDK_DelayAtLeastUs(60000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
}
}

0 Kudos
Reply

548 Views
Manjunathb
Contributor II
Here in this above code getting wrong distance from the sensor
Is their mistake in code or anything ?
Can you resolve this issue ?
0 Kudos
Reply