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.

Compiler/TM4C123GH6PGE: Timer ISR Entry Delay time

Part Number: TM4C123GH6PGE

Tool/software: TI C/C++ Compiler

Hi Charles

Why is there a delay of 800ns when entering an ISR? ?

Attach source code and measurement waveform

//includes
#include <stdint.h> // Variable definitions for the C99 standard.
#include <stdio.h> // Input and output facilities for the C99 standard.
#include <stdbool.h> // Boolean definitions for the C99 standard.
#include "inc/tm4c123gh6pge.h" // Definitions for the interrupt and register assignments.
#include "inc/hw_memmap.h" // Memory map definitions of the Tiva C Series device.
#include "inc/hw_types.h" // Definitions of common types and macros.
#include "inc/hw_gpio.h"
#include "driverlib/sysctl.h" // Definitions and macros for System Control API of DriverLib.
#include "driverlib/interrupt.h" // Defines and macros for NVIC Controller API of DriverLib.
#include "driverlib/gpio.h" // Definitions and macros for GPIO API of DriverLib.
#include "driverlib/timer.h" // Defines and macros for Timer API of DriverLib.
#include "driverlib/pin_map.h" //Mapping of peripherals to pins for all parts.
#include "driverlib/uart.h" // Definitions and macros for UART API of DriverLib.
#include "driverlib/adc.h" // Definitions for ADC API of DriverLib.
#include "driverlib/fpu.h" // Prototypes for the FPU manipulation routines.
#include "utils/uartstdio.h" // Prototypes for the UART console functions.
                             // Needs to add "utils/uartstdio.c" through a relative link.
//definitions
#define UART1_BAUDRATE      115200  // UART baudrate in bps

// function prototypes
void init_timer(void);
void duty_cycle(void);
void init_UART(void);

// global variables
uint32_t sys_clock;
uint32_t  start = 0, end = 0, length = 0;
uint32_t int_flag = 0;

int main(void)
{
    // Configure system clock at 40 MHz
   SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    sys_clock = SysCtlClockGet();
		
    //ISR Processor Cycle 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
		SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
		
		// Enable the processor to respond to interrupts.
    IntMasterEnable();
    
			 
		init_UART();
		UARTprintf("\n TCLK = %d\n" , sys_clock);
		
		// GPIO PD[2]-TA, PD[3]-TB output duration  for  ISR  processing time 
		 GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3  );
		 
    init_timer();
		
    TimerEnable(TIMER0_BASE, TIMER_BOTH);

    while(1){
			GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, ~GPIO_PIN_2);
			
        if (int_flag == 0x1)
        {
            int_flag = 0;
						
				//		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_PIN_2);
            UARTprintf("\nDUTY : %d  =  %d (End) - %d (Start) \n", length, end,start);
    		//		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, 0);

        }
    }
}

void init_timer(void)
{
    // Enable and configure Timer0 peripheral.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
		
    // Initialize timer A and B to count up in edge time mode
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));

    // Timer a records pos edge time and Timer b records neg edge time
    TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    TimerControlEvent(TIMER0_BASE, TIMER_B, TIMER_EVENT_NEG_EDGE);

    //set the value that the timers count 
		// Input signal 20Mhz,  Ts=0.05us  , Sysclk 40Mhz Tc=0.025  , Count = 0.05us/0.025us = 2 (2-1=1 (0x1)	
		// Input signal 1Mhz,    Ts=1us      , Sysclk 40Mhz Tc=0.025  , Count = 1us/0.025us     = 40 (40-1=39 (0x27)		
		// Input signal 500Khz, Ts=2us      , Sysclk 40Mhz Tc=0.025  , Count = 2us/0.025us     = 80 (80-1=79 (0x4F)
		// Input signal 200Khz, Ts=5us      , Sysclk 40Mhz Tc=0.025  , Count = 5us/0.025us     = 200 (200-1=199 (0xC7)
		// Input signal 1Khz,     Ts=1ms     , Sysclk 40Mhz Tc=0.025  , Count = 1ms/0.025us    = 40000 (40000-1=39999 (0x9C3F)
		
    TimerLoadSet(TIMER0_BASE, TIMER_BOTH, 0x4F);
		
    TimerSynchronize(TIMER0_BASE,TIMER_0A_SYNC|TIMER_0B_SYNC );

    //Configure the pin that the timer reads from (PF0)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
		
		//  TM4C Port-F0 unlocked and commit contol register be set.  PA[1:0], PA[5:2] , PB[3:2] , PC[3:0], PD[7], PF[0]
  	HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
	  HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= GPIO_PIN_0;
    
		//  GPIO Configuration , T0CCP0 (TA)-PF[0], T0CCP1(TB)-PF[1]
		GPIOPinConfigure(GPIO_PF0_T0CCP0);		
    GPIOPinConfigure(GPIO_PF1_T0CCP1);
    GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // Timer Interrupt Clear ( TA , TB)
    TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT|TIMER_CAPB_EVENT);
		
    // Enable the indicated timer interrupt source.
    TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT|TIMER_CAPB_EVENT);
		
    // The specified interrupt is enabled in the interrupt controller.
    IntEnable(INT_TIMER0A);
    IntEnable(INT_TIMER0B);

}

// TIMERA , rise edge , Interrupt ISR
 void Timer0AIntHandler(void)
{
		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_PIN_2);
		
    TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
    start = TimerValueGet(TIMER0_BASE, TIMER_A);
		
	  GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, 0);		
}

// TIMERB , fall edge , Interrupt ISR
 void Timer0BIntHandler(void)
{
		GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_PIN_3);
		
    TimerIntClear(TIMER0_BASE, TIMER_CAPB_EVENT);
    end = TimerValueGet(TIMER0_BASE, TIMER_B);
    length = end - start;
    int_flag = 1;
		
	  GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_3, 0);
}


void init_UART(void)
{
    // Enable and configure UART0 for debugging printouts.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, (GPIO_PIN_0 | GPIO_PIN_1));
    UARTStdioConfig(0, UART1_BAUDRATE, sys_clock);
}

CH1 : TimerA(T0CCP0) , CH2: TimerB(T0CCP1), CH3:TimerA-ISR  CH4:TimerB-ISR

  • You should be able enough to answer this now - should you not? (based upon the (extensive) support you've (already) received re: your, "Exact/conforming "Edge-Time" example" (100 postings strong!)

    Your system clock reveals here as 40MHz - thus 25nS/clock. Then - dividing your 800nS (measurement) by the 25nS (clock period) reveals 32 cycles to have elapsed.

    Both the MCU manual & ARM's (more definitive) site detail Interrupts. (to include "latency" - which best describes your issue/request.)

    From the "4C123 manual:"   (Section 1.3.1.3)

    "  ■ Deterministic, fast interrupt processing: always 12 cycles, or just 6 cycles with tail-chaining (these values reflect no FPU stacking) "

    Some way/how your "Entry into the ISR has exceeded the (stated) 12*25=300nS" - has it not?    Why is that - do you suppose?   "YOU should think NOW - rather than reading on!)

    *** (below to be read ONLY after significant poster thought!) ***

    Have you not "burdened" the "measured interrupts" via your addition of the UART & "code logic" which ADDS to the MCU's (admitted) 12 cycle latency?     UARTs (especially) are slow - should not "intrude" into the interrupt process.   (and just maybe - NOW you know why!

    Your (friend) "KISS" strongly suggests that you, "Perform such measurements w/all "other/competing" code operations "Turned OFF" - so that a "Purity of Measure" is best insured.    

  • Hi Jame,

     I think cb1 explains very well on the different components which contribute to the 32 cycles you observe. Let me breakdown some components further.

     When a rise edge is detected it must be first latched (that is one cycle) and then go through a edge detection logic (this is one more cycle). A edge is detection logic is normally a flop followed by a AND gate with a bubble on one of the input terminal.  Once you enter the interrupt you will execute GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_PIN_2). Now let's look at how many cycles constitute this C line code by looking the corresponding assembly instructions. Below is taken from project0 example.

    As you can see it can take about 5+ cycles to execute the GPIOPinWrite(). Finally the write has to travel through the internal MCU interconnect before the GPIO data register is actually written. That can take another cycle. So we are talking about 8 cycles on top of what cb1 just mentioned.

  • Jame,

    Great to see a separate post! Mind me suggest you edit the title to correct the misspelled DEALY, so that others can find it when they search for something related to DELAY?

    1) You system was doing something when the interrupt trigger happened. Most of the actions need to complete to some "safe state" before an interrupt can be serviced. That might take some cycles. If that "something" was UARTprintf("\nDUTY : %d = %d (End) - %d (Start) \n", length, end,start), this would be several cycles...

    2) The execution of GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_PIN_3) also requires some cycles to happen, agree?

    BUT MORE IMPORTANT, this does not matter too much, because the value returned by your TimerValueGet(TIMER0_BASE, TIMER_B) function reflects that instant back when the transition happened, not the moment when you are reading it - so your measurement will still be correct. You just need to be sure to read it before the next triggering occurs.

    Bruno
  • Hi Bruno,
    Thanks. I edited the title.
  • Greetings mes amis: (Bruno & Charles)

    That misspelled "Delay" tormented me - as well.    If (that) "attention to detail" proves lacking - (surely) FAR MORE lurks ahead...    It is poster's "Subject Line" which SELLS his/her post - error there is NOT to be tolerated!   (if posters do not SELL their post - how far are they then, from "begging?")    And - will not such "selling" assist them in their career - tech or otherwise?

    Bruno's excellent "get:" "this does not matter too much, because the value returned by your TimerValueGet(TIMER0_BASE, TIMER_B) function reflects that instant back when the transition happened, not the moment when you are reading it" deserves MULTIPLE (BANNED) LIKEs - was (completely) MISSED by this guy!     (old country would characterize (rightly) as, Dummkopf!)   And that "misunderstanding" appears "duplicated" by our poster.   

    Thanks too to Charles for his "code cycle detail & clarification" (good "care & effort" displayed) - and for restoring (appeal/interest) to poster's, "attention-lite" subject line...  (i.e. if posters "Do not care" - why should the "crack" helper crüe?)

  • Many LIKEs Bruno.

    I'd change the time scale so that only a little over a single cycle was displayed. That will get you both a more accurate and more precise measurement of delay between edges. At coarser time scales the granularity of the measurements is significant.

    One thing that has not been mentioned is that scope capture potentially has much more information to reveal. I know Tek 'scopes have an envelope mode (maybe called something like persistence). By enabling that you can measure the jitter., min and max delays. That gives you insight into the possible sources of delay.

    Robert
  • Robert, *** LIKE *** LIKE ***

    My friend - must devote (some) time to "profit seeking" yet your TAGS (so beyond the (near useless/pedestrian) default ones) make "crack staff & cb1's day!    (so much so that they (staff, call out) "Tag Alert!"    (we ALL know what that means - and "just who" authored!)

    Wild West (even Vancouver) lives on!    (i.e. them thar...I wanna "grab my six-shooter" ...Kill that flawed ICDI)     Our Tek does call it "envelope" btw...

  • Hi Bruno

    Bruno still feels like he doesn't know humility.

    You are proud of the knowledge you know a little bit more than the questioner.

    You seem to be urged to learn humility first rather than to inform the questioner(Also THE FUTURE READERS).

    As shown below.

    Bruno Post>  Does TI ever promised/advertised you they will sell microcontrollers and also make the program for your application?
                          Being critical here won't help, but if that's ALL what it takes to develop products,
                          the lady serving coffee downstairs is a serious competitor to you, Jame shin.

    Bruno Post>  You are one interesting character.
                          Suddenly, your one oscilloscope capture is more reliable than years of engineering design! Well, congratulations!!!
                          No one else has ever performed such test!!!!
                          You just found it, while so many blind engineers got involved with the project and development of applications using
                          these micro controllers for all those years...
                         Call the Nobel Prize organizers, they probably have something waiting for you.

    Bruno Post>  Ti Datasheet 11.3.2.4 " the maximum input frequency for edge detection is 1/4 of the system frequency. "
                           Again, this (grammatically inaccurate) text says DETECTED. There is no lie on this information.
                           As you may suspect, my voluntary contributions to this thread have come to an end.

    Ti engineers I know speak humble and honest.

    And I explain it in detail so that everyone knows.

    regards

  • @Jame,

    You've had "three" outsiders & vendor respond - all aimed to your benefit - might you (consider) their feelings when you "invoke ancient history?"    (rather than respond to the questions & guidance (just today) provided!)

    Not everyone - can at ALL TIMES - behave as a, "Perfect Diplomat."     Perhaps best that you "forgive & forget" and drive toward your "Edge-Time, Jame-driven SOLUTION!"    (note that there is, "NO crying in baseball - and "NO fighting on the forum" (other than my on-going PROTEST over the highly DESTRUCTIVE, UNJUSTIFIED "Banning of LIKE!))    

    I shall depart should this "Motivation & Feedback DEPRIVING Abomination" not be (shortly) rectified...    Clearly the "instigators" of "LIKE's Banning" have little (or NO) knowledge of Control Theory which states that, "Greater rather than Lesser FEEDBACK" is required for BEST SYSTEM PERFORMANCE!     (The "excuse" employed to "justify" LIKE's banning proved NOT sound nor realistic - bordered upon "unbelievable!")

    Bruno (alone) made a significant point in analyzing your code earlier - perhaps your "re-directed focus" to your "issue du jour" rather than (past) comments (perceived as "slights") - moves you closer to your objective.

    I've tried (as well) to provide (some) info of value - as "LIKE" has been banned - we outsiders (must) rely upon "Helped Poster comment/feedback" to maintain (some) level of motivation & feedback...

  • Hi CB1.

    I agree with what you said.
    But I also have feelings.
    Burno speaks very stimulating and critical.
    Thanks to everyone, I am grateful.
    I am sorry if I have any inconvenience from my post.

    fighting with standard "KISS".

    regards.
  • Jame,

    I have no idea what this last post of yours have to do with the current subject.

    From my point of view, you asked a question and I voluntarily stated 3 pieces of information, two of them directly to help you clear your doubt, and the third and more valuable to give you a hint in order as to obtaining good measurements...

    As for my behavior, when someone asks me what color is the sky, I respond "Blue". There is nothing harsh in this, simply plain information - but my engineering background and busy days won't allow me to reply:

    "Oh, dear, there are so many colors out there, which one do you like most? As for the sky, it is mostly blue, isn't honey? I mean, that would be the hue coming to mind, while we can still argue its chromaticity.... I personally get so inspired when, right after sunset, I see all those reddish tones causing a gradient of lower frequency notes into the navyish boredom of usual hours..."

    If you stick to the concept QUESTIONS are given ANSWERS, the forum functionality will maintain a good flow. The current post is called "Timer ISR Entry Delay time", and you received extremely helpful and wise explanations from several posters, for you to understand the factors involved in such delay - don't seek understatements in them, there are none. If there is anything that you could not understand, please get back to us clarifying your remaining doubt, and we shall try to explain further.

    Regards

    Bruno

  • Hi Jame,
    We are all professional. Let's just focus on the technicals. Thanks for your understanding.
  • Dear .   CB1,  Bruno,  Charles,  Robert  Adsett &  all who answered

    Hello 

    Forum Re-departure.

    I explain clearly what I am confused with.

    The maximum input frequency explain an edge time of 1/4 of the system clock frequency.

    Why do I explain this !!

    In other words, If the system clock is 40Mhz, the input frequency is 10Mhz and the edge time is possible.

    However, it is explained that the ISR entry delay time always executes fast interrupts with 12 cycles (25 ns * 12 cycles = 300 ns)

    In fact, it is not, 500Khz and 1Mhz can not execute the edge time function.

    This can be said: It is half a lie.

    The hardware is possible and the software is not.

    Let me give you an example.

    ex> 500khz Input frequency, Ts = 2us, each of two event times is 1us.

    1us / 0.025us = Two event interrupts occur every 40 cycles.

    [Figure 5] Interrupt processing time is 900ns in the previous post show.

    https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/610275/2306651#2306651

    Calculating the cycle need  900ns / 25ns = 36 cycles.

    Therefore, the total minimum cycle = ISR processing cycle + ISR entry delay cycle

    36 cycles + 12 cycles = 48 cycles.

    result : 40 cycle < 48cycle

    There is one more thing.

    There is time to output log message. So you will lose the output log message

    Surprisingly, 1Khz input frequency also loses the message.

    What is the solution to the above problem ?

    Please explain in detail.

    Exceptionally , Jitter should also be discussed, but I would like to say something essential.

    - The engineers I know do not justify actions

       Recognize and accept the wrong parts. talk right.

       I respect all 

    thank you.

  • Hello Jame,

    I will explain to you with as many details as I can think of. Read it calmly, and possibly "separate the pieces of the answer" to comprehend one at a time.

    Each of the specifications on a complex system like an MCU aims to reflect the capacity of that sub-system.  Take for example the ADC module, which converts external analog voltages into digital values. A part such as the TM4C129 has 2 ADC modules, each can sample at a maximum of 2msps. In a direct math, that means 4 million values generated in one second. That is true capacity information.

    But, still in the ADC: if you need to create a system that has to read 4 million analog values per second, store that in memory, compare it to a previous value, and generate an output message to a PC via serial port, then a TM4C129 MCU will by all means NOT BE ABLE to fulfill your needs. Can you appreciate that a complete application is a different issue that one peripheral's specification?

    Now, take the TCCP module. The specification says that, in order for a guaranteed detection, the signal must remain at a given level for at least two clock cycles (25ns in a TM4C123 @80MHz). And the datasheet further explains that "based on this criteria, the maximum input frequency for edge detection is 1/4 of the frequency." (section 13.3.3.3 of a TM4C1294 datasheet)

    This explanation cannot consider the rest of an user's application. If your signal is a continuous 20MHz, and you want to measure each and every rising and every falling transition, record such values, and export to a PC (which we know you don't want, there is no real purpose for such an idea), then you would need a way more complex project, with much more hardware involved.

    So, this is what you can count on your Tiva as far as edge detection: imagine that you have an external signal that has been low for some time, your MCU is "ready to measure", your signal generates a high level signal of 25ns and lowers again (which describes the positive section of a 20MHz rectangular signal), your TM4C123 will surely be able to detect and measure that, do you understand so far?

    Then, after you detected, your application will do other things. In your simple case:

    - Calculate the difference between the edges

    - Convert that to a real time period

    - Originate a human readable message with that value

    - Transmit such message to a PC via serial port

    Have you yet calculated how much time does a text-based message sent to a serial port takes to be sent? It is A LOT OF TIME! This is a good exercise for you: consider how many bytes you message contains, what is the uart speed you are using, and figure out how long does that transmission take. If you wanted to see on a PC terminal "all of your measurements", then you would need to select a message transmission solution that would be faster than the time elapsed between two measurements - and, at 20MHz, not even a standard gigabit ethernet would do!

    I hope this explanation throws some light and helps you draw the border between a peripheral's specification and the overall application requirement.

    What you have not yet told us is what is it that you really need to measure. What is the regularity of your signal? How many actual measurements do you need per second? (Your eyes can't surely read numbers populated at 20MHz) Where do you need to use those measurements - inside the MCU on externally, in a PC? What are your options for transferring the information - only serial port? How long does the measured signal last - just a few seconds, minutes, or continuously?

    All those things are needed for one to engineer a proper solution.

    There are still some ways to make your high frequency signal management more efficient inside a Tiva - but we will be more helpful if you can show us the mission requirements more clearly.

    Regards

    Bruno

  • Well done Bruno, Let me emphasize a  point or two

    Bruno Saraiva said:
    The specification says that, in order for a guaranteed detection, the signal must remain at a given level for at least two clock cycles (25ns in a TM4C123 @80MHz). And the datasheet further explains that "based on this criteria, the maximum input frequency for edge detection is 1/4 of the frequency." (section 13.3.3.3 of a TM4C1294 datasheet)

    Specifically this means that the input will be guaranteed to appear on a pin input register. If the pulse is shorter than that it may not even make it that far. Now what good is that you asks Jame? Well consider something that outputs a single short pulse. If that pulse meets the minimum requirements then you know that the interrupt detection should pick it up. It also tells you what signals frequencies you must filter out to have a glitch free input. This can all be important.

    Also Jame, keep in mind that not all uses of the signal require you to measure the edges, in some cases simply knowing that a change occurred is sufficient. In other cases you would feed this into a counter.

    Personally I've not heard of any signal that required measuring duty cycle at 20MHz. And if I ran across one I don't think a micro would be able to measure, except perhaps on average. Counting, now that's a different prospect.

    Finally, keep in mind that that 20MHz specification is for a 50% duty cycle. As you deviate from that 50% one of the pulses becomes narrower and you can no longer detect it reliably. So it's not even theoretically possibly in the input hardware to measure duty cycle at 20MHz.

    Bruno Saraiva said:
    but we will be more helpful if you can show us the mission requirements more clearly.

    Bruno, you are starting to show some small talent for understatement.

    Robert