/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_tpm.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Define instance */
#define DEMO_TPM_BASEADDR TPM2
/* Interrupt to enable and flag to read; depends on the TPM channel used */
#define BOARD_TPM_INPUT_CAPTURE_CHANNEL kTPM_Chnl_0
/* Interrupt to enable and flag to read; depends on the TPM channel used */
#define TPM_CHANNEL_INTERRUPT_ENABLE kTPM_Chnl0InterruptEnable
#define TPM_CHANNEL_FLAG kTPM_Chnl0Flag
/* Interrupt number and interrupt handler for the TPM instance used */
#define TPM_INTERRUPT_NUMBER TPM2_IRQn
#define TPM_INPUT_CAPTURE_HANDLER TPM2_IRQHandler
/* Get source clock for TPM driver */
#define LPTPM_CLOCK_ROOT kCLOCK_Root_Tpm2
#define LPTPM_CLOCK_GATE kCLOCK_Tpm2
#define TPM_SOURCE_CLOCK CLOCK_GetIpFreq(LPTPM_CLOCK_ROOT)
/* Adjust this based on expected signal frequency */
#define EXPECTED_MAX_FREQUENCY 1000U /* 1 kHz */
#define EXPECTED_MIN_FREQUENCY 1U /* 1 Hz */
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool tpmIsrFlag = false;
volatile uint32_t counterStart = 0;
volatile uint32_t counterEnd = 0;
volatile uint32_t capturedValue = 0;
/*******************************************************************************
* Code
******************************************************************************/
void TPM_INPUT_CAPTURE_HANDLER(void)
{
if (TPM_GetStatusFlags(DEMO_TPM_BASEADDR))
{
tpmIsrFlag = true;
/* Capture the value */
capturedValue = TPM_GetChannelValue(DEMO_TPM_BASEADDR, BOARD_TPM_INPUT_CAPTURE_CHANNEL);
/* Capture the end counter value when the interrupt occurs */
counterEnd = DEMO_TPM_BASEADDR->CNT;
/* Clear interrupt flag */
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 */
const clock_root_config_t lptpmClkCfg = {
.clockOff = false,
.mux = 0, /* Select clock source, e.g., system clock */
.div = 1 /* Adjust divider to match expected signal frequency */
};
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
CLOCK_SetRootClock(LPTPM_CLOCK_ROOT, &lptpmClkCfg);
CLOCK_EnableClock(LPTPM_CLOCK_GATE);
/* Print a note to terminal */
PRINTF("\r\nTPM Input Capture with Counter Example\r\n");
PRINTF("Provide an input signal with frequency between %u Hz and %u Hz\r\n", EXPECTED_MIN_FREQUENCY, EXPECTED_MAX_FREQUENCY);
PRINTF("Waiting for input signal...\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 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);
/* Reset the counter */
DEMO_TPM_BASEADDR->CNT = 0;
counterStart = 0;
while (tpmIsrFlag != true)
{
/* Wait for the interrupt to occur */
}
/* Validate clock frequency */
uint32_t clockFrequency = TPM_SOURCE_CLOCK;
if (clockFrequency == 0)
{
PRINTF("\r\nError: Clock frequency is 0. Check the clock configuration.\r\n");
while (1)
;
}
/* Calculate elapsed time using counter values */
if (counterEnd >= counterStart)
{
uint32_t elapsedCounts = counterEnd - counterStart;
float elapsedTime = (float)elapsedCounts / (float)clockFrequency;
/* Validate and calculate frequency */
uint32_t signalFrequency = (capturedValue != 0) ? (clockFrequency / capturedValue) : 0;
/* Print results */
PRINTF("\r\nCounter Start Value: %u\r\n", counterStart);
PRINTF("Counter End Value: %u\r\n", counterEnd);
PRINTF("Elapsed Counts: %u\r\n", elapsedCounts);
PRINTF("TPM Source Clock Frequency: %u Hz\r\n", clockFrequency);
PRINTF("Elapsed Time: %.6f seconds\r\n", elapsedTime);
PRINTF("Estimated Signal Frequency: %u Hz\r\n", signalFrequency);
}
else
{
PRINTF("\r\nError: Counter end value is less than counter start value.\r\n");
}
while (1)
{
}
}