This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: Timer Capture

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: SYSBIOS

Hello, I am using TM4C1294XL board for my work.As I want capture positive edge using Timer1A and Timer1B whereas I want to get the value of input signal at every positive cycle . I have created a small program but timer interrupt event is not working.

Here is my Code,

void Timer1AIsr(void)
{
ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt

}

void Timer1BIsr(void)
{
ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt

}

void Config_Timer(void)
{
// ENABLE TIMER PERIPHERAL
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);


GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
GPIOPinConfigure(GPIO_PD2_T1CCP0);
GPIOPinTypeTimer(GPIO_PORTD_BASE, (GPIO_PIN_2 | GPIO_PIN_3));// enable the GPIO pins for timer


// Configure
ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);
ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, (ui32SysClock / 2)); // Divide by 20 for 50mSec Delay

ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1A configured 16 bit time capture
ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1B configured 16 bit time capture

ROM_TimerControlEvent(TIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
ROM_TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);

ROM_TimerLoadSet(TIMER1_BASE, TIMER_A,0);
ROM_TimerLoadSet(TIMER1_BASE, TIMER_B,0);

// IntRegister(INT_TIMER1A, edge_capture);

TimerIntRegister(TIMER3_BASE, TIMER_A, Timer3Isr); // Registering ISR
TimerIntRegister(TIMER1_BASE, TIMER_A, Timer1AIsr); // Registering ISR
TimerIntRegister(TIMER1_BASE, TIMER_B, Timer1BIsr); // Registering ISR

//
// Setup the interrupts for the timer timeouts.
//
TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
IntEnable(INT_TIMER3A);
TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);

TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt
IntEnable(INT_TIMER1A);
TimerIntEnable(TIMER1_BASE, TIMER_CAPA_EVENT);

TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt
IntEnable(INT_TIMER1B);
TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);

//
// Enable the timers.
//
TimerEnable(TIMER3_BASE, TIMER_A);
TimerEnable(TIMER1_BASE, TIMER_A);
TimerEnable(TIMER1_BASE, TIMER_B);

}

 

PS- Ignore Timer3 part from my code as it is for other function.

Thank You.

  • Hi,

      I see some issues with your code. 

      First, you are missing the pinmux for T1CCP1. Below is what you wrote.

    GPIOPinConfigure(GPIO_PD2_T1CCP0);
    GPIOPinTypeTimer(GPIO_PORTD_BASE, (GPIO_PIN_2 | GPIO_PIN_3));// enable the GPIO pins for timer

    You need to have:

    GPIOPinConfigure(GPIO_PD2_T1CCP0);

    GPIOPinConfigure(GPIO_PD3_T1CCP1);

    GPIOPinTypeTimer(GPIO_PORTD_BASE, (GPIO_PIN_2 | GPIO_PIN_3));// enable the GPIO pins for timer

    Second problem is with how you configure the timer A and B in edge time mode. If you want to use both the timer A and B as a 16-bit timer at the same time you need to use the TIMER_CFG_SPLIT_PAIR flag. 

    You wrote:

    ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1A configured 16 bit time capture
    ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1B configured 16 bit time capture

    It should be:

    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));

  • Thanks For Reply. 

    Actually currently I am checking only for Timer1A to get the general idea about capture mode.As I am lack of function generator instead I am Toggling 1 pin for 1Sec and Shorting to PD2 pin(Timer1A) for debugging but as of now timer1A interrupt routine is not occurring. Do I have to add any other parameters regarding timer or else? Thanks.

  • Hi,

      Did you have the below line in your code to enable the processor interrupt?

    // Enable the processor to respond to interrupts.
    IntMasterEnable();

  • Hello Sir, Yes I have added this line after Timer init function. 

  • Hi

     Can you send me your complete CCS project? Please remove anything that is irrelevant to the problem (e.g. the TIMER3 and the other half of Timer1). 

  • Yes. Just give me your email ID, will send you zip file. And I am using Timer 3 for Toggling pin for precise time and give this as a input to PD2 pin(Timer 1A to Capture Positive edge).

  • Hi,

      You can first click on my name and then click on the '+ Connect' button on the upper right hand. Once I accept your friend request, you can send me the project. 

  • #include <stdint.h>
    #include <stdbool.h>
    #include <stdlib.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/timer.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include <ti/drivers/UART.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/sysbios/knl/Semaphore.h>

    /* XDC module Headers */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>

    /* BIOS module Headers */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>

    /* Example/Board Header files */
    #include "Board.h"

    #define TASKSTACKSIZE 128

    Void task1Fxn(UArg arg0, UArg arg1);
    Void task2Fxn(UArg arg0, UArg arg1);

    void Config_Timer(void);

    // Timers
    uint32_t ui32SysClock;

    void Timer3Isr(void)
    {
    ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt

    if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0))
    {
    GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x0);
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0);
    }
    else
    {
    GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0);
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    }
    }

    void Timer1AIsr(void)
    {
    ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt

    }

    void Timer1BIsr(void)
    {
    ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt

    }

    void main(void)
    {
    //
    // Run from the PLL at 120 MHz.
    //
    ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480),120000000);

    Board_initGeneral();
    Board_initGPIO();
    Board_initUART();

    Config_Timer();
    //
    // Enable processor interrupts.
    //
    // ROM_IntMasterEnable();
    IntMasterEnable();

    BIOS_start(); /* Does not return */
    }

    void Config_Timer(void)
    {
    // ENABLE TIMER PERIPHERAL
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);


    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinConfigure(GPIO_PD2_T1CCP0);
    GPIOPinConfigure(GPIO_PD3_T1CCP1);
    GPIOPinTypeTimer(GPIO_PORTD_BASE, (GPIO_PIN_2 | GPIO_PIN_3));// enable the GPIO pins for timer


    // Configure
    ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);
    ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, (ui32SysClock)); // Divide by 20 for 50mSec Delay

    // ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1A configured 16 bit time capture
    // ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1B configured 16 bit time capture

    ROM_TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));

    ROM_TimerControlEvent(TIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    ROM_TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);

    ROM_TimerLoadSet(TIMER1_BASE, TIMER_A,0);
    ROM_TimerLoadSet(TIMER1_BASE, TIMER_B,0);

    // IntRegister(INT_TIMER1A, edge_capture);

    TimerIntRegister(TIMER3_BASE, TIMER_A, Timer3Isr); // Registering ISR
    TimerIntRegister(TIMER1_BASE, TIMER_A, Timer1AIsr); // Registering ISR
    TimerIntRegister(TIMER1_BASE, TIMER_B, Timer1BIsr); // Registering ISR

    //
    // Setup the interrupts for the timer timeouts.
    //
    TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
    IntEnable(INT_TIMER3A);
    TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);

    TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt
    IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER1_BASE, TIMER_CAPA_EVENT);

    TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt
    IntEnable(INT_TIMER1B);
    TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);

    //
    // Enable the timers.
    //
    TimerEnable(TIMER3_BASE, TIMER_A);
    TimerEnable(TIMER1_BASE, TIMER_A);
    TimerEnable(TIMER1_BASE, TIMER_B);

    }

  • Hi,

      You never mentioned you are using TI-RTOS and in your first post, you were giving just snippet of your code. Although I'm not a TI-RTOS expert, I think your problem is on using the TimerIntRegister(). You should never use TimerIntRegister() in the TI-RTOS context. The interrupt should be handled by the TI-RTOS Hwi module. Read this FAQ post for an explanation. 

     Go to the Hwi section in this TI-RTOS training presentation for Hwi usage. 

    https://training.ti.com/sites/default/files/docs/TI_RTOS_Kernel_Workshop_Student_Guide_rev4.00.pdf

    https://training.ti.com/getting-started-ti-rtos-training-series

      I'm not sure if you really want to use TI-RTOS if your application is only about generating PWM and input capture because it seems simple enough to do it without the RTOS. Perhaps you will expand your application in the future to something more complex requiring the task scheduling of the RTOS and that will be a different story. For what you want to do right now (e.g. toggling pin based on Timer 3 interrupt and use the Timer1A to capture it) I will suggest you first start with a non-TI RTOS environment. 

  • In case you wanted to try out your application in a non-TI-RTOS environment, here is code that I modify. I found several mistake in your code. 

    mistake 1:

      You wrote below. It should be TIMER1_BASE instead.

    ROM_TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));

    mistake 2:

    You want to use PN0 for for toggling the pin but you didn't enable the PN0. You are missing the below line.

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    mistake 3:
    When counting up, rather than preset the counter with 0, you need to actually set an upper value for the counter to count up to and then reset back to 0. I modify
    your code so that it will be able to fully utilize the full 24-bit counter. I change to below two lines.

    TimerPrescaleSet(TIMER1_BASE, TIMER_BOTH, 0xFF); TimerLoadSet(TIMER1_BASE, TIMER_BOTH, 0xFFFF);

    mistake 4:
    You are using the TIMER3 to create a one second timeout. This is much larger than than the 24-bit counter the TIMER1 is able to capture when you are in split
    mode. I modify it to create a shorted timeout value to illustrate the the TIMER1 can capture it. Or you can modify it on your own to fully use the 32-bit timer instead
    of split mode.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup timer_examples_list
    //! <h1>PWM using Timer (pwm)</h1>
    //!
    //! This example shows how to configure Timer1B to generate a PWM signal on the
    //! timer's CCP pin.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - TIMER1 peripheral
    //! - GPIO Port D peripheral (for T1CCP1 pin)
    //! - T1CCP1 - PD3
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example.  These are not required for operation of
    //! Timer0.
    //! - UART0 peripheral
    //! - GPIO Port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - None.
    //
    //*****************************************************************************
    
    void Config_Timer(void);
    
    // Timers
    uint32_t ui32SysClock;
    
    void Timer3Isr(void)
    {
    	ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
    
    	if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0))
    	{
    		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x0);
    		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0);
    	}
    	else
    	{
    		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0);
    		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    	}
    }
    
    void Timer1AIsr(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt
    
    }
    
    void Timer1BIsr(void)
    {
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt
    
    }
    
    void main(void)
    {
    	//
    	// Run from the PLL at 120 MHz.
    	//
    	ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    			SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    			SYSCTL_CFG_VCO_480),120000000);
    
    
    	Config_Timer();
    	//
    	// Enable processor interrupts.
    	//
    	// ROM_IntMasterEnable();
    	IntMasterEnable();
    	while (1);
    
    }
    
    void Config_Timer(void)
    {
    	// ENABLE TIMER PERIPHERAL
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    
    	GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    	GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
    	GPIOPinConfigure(GPIO_PD2_T1CCP0);
    	GPIOPinConfigure(GPIO_PD3_T1CCP1);
    
    	GPIOPinTypeTimer(GPIO_PORTD_BASE, (GPIO_PIN_2 | GPIO_PIN_3));// enable the GPIO pins for timer
    
    
    	// Configure
    	ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);
    	ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, (ui32SysClock / 20000)); // Divide by 20 for 50mSec Delay
    
    	// ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1A configured 16 bit time capture
    	// ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_CAP_TIME)); // timer1B configured 16 bit time capture
    
    	ROM_TimerConfigure(TIMER1_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));
    
    	ROM_TimerControlEvent(TIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    	ROM_TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE);
    
        TimerPrescaleSet(TIMER1_BASE, TIMER_BOTH, 0xFF);
        TimerLoadSet(TIMER1_BASE, TIMER_BOTH, 0xFFFF);
    //	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A,0x0);
    //	ROM_TimerLoadSet(TIMER1_BASE, TIMER_B,0x0);
    
    	// IntRegister(INT_TIMER1A, edge_capture);
    
    	TimerIntRegister(TIMER3_BASE, TIMER_A, Timer3Isr); // Registering ISR
    	TimerIntRegister(TIMER1_BASE, TIMER_A, Timer1AIsr); // Registering ISR
    	TimerIntRegister(TIMER1_BASE, TIMER_B, Timer1BIsr); // Registering ISR
    
    	//
    	// Setup the interrupts for the timer timeouts.
    	//
    	TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
    	IntEnable(INT_TIMER3A);
    	TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
    
    	TimerIntClear(TIMER1_BASE, TIMER_CAPA_EVENT); // Clear the timer interrupt
    	IntEnable(INT_TIMER1A);
    	TimerIntEnable(TIMER1_BASE, TIMER_CAPA_EVENT);
    
    	TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT); // Clear the timer interrupt
    	IntEnable(INT_TIMER1B);
    	TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);
    
    	//
    	// Enable the timers.
    	//
    	TimerEnable(TIMER3_BASE, TIMER_A);
    	TimerEnable(TIMER1_BASE, TIMER_A);
    	TimerEnable(TIMER1_BASE, TIMER_B);
    
    }