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.

Latency on high speed DSP interrupt

Other Parts Discussed in Thread: OMAP3530

Hello,

I am using the DSP of an OMAP3530 to acquire data in parallel from 32 I2S microphones, each of them outputs one bit each clock cycle (@3MHz).

The DSP is running at 360MHz, DSP/BIOS version is 5.41.07.24, DSP/LINK version is 1.65.00.03.

The timers 8 and 9 (configured as PWM) are generating the two clocks required for I2S protocol and the data lines (16 data lines, 2 microphones per line) are connected to GPIOs configured as input.

The idea is to have Timer8 triggering a 3MHz interrupt. The interrupt function only copies data from the GPIO register to a temporary buffer that will be treated in a background task.

The process works nicely at low frequencies but many interrupts are dropped when running at 3MHz. This seems to be due to an overhead before the interrupt function call. It is about 500ns (180 clock cycles). According to DSP/BIOS datasheet, such a latency is normal when using DSP/BIOS' dispatcher. I thus tried without the dispatcher using TConf to set the interrupt and the following C code :

// C code
#define TIMER_8_TISR 0x4903E018 //Timer 8 interrupt status register
#define GPIO_6_CLEARDATA 0x49058090 //GPIO bank 6, output clear register
#define GPIO_6_SETDATA 0x49058094 //GPIO bank 6, output set register
#define DEBUG_PIN_B 26 //Index of GPIO186 in GPIO bank 6

void interrupt my_interrupt_in_c ()

{
    SET_REG(TIMER_8_TISR, 0x00000003); // Clear the interrupt flag of timer 8

    SET_REG(GPIO_6_SETDATA, 1 << DEBUG_PIN_B); // Rise a GPIO for debuging

    SET_REG(GPIO_6_CLEARDATA, 1 << DEBUG_PIN_B); // Fall the previous GPIO for debugging
}

// TConf script
bios.HWI.instance("HWI_INT4").fxn = prog.extern("_my_interrupt_in_c", "asm"); // map the interrupt function
bios.HWI.instance("HWI_INT4").useDispatcher = 0;                              // don't use the dispatcher
bios.HWI.instance("HWI_INT4").interruptSelectNumber = 54;                     // select interrupt source 54 (timer8)

With the previous code, I'm still experiencing a 500ns overhead.

I also tried not to use the 'interrupt' keyword (replacing 'void interrupt my_interrupt_in_c()' by 'void my_interrupt_in_c()') and to call manually the 'HWI_enter' and 'HWI_exit' macros. The TConf script is then :

// TConf script
bios.HWI.instance("HWI_INT4").fxn = prog.extern("_my_interruption_in_asm", "asm"); // map the interrupt function
bios.HWI.instance("HWI_INT4").useDispatcher = 0;                              // don't use the dispatcher
bios.HWI.instance("HWI_INT4").interruptSelectNumber = 54;                     // select interrupt source 54 (timer8)

And the asm code is :

   .include "c64.h64"
   .include "hwi.h62"

   .text
   .global _my_interrupt_in_c
   .global _my_interrupt_in_asm



_my_interrupt_in_asm :

   ; Save Context
   HWI_enter C64_ATEMPS, C64_BTEMPS, C64_CTEMPS, 0xFFFF, 0

   ; Clear int source
   mvkl 0x0000010, a3 ; assuming here Int4
   mvc a3, ICR

   ; Call the C function
   b _my_interrupt_in_c ;

   mvkl _hwi_int4_end, b3
   mvkh _hwi_int4_end, b3
   nop 3

_hwi_int4_end:
   ; Restore context
   HWI_exit C64_ATEMPS, C64_BTEMPS, C64_CTEMPS, 0xFFFF, 0

.end

This code still works but the overhead is now about 1000ns. The extra-overhead is entirely due to the call of 'HWI_enter' which does more than saving the current values of the registers.

Looking at the assembly code generated by the compiler, I could not find any explanation for the overhead. Only the register that are modified by the function are saved and restored (in our case A3, B4, B5 and B6). According to the "TMS320C64x DSP+CPU " the interrupt overhead is only 13 cycles.

What is the explanation for the overhead I am experiencing ? Sould it be possible to run 3MHz interruptions knowing that no DSP/BIOS objects or functions will be used inside the interrupt function (so the main part of DSP/BIOS interrupt prologue should not be necessary) ? What can I do to remove this overhead and lattency ?

Thank you in advance for your help,

Regards,