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.

How to set timer interrupt period in C6748?

Hello everyone.

I compiled starware example code using C6748 LCDK.

I want to set interrupt period 2MHz. but in example the period is about 1 second.

I found a fuction and defined value

    TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER12, TMR_PERIOD_LSB32);
    TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER34, TMR_PERIOD_MSB32);

#define TMR_PERIOD_LSB32               (0x07FFFFFF)   
#define TMR_PERIOD_MSB32               (0x0)

I chagned the value and period became more fast.

#define TMR_PERIOD_LSB32               (0x01)  
#define TMR_PERIOD_MSB32               (0x0)

But not enough to my application. So i think there is other register to set period of timer.

But in example code there is no other thing to set most fuctions are extern vold type.

How can make timer period more fast?

And i have another question. In startware exaplme i can't use register(ex TIM12, PRD12) in technical reference manual. compile error happened.

Why?

Thanks.

  • Please refer to this e2e thread for response on setting Timer using Starterware code:
    e2e.ti.com/.../1184825

    Regards,
    Rahul
  • Timer 2 is clocked by SYSCLK2, from C6748_LCDK.gel:
    PLLM = 24
    POSTDIV = 1
    PLLDIV2 = 1
    OSCIN = 24khz
    PLL0 = OSCIN * (PLLM+1) / (POSTDIV+1)
    PLL0 = 24khz * (24+1) / (1+1)
    PLL0 = 300MHz
    SYSCLK2 = PLL0 / (PLLDIV2+1)
    = 300Mhz/(1+1)
    = 150Mhz -> 6.666ns period

    With MSB = 0x7FFFFFF = 134217727 counts, the timer period is 0.894784s. Close enough to 1s allowing for latency and overhead.

    For 2Mhz timer frequency, that is a period of 500ns. The count for that would be 75. Set TMR_PERIOD_LSB32 to 75. Or a bit less to allow for latency and overhead.

    Note that with a 2Mhz timer frequency, the the number of processor clock cycles is only 150 cycles between timer interrupts. Unlkely you can service you timer interrupt before you have to start another.

    Setting TMR_PERIOD_LSB32 to 1 would mean that you are executing the timer ISR every 13.333ns or every 4 cycles. Very unlikely that you can service the interrupt in that time. You will be missing interrupts. Whatever service frequency you are seeing in this case will be the time required to run the ISR code.
  • Thank to reply, Norman Wong

    I tried that you recommanded. I changed LSB = 75 and I increase 1 per  timer ISR to show what count would increase per second.

    The variable increase about 60,000 count per second. It is different we expected.

    And I changed LSB value; 75/100/1000/10000

    The variable increase about 60,000 count per second in LSB = 75/100/1000 and16,000 count in LSB = 10000

    In my example code there is nothing except for setting timer ISR.

    I still don't know why period is not match i calculated.

    and I have another question.

    How i see .gel file??? in many Q&A, people said about 'gel file' but i can't find the file in my project.

    Thanks.

    timerCounter.c
    
    
    
    
    
    
    
    
    
    
    
    /**
     * \file  timerCounter.c
     *
     * \brief Sample application for timer.
     */
    
    /*
    * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 
    *
    *  Redistribution and use in source and binary forms, with or without 
    *  modification, are permitted provided that the following conditions 
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the   
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    #include "uart.h"
    #include "hw_uart.h"
    #include "interrupt.h"
    #include "soc_C6748.h"
    #include "hw_syscfg0_C6748.h"
    #include "timer.h"
    #include "lcdkC6748.h"
    #include "uartStdio.h"
    
    
    
    
    #ifndef _TMS320C6X
    #include "cpu.h"
    #endif
    
    /******************************************************************************
    **                      INTERNAL MACRO DEFINITIONS
    *******************************************************************************/
    #define STR_LEN                        (13)
    //#define TMR_PERIOD_LSB32               (0x07FFFFFF)			// clear lsc
    //#define TMR_PERIOD_MSB32               (0x0)						// clear lsc
    #define TMR_PERIOD_LSB32               (10000)				// insert lsc    0x07FFFFFF = 134217727
    #define TMR_PERIOD_MSB32               (0x0)						// insert lsc
    
    
    /******************************************************************************
    **                      INTERNAL FUNCTION PROTOTYPES
    *******************************************************************************/
    static void TimerIsr(void);
    static void TimerSetUp64Bit(void);
    static void TimerIntrSetUp(void);
    
    /******************************************************************************
    **                      INTERNAL VARIABLE DEFINITIONS
    *******************************************************************************/
    static unsigned char cntArr[9] = {'8', '7', '6', '5', '4', '3', '2', '1', '0'};
    static volatile unsigned int secCnt = 0;
    static volatile unsigned int flagIsrCnt = 0;
    
    /******************************************************************************
    **                          FUNCTION DEFINITIONS
    *******************************************************************************/
    
    long count_1 = 0;
    
    
    int main(void)
    {
    
    
    
        /* Set up the UART2 peripheral */
        UARTStdioInit();
    
        /* Set up the Timer2 peripheral */
        TimerSetUp64Bit();
    
        /* Set up the AINTC to generate Timer2 interrupts */
        TimerIntrSetUp();
    
        /* Enable the timer interrupt */
        TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
    
    #ifndef _TMS320C6X
        /* Switch to non privileged mode; This is done for demonstration purpose */
        CPUSwitchToUserMode();
    #endif
    
        /* Send the first String */
        UARTPuts("Tencounter: 9", -1);
    
        /* Start the timer. Characters from cntArr will be sent from the ISR */
        TimerEnable(SOC_TMR_2_REGS, TMR_TIMER12, TMR_ENABLE_CONT);
    
        /* make sure all the characters from cntArray from ISR */
    
    
    
    	while(1);
    
    
    
    }
    
    /*
    ** Timer Interrupt Service Routine
    */
    
    int count_2 = 0;
    int count_3 = 0;
    int count_4 = 0;
    
    
    static void TimerIsr(void)
    {
        /* Disable the timer interrupt */
        TimerIntDisable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
    
        	count_1++ ;
    
    #ifdef _TMS320C6X
        /* Clear interrupt status in DSPINTC */
        IntEventClear(SYS_INT_T64P2_TINTALL);
    #else
        /* Clear the interrupt status in AINTC */
        IntSystemStatusClear(SYS_INT_TIMR2_ALL);
    #endif
        TimerIntStatusClear(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
    
        /* Signal application to print a new character */
        flagIsrCnt = 1;
    
        /* Enable the timer interrupt */
        TimerIntEnable(SOC_TMR_2_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
    }
    
    
    /*
    ** Setup the timer for 64 bit mode
    */
    static void TimerSetUp64Bit(void)
    {
        /* Configuration of Timer */
        TimerConfigure(SOC_TMR_2_REGS, TMR_CFG_64BIT_CLK_INT);
    
    
    
        /* Set the 64 bit timer period */
        TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER12, TMR_PERIOD_LSB32);
        TimerPeriodSet(SOC_TMR_2_REGS, TMR_TIMER34, TMR_PERIOD_MSB32);
    }
    
    /*
    ** Set up the ARM Interrupt Controller for generating timer interrupt
    */
    static void TimerIntrSetUp(void)
    {
    #ifdef _TMS320C6X
        /* Initialize the DSPINTC */
        IntDSPINTCInit();
    
        /* Register the Timer ISR */
        IntRegister(C674X_MASK_INT4, TimerIsr);
    
        /* Map Timer interrupts to DSP maskable interrupt */
        IntEventMap(C674X_MASK_INT4, SYS_INT_T64P2_TINTALL);
    
        /* Enable DSP interrupt in DSPINTC */
        IntEnable(C674X_MASK_INT4);
    
        /* Enable DSP interrupts */
        IntGlobalEnable();
    #else
        /* Initialize AINTC and register timer interrupt */
        IntAINTCInit();
        
        /* Register the Timer ISR */
        IntRegister(SYS_INT_TIMR2_ALL, TimerIsr);
      
        /* Set the channel number for Timer interrupt, it will map to IRQ */
        IntChannelSet(SYS_INT_TIMR2_ALL, 2);
       
        /* Enable IRQ for ARM (in CPSR)*/
        IntMasterIRQEnable();
      
        /* Enable AINTC interrupts in GER */
        IntGlobalEnable();
    
        /* Enable IRQ in AINTC */
        IntIRQEnable();
    
        /* Enable timer interrupts in AINTC */
        IntSystemEnable(SYS_INT_TIMR2_ALL);
    #endif
    }
    /***************************** End Of File ***********************************/
    

  • With a LSB of 10000, the expected timer period would be 10000*6.666ns or 66666ns or 15000Hz. That is close to your observation of 16000. I am assuming you are just roughly starting and stopping the code for roughly one second. Human reaction time would explain the difference.

    Your observation of 60000 counts for an LSB of 75/100/1000 implies that the ISR took 1/60000 second or 16666ns. That would suggest that the minimum count you can load into the timer is 16666.666/6.666 or 2500, ie 60kHz. You cannot use a value oF LSB lower than 2500 with the current code. The number of CPU clock cycles would be 16666.666/3.333 or 5000. That does seem like a lot of cycles. You should trace the code from intvecs.asm to interrupt.c to timerCounter.c. There is quite a bit of code. For example, VEC_ENTRY will save/restore all registers to/from memory. Memory accesses can take more than one cycle if the memory is slow. All that will take time. It also takes some time for an interrupt to be recognized by the processor and acted upon. This is before the first code is even run. Somewhere in the datasheet are interrupt latency times.

    Odds are is that your code is running from DDR. That is quite a bit slower than internal L2 SRAM. You could change your linker ".cmd" file to put your code and data into L2. That should make it faster but I really doubt you can achieve 2MHz.

    You could try using a polled IO instead of a interrupt. It seems counter-intuitive but polling code can execute faster than interrupt driven code. So instead of using ISR code, poll the timer registers from main().

    If a GEL script is the build directory, CCS is likely using a GEL script from the CCS install directory or the StarterWare folder. Check you project options for specification of a GEL file. I don't have accecss to a development machine any more. I vaguely rememberit in the debug options.

    What are trying to do? It is very unlikely you can achieve a 2MHz timer. You will have to use a different approach, eg. different peripheral.