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.

TMS320F28386S: Timer examples

Part Number: TMS320F28386S

I would much appreciate a timer example for the F28386 that sets it up as a one-shot and fires an interrupt at conclusion of count.

Thanks,

JH

  • Hello John,

    There isn't an example for a one-shot timer, but I've written a main.c file you can use based on the existing example for CPU timers. You need to enable the interrupt to fire at the end of the count, and within the interrupt service routine you disable the interrupt to prevent it from firing again. I hope this is useful:

    #include "driverlib.h"
    #include "device.h"
    
    uint16_t reached = 0;
    
    __interrupt void cpuTimer0ISR(void);
    void initCPUTimer(void);
    void configCPUTimer(uint32_t cpuTimer, uint32_t period);
    
    void main(void)
    {
        Device_init();
        Interrupt_initModule();
        Interrupt_initVectorTable();
        Interrupt_register(INT_TIMER0, &cpuTimer0ISR);
    
        initCPUTimer();
        configCPUTimer(CPUTIMER0_BASE, 100);
    
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        EINT;
        ERTM;
    
        while(1);
    }
    
    void initCPUTimer(void)
    {
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
        CPUTimer_stopTimer(CPUTIMER0_BASE);
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    }
    
    void configCPUTimer(uint32_t cpuTimer, uint32_t period)
    {
        CPUTimer_setPeriod(cpuTimer, period);
        CPUTimer_setPreScaler(cpuTimer, 0);
    
        CPUTimer_stopTimer(cpuTimer);
        CPUTimer_reloadTimerCounter(cpuTimer);
        CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
        CPUTimer_enableInterrupt(cpuTimer);
    }
    
    __interrupt void cpuTimer0ISR(void)
    {
        reached = reached + 1;
        CPUTimer_disableInterrupt(CPUTIMER0_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    

    Best regards,

    Omer Amir

  • Thanks for the post.

    I modified the while loop and it seems the ISR is invoked twice.

        while(1)
        {
            static uint16_t reachedCopy = 0;
            if (reached)
            {
                reachedCopy++;
            }
        }

    Also what changes would I make in the while loop so the timer is set again?

    Thanks,

    John

  • Hello John,

    To re-enable the ISR to trigger at the end of the timer, you can use "CPUTimer_enableInterrupt(CPUTIMER0_BASE);". The counter is still technically going on in the background, which is something I forgot to account for. I've updated my code to now disable the counter in the interrupt instead, and re-enable it within the while loop (the interrupt needs to be re-enabled in both cases).

    I'm not sure how you're getting the ISR invoked twice, when I run my code the "reached" variable is only ever set to 1 (any time it hits the ISR, it will increment "reached"). Your modified while loop assumes that "reached" gets reset, which is not the case, so "reachedCopy" will always be incremented. That may be why it seems like your ISR is invoked more than once.

    #include "driverlib.h"
    #include "device.h"
    
    uint16_t reached = 0;
    
    __interrupt void cpuTimer0ISR(void);
    void initCPUTimer(void);
    void configCPUTimer(uint32_t cpuTimer, uint32_t period);
    
    void main(void)
    {
        Device_init();
        Interrupt_initModule();
        Interrupt_initVectorTable();
        Interrupt_register(INT_TIMER0, &cpuTimer0ISR);
    
        initCPUTimer();
        configCPUTimer(CPUTIMER0_BASE, 100);
    
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        EINT;
        ERTM;
    
        while(1)
        {
            if(reached)
            {
                CPUTimer_enableInterrupt(CPUTIMER0_BASE);
                CPUTimer_startTimer(CPUTIMER0_BASE);
            }
        }
    }
    
    void initCPUTimer(void)
    {
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
        CPUTimer_stopTimer(CPUTIMER0_BASE);
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    }
    
    void configCPUTimer(uint32_t cpuTimer, uint32_t period)
    {
        CPUTimer_setPeriod(cpuTimer, period);
        CPUTimer_setPreScaler(cpuTimer, 0);
    
        CPUTimer_stopTimer(cpuTimer);
        CPUTimer_reloadTimerCounter(cpuTimer);
        CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
        CPUTimer_enableInterrupt(cpuTimer);
    }
    
    __interrupt void cpuTimer0ISR(void)
    {
        reached = reached + 1;
        CPUTimer_stopTimer(CPUTIMER0_BASE);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    

    Best regards,

    Omer Amir

  • Thanks for the help.

    Apologies for the bad while loop. I only partially copied it by mistake and then the next mistake was to add the two closing braces. The variable reach was reset at the end of the if (reached) conditional. Good catch on your part.

    I set a breakpoint at line 31 and on the first stop the value of reached was 2. I changed the value in line 18 from 100 to 100000 and ran it again. This time reached was 1. So that clears that up.

    Could you tell me why all of the functions called in the init function are also called in the config function? Also, I have not been using CPUTimer_reloadTimerCounter() as it seemed that CPUTimer_setPeriod() set the value. The documentation is a bit sparse so what does this function really do and when is it needed?

    Thanks again,

    John

  • Hello John,

    Could you tell me why all of the functions called in the init function are also called in the config function? Also, I have not been using CPUTimer_reloadTimerCounter() as it seemed that CPUTimer_setPeriod() set the value. The documentation is a bit sparse so what does this function really do and when is it needed?

    I copied the code from the timer_ex1_cputimers example. Looking at that, it seems like initCPUTimers initializes all the CPU timers to a baseline/default configuration. The configCPUTimer function then allows you to configure a specific CPU timer (0, 1, or 2) and set it's frequency/period (I modified it to just configure the CPU timer period).

    I've already answered the next part of your question in the other post you created, so I'll include my response below:

    "The value of the period is set using the CPUTimer_setPeriod() function, but the CPUTimer_reloadTimerCounter() function sets the TRB bit in the TCR register. This loads the timer counter TIMH:TIM with the period so that it is essentially starting the counter from the beginning (the counter decrements the loaded period value). This bit also loads the prescale counter PSCH:PSC with the timer dividedown TDDRH:TDDR value."

    You can find out more about this in the "CPUTIMER_REGS Registers" section of the technical reference manual (section 3.14.8). Let me know if you have any other questions.

    Best regards,

    Omer Amir

  • Thanks for repeating. I did not see a response notification for the other thread. Will take a look now.