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:
I want to convert this tick value into microseconds.
My question is:
What is the correct way to calculate time in microseconds from the captured ticks?
Which TPM clock frequency should I use in the calculation?
Is CLOCK_GetIpFreq(LPTPM_CLOCK_ROOT) or CLOCK_GetFreq(kCLOCK_Tpm0) the correct API to use?
Does the prescaler affect this, and how should I include it in the conversion?
Here’s the formula I’m currently using:
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!
Hello,
ticks
variable, as suggested in the NXP community thread. 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);
}
}