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.

AM5726: DSP GPIO Interrupt Latency

Part Number: AM5726

We have GPIO interrupt that occur every 31.25 uSec.

I timestamp the TSCL, and check that time between each interrupt falls below 35 uSec. Allowing jitter of 3.75 uSec.

I also toggle LED on board when more than 100 measurements is not matching this condition.

Here is the code:

static const uint32_t CPU_FREQ_IN_MHZ = 750;
static const uint32_t MICROS_IN_ONE_MTS_UP_LIMIT = 35;

void mtsFPGAIsr()
{
   cpu_timestamp = TSCL;

   if(once)
   {
      cpu_timestamp_prev = cpu_timestamp;
      once = 0;
   }

   delta_cpu_timestamp = cpu_timestamp - cpu_timestamp_prev;
   if(delta_cpu_timestamp > CPU_FREQ_IN_MHZ * MICROS_IN_ONE_MTS_UP_LIMIT)
   {
      if(delta_cpu_timestamp > delta_cpu_timestamp_max) delta_cpu_timestamp_max = delta_cpu_timestamp;
      delta_cpu_timestamp_more_than_mts_triggered_cntr++;
      delta_cpu_timestamp_more_than_mts_triggered_total++;
      if(delta_cpu_timestamp_more_than_mts_triggered_cntr > 100)
      {
         GPIO_toggle(BOARD_GPIO_LED_RED_AX1_DSP);
         delta_cpu_timestamp_more_than_mts_triggered_cntr = 0;
      }
   }
   cpu_timestamp_prev = cpu_timestamp;  // aging
}

When no tasks running, there is no jitter, and all good,

delta_cpu_timestamp_more_than_mts_triggered_total = 0

But when i create these test tasks, i start to have problems and 

delta_cpu_timestamp_more_than_mts_triggered_total > 0,

Here are the tasks,

Void test_task_a(UArg arg0, UArg arg1)
{
   while(true) {
      Task_sleep(1000);
   }
}

Void test_task_b(UArg arg0, UArg arg1)
{
   OSAL_SemaphorePend(test_task_b_sem, OSAL_MAX_DELAY);
}

Void test_task_c(UArg arg0, UArg arg1)
{
   OSAL_SemaphorePend(test_task_c_sem, OSAL_MAX_DELAY);
}

  • When in test_task_a i change the loop with sleep to blocking at semaphore, the number of time that latency occures is low and occurs rarely, but still occurs.
  • When there is only 1 task with loop there is no latency in interrupt. or maybe does occur but very very rarely.
  • Maximum latency is always 2 * 31.25, 3 * 31.25, which looks like skipping, maybe something that coming from hwi_disable() in Task_sleep(1000) or Sem_pen().

Note: There is no other tasks running except of TI-RTOS Idle task.

Please advise,

With best regard Vadim.

  • Hi,

    If you have XDS560v2 STM JTAG, you can try to capture DSP CPU trace in CCS to find the glitch.

    While TI-RTOS scheduler is running, it might enter critical section and disable interrupt from time-to-time.

    It's difficult to say exactly what is causing the glitch. 

    Can you fit all code and data in L2 RAM so cache can be ruled out?

    If you know there is no semaphore_post() called in ISR, there is one option to optimize HWI dispatcher for invoking ISR in TI-RTOS.

    You can set Hwi.Hwi_dispatcherTaskSupport  = false; in TI-RTOS config file.

    Regards,
    Stanley

  • Hey we managed to solve the issue,

    It was GPIO drivers, i found that GPIO drivers by default uses interrupt line 1, i used it on both a15_0 and dsp1, both was acknowledging same interrupt line GPIO1_IRQ_1, and it caused a problem, we now use 2 different GPIO ports, A15_0 GPIO1, DSP1 GPIO4 for same interrupt and it works good, but we still want to use same GPIO port but different lines, do you have example on how to modify GPIO drivers to use second interrupt line or example on more low level api like CSL to enable and use second interrupt line, thanks.

  • The main change is in pdk/packages\ti\drv\gpio\src\v1\GPIO_v1.c.  You would need to change all references of GPIO_INT_LINE_1 to GPIO_INT_LINE_2.  Are you using TI-RTOS on both the A15 and 66x?  If so, you might need to make the above change using an #ifdef such that it remains GPIO_INT_LINE_1 for the A15 but is GPIO_INT_LINE_2 for the DSP.

  • Yes, i use TI-RTOS on both a15_0 and dsp_1.

    And what about the IRQ to INTC mapping, there is no default for GPIO1_IRQ2, probably we need something like

    CSL_xbarDspIrqConfigure(1, CSL_XBAR_INST_DSP1_IRQ_75, CSL_XBAR_GPIO1_IRQ_2);

    right?

  • Vadim Malinovsky said:
    1
    CSL_xbarDspIrqConfigure(1, CSL_XBAR_INST_DSP1_IRQ_75, CSL_XBAR_GPIO1_IRQ_2);right?

    Yes, that's right.  You would need to map the GPIOx_IRQ_2 line to one of the DSP crossbar interrupts since only line 1 is mapped by default.  You would need to correspondingly map that interrupt to the DSP core as well.  You could eliminate the second step by remapping DSP_IRQ_55 from its default value of GPIO1_IRQ_1 to GPIO1_IRQ_2.