Synchronizing both Cores with IRQ

Hello Everyone!

We are developing a speech processing application on the BF609, currently using the EvKit and CrossCore Studio. In order to distribute the processing on both cores, we need some mechanism to exchange data between them in a synchronized way. So far we tried MCAPI to send data from one core to the other, however this is rather slow. It would be better to use the shared memory and some fast way to synchronize the cores.

Since the data to be processed is received by an SPORT, the best way would be to generate an SPORT DMA IRQ on both cores when the DMA Controller is done receiving. If this is not possible, we could also send an IRQ from one Core to the other.  From the description of the SEC in the hardware reference, it seems that we only need to setup the SCI accordingly, however it is not quite clear how to do that.

Alternatively, we could send an IRQ form one Core to the other.

Any hints would be greatly appreciated!

Many Thanks,

Axel

  • 0
    •  Analog Employees 
    on Nov 14, 2012 2:02 AM

    Hi Axel,

    On BF60x, each interrupt can be uniquely mapped to only one core.

    As defined by SEC_SCTLn.CTG bits in SEC_SCTLn register.

    Hence it will not be possible to broadcast SPORT DMA IRQ to both the cores.

    Although there can be many alternatives to achieve this, couple of which I can think are

    A) Route trigger from one core to another as you suggested.

    This can be done as follows:  In this code excerpt Core 0 get the SPORT DMA IRQ and in the interrupt handler a software interrupt on core 1 is generated  (INTR_SOFT0)

    On Core 0:

    // Interrupt handler

    void SPORT_ISR(uint32_t iid, void* handlerArg)

    {

        /* Raise the software interrupt */

        adi_sec_Raise(INTR_SOFT0);

        return ;

    }

    int main(void)

    {

           /* Initialize SEC */

        adi_sec_Init() ; 

      /* Register the interrupt handler with SEC */

        adi_int_InstallHandler(INTR_SPORT0_A_DMA,SPORT_ISR,NULL,true);

        /* Enable Interrupt*/

        adi_int_EnableInt(INTR_SPORT0_A_DMA, true);

        /* Enable edge sensitive */

        adi_sec_EnableEdgeSense(INTR_SPORT0_A_DMA, true);

         // Explicitly moved after SEC set up after Core 0, in order to ensure adi_sec_init() enable from core 1 is called after              core 0

        /**

         * The default startup code does not include any functionality to allow

         * core 0 to enable core 1. A convenient way to enable core 1 is to use the

         * 'adi_core_1_enable' function.

         */

        adi_core_1_enable();

         while (1) ; 

      }

    // On Core 1

    // Interrupt handler

    void SWIntHandler(uint32_t SID,  void *pCBParm)

    {

        return ;

    }

    int main(void)

    {

        /* Initialize SEC */

        adi_sec_Init() ;

        /* Register the interrupt handler with SEC */

        adi_int_InstallHandler(INTR_SOFT0,SWIntHandler,NULL,true);

        /* Enable Interrupt */

        adi_int_EnableInt(INTR_SOFT0, true);

        /* Assign interrupt to core 1*/

        adi_sec_SetCoreID(INTR_SOFT0, ADI_SEC_CORE_1);

        /* Enable edge sensitive */

        adi_sec_EnableEdgeSense(INTR_SOFT0, true);

      while (1);

    }

    B) Alternative way is to use the  TRU ( trigger routing unit).

    On Core 0:

    Configure TRU such that it generates 2 software interrupts, which are then individually handled on the cores.

    which will have to be configured individually as shown above.

    int tru_config(void)

    {

        /* Enable the TRU */

        *pREG_TRU0_GCTL |= 0x1;

        /* Configure TRU to generate (TRU0 Interrupt Request 0, TRU0 Interrupt Request 1 ) trigger from SPORT DMA  master */

        *pREG_TRU0_SSR16 = TRGM_SPORT0_A_DMA ;

         *pREG_TRU0_SSR17 = TRGM_SPORT0_A_DMA ;

        return 0;

    }

    Please let me know, if there is something that is not clear.

    Thanks,

    Akash

  • Thank you!

    The INTR_SOFT0 is exactly what I was looking for.

    You solved my problem in one go. Adding your code worked at the first try.

    Kind regards,

    Axel

  • hi !

    i use your solution ->but how can i ack the pending SW-interrupt.

    i get the software int once , and then i have to ack this????

    please help . thanx chris