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.

TMS320F280040-Q1: Timer interrupt - How does period register control the trigger time?

Part Number: TMS320F280040-Q1
Other Parts Discussed in Thread: SYSCONFIG

Hello, 

I am adjusting the timer interrupt trigger time to nanosecond level. Right now the minimum I got is 2us and the clock is 100MHz.

I tried to change the period register to a smaller value, but seems not changing the trigger time any more. Is 2us is the limit or I miss anything?

It looks that the MCU doesn't got much time to run when keeping handling 2us timer interrupt. 

Thanks!

Crane

  • Crane,

    The subject matter expert will get back to you on Monday.

    Thanks & Regards,

    Santosh

  • Hello Crane,

    It may be the case that the ISR used to handle the interrupt takes enough time to handle that by the time the interrupt can trigger again, it's already missing an interrupt (for periods less than 2 us). I still need to look into this to see if I can find some explanation, but in the mean time can you tell me how you handle the interrupt, and what if anything do you include in your ISR?

    Best regards,

    Omer Amir

  • Thanks Omer for your reply.

    Right now I am checking to find out the shorted time to trigger a timer interrupt and see if it can be shorter than 1us. So in ISR, there is only a statement to toggle two GPIOs and increase a count.

  • Hello Crane,

    So far, there are a few things that may effect how fast a CPU timer interrupt can be triggered/handled. The first is the time it takes to leave the main program to handle an ISR, which may take a few clock cycles, but not too many. The next is the instructions within the ISR. In your case, if you are running the program directly from RAM, then there is at least a 40 ns delay for this device for toggling the GPIO, and perhaps another 1 cycle to increment a counter (10 ns). This can be increased significantly when running from Flash because of the wait states required to read instructions.

    I do not yet have the amount of clocks it takes to jump to/from an ISR, so I'll have to get back to you on that, but so far these are the things that would normally affect overall timing.

    Best regards,

    Omer Amir

  • Ok got it. Thanks Omer.

    If this is the case, it brings up two questions:

    1. You mean the time that triggered is not just decided by the settings when the timer is initialized, but also the time MCU uses to handle the interrupt? I changed the settings from 2us trigger to 1us trigger, what I observe is still strictly 2us, not seems like shorter a little bit. If the MCU's handling the interrupt impacts what I observe, I don't think the trigger would still be exactly 2us.

    2. If it would take MCU around 100ns to handle the interrupt running from RAM, it will not leave much time for MCU to do other things when the interrupt trigger time is set as 1us or even 500ns, let alone running from FLASH. So I think in real application, it is no point to set interrupt timer trigger time so short, right?

    Thanks!

    Crane

  • Hello Crane,

    I will do some investigation on my side and get back to you as soon as I have a more definitive answer.

    Best regards,

    Omer Amir

  • Hi Crane,

    Just giving you an update. I was able to replicate a similar timing situation that you were seeing, although I created a project with nothing but the timer and had a minimum period of 2.6 us (1.3 us between toggling a GPIO). I'm working with some other experts to try and discover why this is occurring, so I'll get back to you once I have an answer.

    Best regards,

    Omer Amir

  • Thanks Omer for the update. 

  • Hello Crane,

    After some more testing, I was able to get the timer interrupt to trigger about every 380 ns with only a GPIO toggle instruction and interrupt clearing instruction within the ISR (or 33 cycles using just the interrupt clearing statement). However, to do this I had to create my own versions of the driverlib functions that do the same actions, only trimmed down so that excess math like adding and casting were done by the time the ISR was reached. Essentially, I had to create a hard-coded version of the functions to clear only 1 interrupt and toggle only 1 GPIO.

    If this fits with the case you intend to use the CPU timer for, let me know and I can attach the example that I created. If you have further questions, or if this does not meet the specification you require, let me know as well.

    Best regards,

    Omer Amir

  • Thanks Omer for your efforts!

    Ok, which means the parameter temp for this function CPUTimer_setPeriod(cpuTimer, temp) indeed won't work to make the interrupt trigger time shorter than 2us. As the function writes numbers to register, I am still wondering why changing the value of the register doesn't work. 

    I am not exactly sure what you mean saying " clear only 1 interrupt and toggle only 1 GPIO"? What I need is to generate a waveform with 450+/-150num high and 850+/-150ns low as 0 and vice versa as 1.

    By the way, is the timer counter accessible or it can only be used to generate timer interrupt?

    Thanks!

    Crane

  • Hello Crane,

    I am still wondering why changing the value of the register doesn't work.

    If you're talking about why changing the timer's period doesn't change the actual time it takes between leaving and entering an ISR, it's because the timer is delayed by the fact that the interrupt takes longer to handle than the timer's period will allow. In essence, the interrupt is triggered again before the previous interrupt can finish being handled. Thus, it's stuck at handling the ISR as fast as it can, at a constant speed. If you remove everything except the interrupt clear instruction from your ISR, you should see the timing change.

    I am not exactly sure what you mean saying " clear only 1 interrupt and toggle only 1 GPIO"? What I need is to generate a waveform with 450+/-150num high and 850+/-150ns low as 0 and vice versa as 1.

    When I was testing to get the minimum allowable period from the timer, I only put 2 instructions within my ISR: an instruction to toggle the output of a GPIO pin and an instruction to clear the interrupt flag. I'm not sure if you'll be able to do 450 +/-150 as a period, at least from how far I was able to push my code. You can get close, but I couldn't quite get down to 300 ns as a minimum.

    By the way, is the timer counter accessible or it can only be used to generate timer interrupt?

    Yes, looking at the technical reference manual, the current count of the timer can be accessed using the TIM register in the CPUTIMER_REGS timer registers. (Section 3.14.5.1, or page 228).

    Best regards,

    Omer Amir

  • Ok, it seems that if I generate an interrupt every 450ns, it can only toggle the pin and clear the interrupt. If anything else needs to be done, it won't be able to handle it, right?

  • Hello Crane,

    Essentially yes, as with any microcontroller, adding an instruction within an interrupt handler will increase the time it takes for that same interrupt to be triggered again (given that the interrupt is cleared at the end of the handler). It should be able to toggle the GPIO pin just fine, if that's all it's doing. I've attached the main code I used in my example to get this timing (I imported an empty F28004x project to start off with and used SysConfig to initialize the timer).

    Best regards,

    Omer Amir

    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "c2000ware_libraries.h"
    
    #define HWREG32(x) (*((volatile uint32_t *)(x)))
    #define HWREGH(x) (*((volatile uint16_t *)(x)))
    uint32_t *gpioDataReg = (uint32_t *)((uintptr_t)GPIODATA_BASE) + ((myGPIO0 / 32U) * GPIO_DATA_REGS_STEP);
    uint16_t interruptClearReg = PIECTRL_BASE + PIE_O_ACK;
    uint32_t gpioToggleValue = (uint32_t)1U << (myGPIO0 % 32U);
    
    void main(void)
    {
        Device_init();
        Device_initGPIO();
        Interrupt_initModule();
        Interrupt_initVectorTable();
        Board_init();
        C2000Ware_libraries_init();
        EINT;
        ERTM;
    
        while(1);
    }
    
    __interrupt void INT_myCPUTIMER0_ISR(void)
    {
        //GPIO_togglePin(myGPIO0)
        gpioDataReg[GPIO_GPxTOGGLE_INDEX] = gpioToggleValue;
    
        //Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
        HWREGH(interruptClearReg) = 0x1;
    }
    

  • Thanks a lot Omer! I will try it later to see if it work for my application.

  • No problem, let me know if you have further questions or if this resolves your issue.

    Best regards,

    Omer Amir

  • Hello Crane,

    I forgot to mention that you can turn on optimizations in the project properties, and it should allow the program to trigger the interrupt more efficiently using the driverlib functions (see the driverlib function calls I commented out above). This even triggered faster than the hard-coded values I used.

    I was also discussing your post with some colleagues, and I was wondering if there was a reason you're not using the ePWM to generate your waveform? I was able to generate a PWM within your required margin of error (500 ns high and 810 ns low). It might be better to use this if you want to have your system available for other actions.

    You can use this video series if you need help setting up the peripheral: https://training.ti.com/enhanced-pulse-width-modulator-epwm-training-c2000-mcus?context=1137766-1149551

    Best regards,

    Omer Amir

  • Thanks Omer for the update!

    I haven't gotten a chance to look at how to use ePWM to do that. One question was if ePWM is able to generate the waveform which has different pulses for each period. I am doing tests out of town and will take a look at the video later.

    Best regards,

    Crane

  • Crane,

    You cam modulate the duty-cycle of PWM. Please take a look C2000 Academy lab.

    https://dev.ti.com/tirex/explore/node?node=A__Adlf59dR9TRikXjOlRRRsg__c2000Academy__jEBbtmC__LATEST 

    Regards,

    Santosh

  • Crane you are definitely going to be able to generate PWM pulse with different duties every period. You can review this document along with the academy videos mentioned by Santosh to achieve this.

    www.ti.com/.../sprad12.pdf

    Nima