I have written some baremetal code to interface a a Ping Parallax ultrasonic range finder using interrupts but I am having some trouble properly initializing the KL25Z TPM1 for input capture. Basically I just need to measure the time between the rising edge and falling edge of the sensor output. I am using TPM1_CH0 on pin PTA12 for sensor output to the KL25Z freedomboard. I have taken the approach that Alice_Yang suggested in this thread: Re: Using of TPM to calculate pulse width in KL25Z Here is how I have initialized the hardware. Please correct me if I'm wrong.
TPM1_CH0 Initialization:
void TPM1_CH0_Timer_Capture_Init(void)
{
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Enable clock to PORTA */
PORTA_PCR12 = PORT_PCR_MUX(3); /* Set Port A for TPM1CH0 input */
SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; /* Enable clock to TPM1 */
SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* We Want MCGPLLCLK/2 */
SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK);
SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); /* We want the MCGPLLCLK/2 */
TPM1_SC |= 0x00; /* Blow away the control registers to ensure that the counter is not running */
TPM1_CONF |= 0x00; /* Blow away the control registers to ensure that the counter is not running */
TPM1_SC = TPM_SC_PS(TPM1_CLK_PRESCALE); /* Setup prescaler to DIV by 4 */
TPM1_MOD = 0xFFFF; /* Set max modulo */
/* Input Capture mode rising edge interrupt first, ELSB:ELSA = 01, MSB:MSA = 00 */
TPM1_C0SC |= TPM_CnSC_CHIE_MASK | TPM_CnSC_ELSA_MASK & ~(TPM_CnSC_ELSB_MASK) & ~(TPM_CnSC_MSA_MASK) & ~(TPM_CnSC_MSB_MASK);
}
Here is the logic I plan to follow inside the FTM1_IRQHandler() I still have not implemented the handler
void FTM1_IRQHandler(void)
{
//clear channel interrupt flag
//stop timer
//check for rising or falling edge interrupt
//if rising edge interrupt
//save TPM counter value in var called rising_val
//set falling edge interrupt
//start the timer
//if falling edge interrupt
//save TPM counter value in var called falling_val
}
And the sequence of events in main:
int main(void)
{
/* Core Clock is now at 48MHz using the 8MHZ Crystal */
pll_init(8000000, LOW_POWER, CRYSTAL, 4, 24, MCGOUT); //Using Eli Highs' PLL init mcg library files
TPM1_CH0_Timer_Capture_Init();
Init_PORTA();
for(;;) {
// logic here gives the range finder the start pulse it needs
GPIOA_PDDR |= GPIO_PTA1_LOC; /* make PortA_1 an output */
GPIO_PTA2_HIGH; /* PTA2 HIGH for A to B Level Shifter DIR */
GPIO_PTA1_HIGH;
DelayUs_NoIRQ(5); /* delay 5us */
GPIO_PTA1_LOW;
DelayUs_NoIRQ(300); /* delay 300us */
GPIOA_PDDR &= ~GPIO_PTA1_LOC; /* make PortA_1 an input */
GPIO_PTA2_LOW; /* PTA2 LOW for B to A Level Shifter DIR */
// Logic here handles the IRQ and pulse width measurement
enable_irq (INT_TPM1-16); /* Enable Timer1 interrupt in NVIC */
TPM1_SC |= TPM_SC_CMOD(1); /* Enable the TPM1_CH0 Timer */
DelayMs_NoIRQ(19); /* delay 19ms */
disable_irq (INT_TPM1-16); /* Disable Timer1 interrupt in NVIC */
val = falling_edge_val - rising_edge_val; /* Save captured pulse width value */
}
return 0;
}
Is there anything wrong with how I've initialized my TPM1_CH0 capture input for TPM1? Thank you for any assitance.
There is a tutorial how to use the TPM for measuring ultrasonic echo signals, see Tutorial: Ultrasonic Ranging with the Freedom Board
I hope this helps,
Erich
Hi exgreyfox,
I find you also have anther post about the TPM1_CH0 question which already be solved, so please refer to your anther post: How do I detect both rising and falling edge interrupt with input capture?
If you still have question, please contact with me!
Besides, if your input PWM wave is fast, I suggest you use two capture pin instead of just one capture pin.
Wish it helps you!
Have a great day,
Jingjing
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------