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.

Periodic timer interrupt too slow

Genius 5820 points
Other Parts Discussed in Thread: AM3358, AM3359

Hi,

I created a small BeagleBone test-application that makes use of DMTimer2 to create a (fast) periodic interrupt. This test-application mainly uses code out of the examples that come with starterware. Unfortunately it is not as fast as expected. Currently I'm not sure if only the first interrupt comes with expected speed (altough I'ml already using auto-reload via flag DMTIMER_AUTORLD_NOCMP_ENABLE) or if the clock source is not CLK_M_OSC (but DMTimer2ModuleClkConfig() is setting the correct clock source). That's what I'm doing to initialise the timer-IRQ:

DMTimer2ModuleClkConfig(); // should select 24 MHz CLK_M_OSC as clock source

IntMasterIRQEnable();
IntAINTCInit();
IntRegister(SYS_INT_TINT2, isr_func);
IntPrioritySet(SYS_INT_TINT2, 0, AINTC_HOSTINT_ROUTE_IRQ);
IntSystemEnable(SYS_INT_TINT2);

DMTimerCounterSet(SOC_DMTIMER_2_REGS,0xFFFFFFF9); // load initial value
DMTimerReloadSet(SOC_DMTIMER_2_REGS, 0xFFFFFFF9); //...and reload value
DMTimerModeConfigure(SOC_DMTIMER_2_REGS, DMTIMER_AUTORLD_NOCMP_ENABLE); // auto-reload and overflow, so this should appear periodically

DMTimerIntEnable(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_EN_FLAG);
DMTimerEnable(SOC_DMTIMER_2_REGS);

My ISR looks like this:

static void isr_func()
{
   static int clockCtr=0;
   static int ledCtr=0;
   // DMTimerIntDisable(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_EN_FLAG); not sure regarding these functions, it does not seem to make a difference if they exist or not, but in my opinion it would be good to not to disable the interrupt to keep the interrupt frequency stable (ISR code in this case must be faster than the frequency itself of course)
   // DMTimerIntStatusClear(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_IT_FLAG);

   ledCtr++;
   clockCtr++;

   // some code here...

   /* Re-enable the DMTimer interrupt */
   // DMTimerIntEnable(SOC_DMTIMER_2_REGS, DMTIMER_INT_OVF_EN_FLAG);
}

Any ideas what could be wrong?

Thanks!

  • Meanwhile I did some experiments using dmtimerCounter-example out of Starterware. Instead of console output I'm toggling a GPIO on every call of the ISR to check the frequency with an oscilloscope. This works well with the timer and reload count of 0xFF000000u (default of the example). It also works with a timer/reload count of 0xFFFFFE00u but the ISR is called only once when I use timer/reload counts of 0xFFFFFF00u or bigger.

    So it seems smaller prescaler/counter values/higher interrupt frequencies fail for some reason. What could cause this?

    I also found my Beagleboard is using an AM3359 processor and not the AM3358 - could this make a difference?

    Thanks!

  • Hi Hans,

    Usage of AM3359 instead of AM3358 should not cause this behaviour.

    Can you try by placing a breakpoint at the ISR and check how many times the ISR is hit. Or a variable which is incremented in the ISR also can give  a clue. Why i am saying this is the overflow value is very small and hence it may seem that the ISR is not hit. At the end of application the variable count can give a clue.

    Regards,

    Jeethan

  • I have tried the same code (like dmtimer example) because i have trouble with the SPI Interrupt.

    This code above is not running on my system. Configurations are done right, in the ISR i toggle a GPIO(to verify with an oscilloscope).

    After the function DMTimerEnable(SOC_DMTIMER_3_REGS); is called, the program in debug mode hangs somewhere? In Interrupt?

    The following system_printf´s or the BiosStart(); would not be executed.

    @Hans, the DmTimer2 with your code works fine?

    I uses additional this to select the M-OSC:

    *((unsigned int*) 0x44E00508) = 0x00000001;        // CM_DPPL + CLKSEL_TIMER2_CLK Register (offset = 8h) = 0x1 
  •  @Jeethan: I added a counter to the ISR and a delay to the main function atfer that the counter was printed to serial console.

    With timer values of 0xFFFFFE00u the ISR is called about 154000 times, with timer values of 0xFFFFFF00u it is called only once.

    And I notices some more: With a timer value of 0xFFFFFF00u the ISR is called only once during my delay (nearly immediately), than for a very long time of approximately some minutes it was not called and after that time it was called regularly and possibly (I'm currently really not sure) with the desired frequency. So it seems only the second timer counter value is wrong for some reason.

    @Daniel: With lower IRQ-frequencies the code from dmtimer-example works fine for me. 

  • Hi Hans,

    The Timer overflow value is very small in terms of nanoseconds. Even i tried the following and it seems the software latency is more than the overflow time and hence the example is not working as expected. However the ISR is getting hit and the count value i am seeing is 358.

    May i know your requirement for timer? What is the overflow value required for your application?

    Regards,

    Jeethan 

  • Hi Jeethan,

    I'm planning to do some bit-banging on some GPIOs, means generating some defined signals there. That's what I calculated:

    M_CLK_OSC is 24 MHz. With a prescaler value of 6 (yes, I know, very small) I get a IRQ-frequency of 4 MHz. With the CPU on 1 GHz the maximum number of clock cycles I could use within this ISR is 250 (going to that maximum of course would stall the system completely).

    Currently I'm only incrementing two int-variables, doing a comparison and writing to two GPIOs. This code should be far below these 250 cycles. Thus I'm a bit amazed that I'm already above the limit.

    Should the ISR and used variables be moved from DDR-RAM to internal SDRAM? How can I tell the linker to do that?

    Cheers

    Hans

  • @Hans: I dont want to open a new similar thread, if its okay.

    I have the ISR like you, but i´m toggling a GPIO. And i have uncommented

     DMTimerIntDisable(),IntStatusClear() and IntEnable().

    This is my INT and DMTimer setup:

    	DMTimer3ModuleClkConfig();
    *((unsigned int*) 0x44E0050C) = 0x00000001;		// CM_DPPL + CLKSEL_TIMER3_CLK Register (offset = Ch) = 0x1 = SEL2 : Select CLK_M_OSC clock
    IntMasterIRQEnable();
    	IntAINTCInit();
    	IntRegister(SYS_INT_TINT3, timer3isr);
    	IntPrioritySet(SYS_INT_TINT3, 0, AINTC_HOSTINT_ROUTE_IRQ);
    	IntSystemEnable(SYS_INT_TINT3);
    
    	DMTimerCounterSet(SOC_DMTIMER_3_REGS,0xFFFFFC17); // load initial value c17 = delta 1000dec b4f = delta 1200
    	DMTimerReloadSet(SOC_DMTIMER_3_REGS, 0xFFFFFC17); //...and reload value
    	DMTimerModeConfigure(SOC_DMTIMER_3_REGS, DMTIMER_AUTORLD_NOCMP_ENABLE); // auto-reload and overflow, so this should appear periodically
    	*((unsigned int*) 0x48042034) |= 0x00000002; // IRQWAKEEN wakeup generation for Overflow
    
    	DMTimerIntEnable(SOC_DMTIMER_3_REGS, DMTIMER_INT_OVF_EN_FLAG);
    
    DMTimerEnable(SOC_DMTIMER_3_REGS);

        Can you give me a hint ? Why the the GPIO is not toggling? How i can see when the ISR will be called?

  •  @Daniel: find my code at http://pastebin.com/sNpmTtnt

     master_irq_init() is the entry point. It toggle one GPIO output on every ISR call and blinks a LED on a lower, visible frequency.

  • Thank you Hans.

    It´s curious. I hav adjusted my Code (= http://pastebin.com/8X3ZFcGJ )

    to yours (it was already the same except the strucutre) and its not working. It seems that the ISR is not called.

    Can you have a look?

  • Hi Daniel,

    why don't you simpyl use the dmtimer-Example , check if it works and then add your specific code step by step. When your ISR is not working at some point, the lines of code you added last cause the troubes.

    Hans