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: I want '20' nanoseconds Timer delay for Plink the LED on EK-TM4C1294XL Board

Part Number: TM4C1294NCPDT

Hi,

How to make '20' Nanoseconds delay in Timer?

in Example Time code to convert for 20 Nanoseconds for our Testing. The Code given to Below.

#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"


// System clock rate in Hz.
uint32_t g_ui32SysClock;

// Flags that contain the current value of the interrupt indicator as displayed on the UART.
uint32_t g_ui32Flags;

// Configure the UART and its pins. This must be called before UARTprintf().
void ConfigureUART(void)
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

UARTStdioConfig(0, 115200, g_ui32SysClock);
}


// The interrupt handler for the first timer interrupt.
void Timer0IntHandler(void)
{
char cOne;
uint32_t Load_Value = 0U, Match_Value = 0U, TimerClock_Value = 0U;

MAP_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
TimerClock_Value = MAP_TimerClockSourceGet(TIMER0_BASE);
Load_Value = MAP_TimerLoadGet(TIMER0_BASE, TIMER_A);
Match_Value = MAP_TimerMatchGet(TIMER0_BASE, TIMER_A);
HWREGBITW(&g_ui32Flags, 0) ^= 1;
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, g_ui32Flags);
MAP_IntMasterDisable();

cOne = HWREGBITW(&g_ui32Flags, 0) ? '1' : '0';
UARTprintf("\r***************************************************");
UARTprintf("\rT1: %c", cOne);
UARTprintf("\rSysClock: %d", g_ui32SysClock);
UARTprintf("\rTimerClock: %d", TimerClock_Value);
UARTprintf("\rLoadValue: %d", Load_Value);
UARTprintf("\rMatchValue: %d", Match_Value);

MAP_IntMasterEnable();
}


// The interrupt handler for the second timer interrupt.
void Timer1IntHandler(void)
{}

// This example application demonstrates the use of the timers to generate periodic interrupts.
int main(void)
{
g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_240), 120000000);

ConfigureUART();
UARTprintf("\nTimers example\n");


MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
MAP_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);


MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, (g_ui32SysClock / 60000000));

MAP_IntMasterEnable();
MAP_IntEnable(INT_TIMER0A);
MAP_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
MAP_TimerEnable(TIMER0_BASE, TIMER_A);

while(1)
{
}
}

  • Hi,

      You have the below preload value for the timer. g_ui32SysClock / 60000000 is equal to 2 System Clock. One System clock is 8.3ns at 120Mhz. For 2 clocks, this is 16.6ns.  This means your timer will expire every  16.6ns. I'm not sure what type of application you are trying to create. You are literally creating a timer at 16.6ns duration. Why are you doing that? It does not make an application sense to me. There is latency from the time an interrupt is generated until the ISR is serviced. That will be multiple cycles. That means by the time the processor enters the ISR, the timer has timeout multiple times already. In addition, the processor needs to execute your code in the ISR. Look at your ISR, you have tons of code to print data through UARTPrintf and also toggle GPIO. That can take hundreds if not thousands of cycles. During this time, your timer has timeout hundreds of times. 

    MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, (g_ui32SysClock / 60000000));

    If you want to delay something, you can use SysCtlDelay. For example, SysCtlDelay(1) will create a delay that is equal to 3 cycles. At 120Mhz, that is about 25ns. 

  • Hi Charles,

    Thank for providing this information.

    I will working one project that is Calculate the time between the Two operation.

    the operation is if i press the switch that output is through to the another board and then the another board is give some input. that time i will measure the Time in between output and input.

    that's why i testing the Time operation.

    Thanks & Regard,

    Vijay

  • Hi,

      One idea I can think of is to take the timestamp when the switch is pressed on board_A and take another timestamp when board_B asserts another input to board_A. Take the difference between these two timestamps. You will use the Input Time mode for the timer. 

    13.3.3.4 Input Edge-Time Mode
    Note: For rising-edge detection, the input signal must be High for at least two system clock periods
    following the rising edge. Similarly, for falling edge detection, the input signal must be Low
    for at least two system clock periods following the falling edge. Based on this criteria, the
    maximum input frequency for edge detection is 1/4 of the system frequency.
    In Edge-Time mode, the timer is configured as a 24-bit up- or down-counter including the optional
    prescaler with the upper timer value stored in the GPTMTnPR register and the lower bits in the
    GPTMTnILR register. In this mode, the timer is initialized to the value loaded in the GPTMTnILR
    and GPTMTnPR registers when counting down and 0x0 when counting up. The timer is capable of
    capturing three types of events: rising edge, falling edge, or both. The timer is placed into Edge-Time
    mode by setting the TnCMR bit in the GPTMTnMR register, and the type of event that the timer
    captures is determined by the TnEVENT fields of the GPTMCTL register. Table 13-8 on page 964
    shows the values that are loaded into the timer registers when the timer is enabled.

    When software writes the TnEN bit in the GPTMCTL register, the timer is enabled for event capture.
    When the selected input event is detected, the current timer counter value is captured in the
    GPTMTnR and GPTMTnPS register and is available to be read by the microcontroller. The GPTM
    then asserts the CnERIS bit in the GPTM Raw Interrupt Status (GPTMRIS) register, and holds it
    until it is cleared by writing the GPTM Interrupt Clear (GPTMICR) register. If the capture mode
    event interrupt is enabled in the GPTM Interrupt Mask (GPTMIMR) register, the GPTM also sets
    the CnEMIS bit in the GPTM Masked Interrupt Status (GPTMMIS) register. In this mode, the
    GPTMTnR and GPTMTnPS registers hold the time at which the selected input event occurred while

    the GPTMTnV register holds the free-running timer value. These registers can be read to determine
    the time that elapsed between the interrupt assertion and the entry into the ISR.
    In addition to generating interrupts, an ADC and/or a μDMA trigger can be generated. The ADC
    trigger is enabled by setting the TnOTE bit in GPTMCTL and the event that activates the ADC is
    configured in the GPTM ADC Event (GPTMADCEV) register. The μDMA trigger is enabled by
    configuring the appropriate μDMA channel as well as the type of trigger selected in the GPTM DMA
    Event (GPTMDMAEV) register. See “Channel Configuration” on page 683.
    After an event has been captured, the timer does not stop counting. It continues to count until the
    TnEN bit is cleared. When the timer reaches the timeout value, it is reloaded with 0x0 in up-count
    mode and the value from the GPTMTnILR and GPTMTnPR registers in down-count mode.
    Figure 13-3 on page 965 shows how input edge timing mode works. In the diagram, it is assumed
    that the start value of the timer is the default value of 0xFFFF, and the timer is configured to capture
    rising edge events.
    Each time a rising edge event is detected, the current count value is loaded into the GPTMTnR and
    GPTMTnPS registers, and is held there until another rising edge is detected (at which point the new
    count value is loaded into the GPTMTnR and GPTMTnPS registers).

  • Hi Charles 

    I understand. Thanks for help.

    Thanks & Regards,

    Vijay