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.

RTOS/66AK2G12: SYS/BIOS CIC/CpIntc, EventCombiner, INTC

Part Number: 66AK2G12

Tool/software: TI-RTOS

Dear All,

I am trying to setup HWIs during runtime using SYS/BIOS API.

My current environment is:

66AK2G12, SYS/BIOS 6.75.2.0, XDC 3.55.0.11, PDK K2G 1.0.13

The intention is to setup a timer ISR that is called ever 1 ms. A few weeks ago I failed. No I had more time to investiage and was able to do so.

But for one of the 4 possible scenarions I need to do a kind of dirty hack to have it working so I wanted to discuss with you.

The 4 scenarios I am talking about are

  1. DSP-level interrupt controller (INTC)
  2. DSP-level interrupt controller (INTC) + DSP-level event combiner (INTC)
  3. chip-level interrupt controller (CIC/CpIntc) + DSP-level interrupt controller (INTC)
  4. chip-level interrupt controller (CIC/CpIntc) + DSP-level interrupt controller (INTC) + DSP-level event combiner (INTC)

All scenarios are working except the 3rd one. Here I have to apply an additional function call to trigger the HWI once via ISR(Interrupt Set Register). Once this single trigger is done the timer interrupt comes every 1 ms.

Please find here the code I use. There is a pre-processor define I switch the scenarios with.

I don't have other HWIs in the project except the automatic one created for the SYS/BIOS Clock.

Is there someone out there that can explain to me whats going on here???

A interrupt related question I have:

What is the recommended interrupt masking for a) EventCombiner_dispatc() and b) CpIntc_dispatch()?

Please, do not hesitate to post I appreciate any feedback!

Kind Regards,

Bernhard

    void _startHardwareInterrupt()
    {
#define HWI_SETUP_INTC                      1
#define HWI_SETUP_EVENTCOMBINER_INTC        2
#define HWI_SETUP_CIC_INTC                  3
#define HWI_SETUP_CIC_EVENTCOMBINER_INTC    4

#define HWI_SETUP                           3

        int intVector   = 5; // interrupt vector

        int intcEventId = CSL_C66X_COREPAC_TIMER_1_INTL; // so called host interrupt/event

        int cicInstance = 0;
        int cicEventId  = CSL_CIC_TIMER_1_INTL; // so called system interrupt/event

#if HWI_SETUP == HWI_SETUP_INTC
        /**
         * Setup INTC
         */
        {
            /**
             * Plug the timer ISR to a HWI vector at the INTC
             */
            {
                Hwi_Params hwiParams;
                Error_Block eb;

                // Defaults: enable, arg = 0, mask none
                Hwi_Params_init(&hwiParams);
                Error_init(&eb);

                // Set the event id of the peripheral assigned to this interrupt
                hwiParams.eventId = intcEventId;

                // Configure and enable interrupt vector to invoke ISR
                Hwi_create(intVector, &TimerSync_hardwareInterrupt_manual, &hwiParams, &eb);
                if ( Error_check(&eb) )
                {
                    // Error Handling
                }
            }
        }
#elif HWI_SETUP == HWI_SETUP_EVENTCOMBINER_INTC
        /**
         * Setup Event Combiner and INTC
         */
        {
            /**
             * Plug the timer ISR to the INTC timer event id at the event
             * combiner
             */
            {
                EventCombiner_dispatchPlug(intcEventId, &TimerSync_hardwareInterrupt_manual, 0/*arg*/, TRUE/*unmask*/);
            }
            /**
             * Plug the event combiner ISR to a HWI vector at the INTC
             */
            {
                Hwi_Params hwiParams;
                Error_Block eb;

                // Defaults: enable, arg = 0, mask none
                Hwi_Params_init(&hwiParams);
                Error_init(&eb);

                // Set the event id of the peripheral assigned to this interrupt
                hwiParams.eventId = intcEventId / 32; // 32 events per group

                // Set the argument passed to the ISR function
                hwiParams.arg = hwiParams.eventId;

                // Configure and enable interrupt vector to invoke ISR
                Hwi_create(intVector, &EventCombiner_dispatch, &hwiParams, &eb);
                if ( Error_check(&eb) )
                {
                    // Error Handling
                }
            }
        }
#elif HWI_SETUP == HWI_SETUP_CIC_INTC
        {
            /**
             * Plug the timer ISR to the CIC event id at the CIC
             */
            {
                // Map CIC timer event id to INTC event id at CIC
                CpIntc_mapSysIntToHostInt(cicInstance, cicEventId, intcEventId);

                // Plug the timer ISR to the CIC timer event id at the CIC
                CpIntc_dispatchPlug(cicEventId, &TimerSync_hardwareInterrupt_manual, 0/*arg*/, TRUE/*unmask*/);

                // Enable the Host Interrupt
                CpIntc_enableHostInt(cicInstance, intcEventId);
            }

            /**
             * Plug the CIC ISR to a HWI vector at the INTC
             */
            {
                Hwi_Params hwiParams;
                Error_Block eb;

                // Defaults: enable, arg = 0, mask none
                Hwi_Params_init(&hwiParams);
                Error_init(&eb);

                // Set the event id of the peripheral assigned to this interrupt
                hwiParams.eventId = CpIntc_getEventId(intcEventId);

                // Set the argument passed to the ISR function
                hwiParams.arg = intcEventId;

                // Configure and enable interrupt vector to invoke ISR
                Hwi_create(intVector, &CpIntc_dispatch, &hwiParams, &eb);
                if ( Error_check(&eb) )
                {
                    // Error Handling
                }

                /**
                 * 2019-07-02 bseiz
                 * This necessary to have the timer interrupt running. Why???
                 */
                Hwi_post(intVector);
            }
        }
#elif HWI_SETUP == HWI_SETUP_CIC_EVENTCOMBINER_INTC
        {
            /**
             * Plug the timer ISR to the CIC event id at the CIC
             */
            {
                // Map CIC timer event id to INTC event id at CIC
                CpIntc_mapSysIntToHostInt(cicInstance, cicEventId, intcEventId);

                // Plug the timer ISR to the CIC timer event id at the CIC
                CpIntc_dispatchPlug(cicEventId, &TimerSync_hardwareInterrupt_manual, 0/*arg*/, TRUE/*unmask*/);

                // Enable the Host Interrupt
                CpIntc_enableHostInt(cicInstance, intcEventId);
            }

            /**
             * Plug the CIC ISR to the INTC timer event id at the event combiner
             */
            {
                EventCombiner_dispatchPlug(CpIntc_getEventId(intcEventId), &CpIntc_dispatch, intcEventId/*arg*/, TRUE/*unmask*/);
            }

            /**
             * Plug the event combiner ISR to a HWI vector at the INTC
             */
            {
                Hwi_Params hwiParams;
                Error_Block eb;

                // Defaults: enable, arg = 0, mask none
                Hwi_Params_init(&hwiParams);
                Error_init(&eb);

                // Set the event id of the peripheral assigned to this interrupt
                hwiParams.eventId = CpIntc_getEventId(intcEventId) / 32;

                // Set the argument passed to the ISR function
                hwiParams.arg = hwiParams.eventId;

                // Configure and enable interrupt vector to invoke ISR
                Hwi_create(intVector, &EventCombiner_dispatch, &hwiParams, &eb);
                if ( Error_check(&eb) )
                {
                    // Error Handling
                }
            }
        }
#endif // HWI_SETUP
    }

  • Bernhard,

    From Processor SDK RTOS perspective, we recommend use of OSAL_RegisterInterrupt API in OS Abstraction layer from application perspective as this takes care of the interrupt setup as well as the event combiner setup from a user perspective.

    You can look at the OSAL test which uses a timer interrupt example for demonstrating the use of driver:

    pdk_k2g_1_0_13\packages\ti\osal\test

    Use of OSAL will also ensure that your application level configuration will play well with the LLD drivers which also use the OSAL layer for setting up interrupt. 

    The INTC/CIC and eventcombiner has been explained in the article here:

    http://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices#Analyzing_Interrupts_in_Code_Composer_Studio

    For K2G specifically, you can refer to the MCASP driver file for K2G soc located here for the event comibiner, INTc and CIC setup details.

    pdk_am57xx_1_0_xx\packages\ti\drv\mcasp\soc\k2g\mcasp_soc.c

    Hope this helps.

    Regards,

    Rahul

  • Dear Rahul,

    thank you very much for your answer!

    Indeed, I did not take the OSAL lib into account. Using its API I have no problems anymore.

    I had a very detailed look to its sources and honestly I can't find a difference to the calls I made.

    Regards,

    Bernhard