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.

TMS320C6678: DSP c6678裸核下,如何实现定时器中断?

Part Number: TMS320C6678

在裸核开发下,在PDK的CSL的库想使用Soc内部定时器8-15中一个实现通用 64bit定时器自动加载模块,以定期器周期产生中断输入,然后实现中断功能。

初次开发DSP处理器, 非常白,想咨询一些问题。

1.首先,定时器软件框架如下:

int8_t timer_led(uint8_t instance, uint32_t timer_clk_freq)

{

   CSL_TmrObj TmrObj; //Tmr struct
   CSL_TmrHandle hTmr; //hTmr->TmrObj
   CSL_Status status; //
   CSL_TmrHwSetup hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
   CSL_TmrEnamode TimeCountMode = CSL_TMR_ENAMODE_CONT;

/* Clear local data structures */
memset(&TmrObj, 0, sizeof(CSL_TmrObj));

 CSL_BootCfgLockKicker();

 hTmr = CSL_tmrOpen(&TmrObj, instance, NULL, &status);

 hwSetup.tmrTimerPeriodLo = period;  //设定定时器周期计数数

/* Clock mode for timerLow output */
hwSetup.tmrClockPulseLo = CSL_TMR_CP_CLOCK;

CSL_tmrHwSetup(hTmr, &hwSetup);

/* Reset the 64-bits low Timer */
CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET64, NULL);  //选择CSL_TMR_CMD_RESET64模式不知道是否正确?

/* Start the timer in CONTINUOUS Mode . */
CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START64 , (void *)&TimeCountMode);

}

这样实现通过自动加载的64位定时程序正确吗?程序运行了,感觉运行基本正常。

2.C6678的核心中断中有定时器中断,下步只通过INTC配置直接产生一级中断给CPU,不行CIC配置。这样方式对吗?

3。上图定时器8中断时间对应Input event number 66和67 ,描述中 Timer interrput low和Timer interrput  high对应什么?是中断出发电平?

我采用通过64位定时器产生中断时,Timer interrput low和Timer interrput  high都有输出?

4。请问现在针对C6678裸核中断,官方还有什么案例参考?

  • 1. 请问这是哪里的代码?如果能按照预设的时间中断的话,说明设置正确了。

    2. 请问是怎么配置的? 可以看一下附件的中断说明文件。

    4111.Configuring Interrupts on Keystone Devices.pdf

    3. 跟触发电平无关,分别是高32bit timer和低32bit timer中断。

    4. 可以参考C:\ti\C6678 SDK 5.03\pdk_c667x_2_0_13\packages\ti\csl\example\timer

  • Hi,Shine

     非常感谢,你的回复。

    1. 请问这是哪里的代码?如果能按照预设的时间中断的话,说明设置正确了。代码是公司购买DSP6678开发板里面带的,过去是代码是32bit 独立定时结构,只是实现了定时点亮LED功能。我现在修改了配置, 更改了CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START64 , (void *)&TimeCountMode)。

    我想继续问下,如果让这个连续自动加载的模式的运行,函数内容不能执行 CSL_tmrClose(wdTmr),如果执行定时就停吧。

    2.请问是怎么配置的? 可以看一下附件的中断说明文件?

    昨天参考了,cpintc_test.c的参考代码,制作一版程序。自己先调试下,再有什么问题再问你 。有空帮我回答下,谢谢了。

    3. 跟触发电平无关,分别是高32bit timer和低32bit timer中断。

    如果定时8器设置为一个64bit 定时器,timer output(TOUTL)如果输出正常话,那么Interrupt(TINTLO) to cpu引脚会产生一个EVT的输出吗?

    我的疑问是 核心中断66(TINH8L)和核心中断67(TINH8H),这个Interrupt(TINTLO) to cpu应该是核心中断66(TINH8L)和核心中断67(TINH8H)?

    我代码如下:

    tatic void init_TimerIntcControllers( )
    {
    CSL_IntcObj iTmrObj; // intcObj66
    CSL_IntcContext context; /** Pointer to the event handle record */
    CSL_IntcEventHandlerRecord EventRecord;


    CSL_IntcGlobalEnableState state; //Global Interrupt enable state
    CSL_Status status;
    CSL_IntcParam vectId; //INT 4-15


    context.numEvtEntries = 1;
    CSL_IntcHandle hIntc20;
    // Uint32 delayCount;
    printf ("**************************************************\n");
    printf ("****************** INTC Testing ****************\n");
    printf ("**************************************************\n");

    /* INTC module initialization */

    if ( CSL_intcInit(&context)!= CSL_SOK)
    {
    printf("Error: GEM-INTC initialization failed\n");
    return;
    }

    // NMI Enable
    if (CSL_intcGlobalNmiEnable() != CSL_SOK)
    {
    printf("Error: GEM-INTC global NMI enable failed\n");
    return;
    }

    /* Enable global interrupts */
    if (CSL_intcGlobalEnable(&state) != CSL_SOK)
    {
    printf ("Error: GEM-INTC global enable failed\n");
    return;
    }
    /**************************************************************
    ********************** INTC related code *********************
    **************************************************************/

    // Opening a handle for the Event 66or65 at vector id 4
    vectId = CSL_INTC_VECTID_4; /** CPU Vector 4 */
    // hIntc20 = CSL_intcOpen (&iTmrObj, CSL_GEM_TINT8L, &vectId , &status);
    hIntc20 = CSL_intcOpen (&iTmrObj, CSL_GEM_TINTLN, &vectId , &status);
    if (hIntc20 == NULL)
    {
    printf("Error: GEM-INTC Open failed\n");
    return;
    }

    /* Register an call-back handler which is invoked when the event occurs. */
    /* Bind ISR to Interrupt */
    EventRecord.handler = (CSL_IntcEventHandler)&event20Handler;
    // EventRecord.arg = (void *)CSL_GEM_TINT8L;
    EventRecord.arg = (void *)CSL_GEM_TINTLN;
    if (CSL_intcPlugEventHandler(hIntc20,&EventRecord) != CSL_SOK)
    {
    printf("Error: GEM-INTC Plug event handler failed\n");
    return;
    }
    /* Clear the event in case it is pending */
    // CSL_intcHwControl(hIntc20, CSL_INTC_CMD_EVTCLEAR, NULL);

    /* Enable event */
    if (CSL_intcHwControl(hIntc20,CSL_INTC_CMD_EVTENABLE, NULL) != CSL_SOK)
    {
    printf("Error: GEM-INTC CSL_INTC_CMD_EVTENABLE command failed\n");
    return;
    }
    printf ("Debug: GEM-INTC Configuration Completed\n");
    // Close handle
    // CSL_IntcClose(hIntc20);

    }

    static void event20Handler (void *arg)
    {
    printf ("****************** event20Handler Testing ****************\n");;
    timerISRCounter++;
    CSL_intcEventClear((CSL_IntcEventId)arg);
    }

    这段程序,不知道为何不往中断函数调入?

    是定时器没有产生中断,还是上面的程序问题吗

  • 补充一个定时8的寄存器状态图

  • 刚看下LOG 

    if (CSL_intcPlugEventHandler(hIntc20,&EventRecord) != CSL_SOK)
    {
    printf("Error: GEM-INTC Plug event handler failed\n");
    return;
    }

    这个执行时,报错了。

  • 主函数调整下:

    int main(void)
    {
    int8_t ret = 0;
    uint32_t main_pll_freq;

    /* Get the cpu freq */
    main_pll_freq = platform_get_main_pll_freq();

    /*
    * the internal timer clock frequency is equal
    * to the CPU frequency divided by 6.
    *
    * Start the testing for timer led.
    */

    // ret = timer_led(CSL_TMR_8, main_pll_freq/6);
    ret = timer_led(CSL_TMR_8, main_pll_freq/6);
    printf(" Testing timer led ok!\n");
    if(ret) {
    printf("Error: Testing timer led failed!\n");
    return ret;
    }
    init_TimerIntcControllers( );
    return 0;

    }

    但是还是向中断函数跳转。

  • 上写错了,还是无法进入中断函数.

  • 不确定您看的哪个timer例程,建议下载proessor SDK,参考C:\ti\C6678 SDK 5.03\pdk_c667x_2_0_13\packages\ti\csl\example\timer.
    https://www.ti.com/tool/PROCESSOR-SDK-C667X

  • 我咨询下:如果定时8器设置为一个64bit 定时器,timer output(TOUTL)如果输出正常话,那么Interrupt(TINTLO) to cpu引脚会产生一个EVT的输出吗?

    我的疑问是 核心中断66(TINH8L)和核心中断67(TINH8H),这个Interrupt(TINTLO) to cpu应该是核心中断66(TINH8L)和核心中断67(TINH8H)?都会有(TINTLO) 和 (TINH8L)中断信号?

  • 会产生TINTLO中断,在Timer user guide里有说明。
    When the timer counter matches the timer period, it generates a maskable timer interrupt (TINTLO), a timer event (TEVTLO), and an output signal on the timer output pin, TOUTL.

    2.1 64-Bit Timer Mode
    https://www.ti.com/lit/ug/sprugv5a/sprugv5a.pdf

  • Hi,Shine

        我想请教,我参考了C:\ti\C6678 SDK 5.03\pdk_c667x_2_0_13\packages\ti\csl\example\timer.

       我参考通用64bit定时器程序,程序如下:

    static Int32 test_gp_timer (Uint8 IntcInstance)
    {
    CSL_IntcHandle tmrIntcHandle;
    CSL_TmrHandle hTmr;
    CSL_TmrObj TmrObj;
    CSL_IntcEventHandlerRecord EventRecord;
    CSL_IntcParam vectId;
    CSL_Status status;
    CSL_TmrHwSetup hwSetup = CSL_TMR_HWSETUP_DEFAULTS;
    CSL_TmrEnamode TimeCountMode = CSL_TMR_ENAMODE_ENABLE;
    Uint32 delayCount;

    /* Clear local data structures */
    memset(&TmrObj, 0, sizeof(CSL_TmrObj));
    printf("Debug: Testing 64bit Timer in Single Shot Mode...\n");

    /**************************************************************
    ********************** INTC related code *********************
    **************************************************************/

    /* Open INTC */
    vectId = CSL_INTC_VECTID_12;
    tmrIntcHandle = CSL_intcOpen(&tmrIntcObj, CSL_GEM_TINTLN, &vectId, NULL);

    /* Bind ISR to Interrupt */
    EventRecord.handler = (CSL_IntcEventHandler)&TimerInterruptHandler;
    EventRecord.arg = (void *)CSL_GEM_TINTLN;
    CSL_intcPlugEventHandler(tmrIntcHandle, &EventRecord);

    /* Event Enable */
    CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);

    /**************************************************************
    ********************** Timer related code ********************
    **************************************************************/

    /* Open the timer. */
    hTmr = CSL_tmrOpen(&TmrObj, IntcInstance, NULL, &status);
    if (hTmr == NULL)
    return -1;

    /* Set the timer mode to 64bit GP Timer Mode and set the PRD registers */
    hwSetup.tmrTimerMode = CSL_TMR_TIMMODE_GPT;
    hwSetup.tmrTimerPeriodLo = 0x0f;
    hwSetup.tmrTimerPeriodHi = 0x00;
    CSL_tmrHwSetup(hTmr, &hwSetup);

    /* Reset the timer ISR Counter. */
    timerISRCounter = 0;

    /* Reset the Timer */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET64, NULL);

    /* Start the timer in SINGLE SHOT Mode. */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START64, (void *)&TimeCountMode);

    /* INTC related code */
    while (timerISRCounter != 1);

    /* Good. The timer ISR was invoked; now we wait for some time and make
    * sure that the ISR was not invoked again since this is a ONE SHOT
    * Timer. */
    for (delayCount = 0; delayCount < MAX_DELAY; delayCount++);

    /* Timer ISR Counter should still be the same */
    if (timerISRCounter != 1)
    return -1;

    /**************************************************************/

    /* Disable the interrupts. */
    CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTDISABLE, NULL);

    /* Stop the Timer */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET64, NULL);

    /* Close the Tmr and interrupt handles */
    CSL_tmrClose(hTmr);
    CSL_intcClose(tmrIntcHandle);

    /* Test has been completed successfully. */
    return 0;
    }

    我现在修改hwSetup.tmrTimerPeriodHi = 0x00;改成hwSetup.tmrTimerPeriodHi = 0x01或任何数值,进行定时功能设计。

    但是;改成hwSetup.tmrTimerPeriodHi = 0x01,程序运行到:

    /* Start the timer in SINGLE SHOT Mode. */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START64, (void *)&TimeCountMode);

    程序就停止,查定时器寄存器也是异常?把还原为hwSetup.tmrTimerPeriodHi = 0x00;程序感觉就正常了,不知道什么原因?

  • 上面描述不是特别准确,应该调到我主函数就结束。现在就想搞明白,hwSetup.tmrTimerPeriodHi 赋值后就无法中断函数调用的原因?

  • 64bit timer的Period是由32bit PeriodHi和32bit PeriodLo组成的,多等一段时间看是否能进中断?