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.

Bio fail to call Interrupt Service Routine

Other Parts Discussed in Thread: OMAP-L138

Hi,

I'm working with DSP/BIOS 5.41 on C6747. I'm trying to run an Interrupt Service Routine using GPIO interrupt. By checking the interrupt status register, I'm sure that the interrupt has been generated. My problem is that I cannot get the BIOS to call the Service Routine. Please help. Thanks in advance.The following is the code:


int main(void)
{
 LOG_printf(&trace, "Main() ...");

   Uint32* kick0R  = (Uint32 *) 0x01C14038;
   Uint32* kick1R  = (Uint32 *) 0x01C1403C;
   Uint32* pinmux4_11  = (Uint32 *) 0x01C14150;

   Uint32* direction4_11 = (Uint32 *) 0x01E26060;
    Uint32* output4_11  = (Uint32 *) 0x01E26064;
    Uint32* input4_11  = (Uint32 *) 0x01E26070;
    Uint32* setRiseTrig4_11 = (Uint32 *) 0x01E26074;
    Uint32* setFallTrig4_11 = (Uint32 *) 0x01E2607C;
    Uint32* clearFallTrig4_11 = (Uint32 *) 0x01E26080;
    Uint32* enable4    = (Uint32 *) 0x01E26008;
    Uint32* intstatus    = (Uint32 *) 0x01E26084;

 *kick0R   = 0x83E70B13;
 *kick1R   = 0x95A4F1E0;
 *pinmux4_11  &= 0xFFFFFFF0;
 *pinmux4_11  |= 0x00000008;
 *direction4_11 &= 0xFFFFF7FF;
 *direction4_11 |= 0x00000800;
 *setRiseTrig4_11 |= 0x00000800;
 *setFallTrig4_11 |= 0x00000800;
 *enable4 = 0x00000010;

 
 while(true)
 {

  if(((*intstatus >>11) &1) == 1)
  {
   LOG_printf(&trace, "((*intstatus >>11) &1) == 1");
   break;
  }

 }

}

void ImuInterruptRoutine(void)
{
 LOG_printf(&trace, "Interrupt Called");
}

// from tcf file:


bios.HWI.instance("HWI_INT7").interruptSelectNumber = 0;
bios.HWI.instance("HWI_INT8").interruptSelectNumber = 1;
bios.HWI.instance("HWI_INT9").interruptSelectNumber = 2;
bios.HWI.instance("HWI_INT10").interruptSelectNumber = 3;


bios.HWI.instance("HWI_INT8").useDispatcher = 1;
bios.HWI.instance("HWI_INT8").arg = 1;


bios.ECM.ENABLE = 1;
bios.ECM.instance("EVENT54").arg = 1024;
bios.ECM.instance("EVENT54").fxn = prog.extern("ImuInterruptRoutine");
bios.ECM.instance("EVENT54").unmask = 1;

  • I notice that you are using the Event Combiner Module (ECM). We'll get to that in a bit.

    First things first. For an interrupt to pass all ALL the way through to the ISR, certain pieces must be in place:

    1. The interrupt must be generated properly (internally or externally) - i.e. the GPIO must have a PATH to cause the IFR (interrupt Flag Register) to be set. You can do this via the BIOS configuration of, for example, HWI_INT5. You simply select the SOURCE (GPIO_0) which you must define as an EVT# (from the datasheet) and a corresponding interrupt service routine (e.g. _ImuInterruptRoutine). In this case, there is no need to use the ECM. More on this later. For example, the C6748 datasheet shows:

    In this case, you would use "41" for GPIO for bank 1, etc. This is the SOURCE of the interrupt. Place this number in the config of HWI_INT5 dialogue box (and don't forget to check the "dispatcher" box on the other tab so that your context save/restore is done properly.

    2. If #1 is done correctly, you should see the IFR (bit 5 for HWI_INT5) getting set. This means the interrupt is being latched properly. If not, go back, the processor is not even recognizing the interrupt.

    3. Next is the IER (bit). If you are using HWI_INT5, IER (bit 5) must be set/enabled to allow this interrupt to pass through to the next "gate". Check the IER register in CCS and see if there is a ONE in bit position 5.

    4. Next is global interrupts (GIE). If you are using BIOS, this is automatically turned on for you. If you're not using BIOS, you must turn on both NMIE and GIE in the CSR register. Otherwise, NO interrupts (at all) will occur. Is GIE turned on? If so, proceed...

    5. If all of the above is correct, you should be getting to your ISR. Place a breakpoint at the first instruction of the ISR to see if you get there. If not, go back up the list and debug the problem. Make sure you have the proper EVT# in the BIOS config for HWI_INTx. Check your datasheet for the proper EVT number and check it twice or three times to make sure, sure, sure.

    If you'd like to learn more about interrupts and see a project that properly configures IER, GIE, etc., download lab 4 solution from the BIOS workshop wiki site. Also, download the ppts and go through chapter 4 (Interrupts) and see if something in that chapter helps you. Here's a link to the BIOS workshop wiki:

    http://processors.wiki.ti.com/index.php/TMS320C64x%2B_DSP_System_Integration_Workshop_using_DSP/BIOS

     

    Regarding the ECM, you only need to use the ECM if you need more than 12 user interrupts. There are 16 HWI_INTx's. The first 4 are reset, nmi, emu0, emu1 - which leaves 12 for users. If you need a "13th" interrupt, then the ECM can help, but in your ISR, you must parse the IFR to see WHICH interrupt fired of the 2+ interrupts that could generate EVT0/1/2/3. The ECM breaks up all 128 interrupt sources into 4 "blocks" of EVT#s - 0-31, 32-63, 64-95, 96-127. If, for example, interrupt EVT# 20 and 21 fire, this will generate a NEW event called EVT0:

    This new EVT has a NEW event number as shown above - it is EVT# 0. This then must be programmed into the BIOS GUI config for HWI_INTx with the proper ISR name and dispatcher turned on. So, instead of programming EVT #20 and EVT #21 to produce two SEPARATE events on two SEPARATE HWI_INTx CPU interrupts, you "combine" them into one EVT - EVT0 in this case which is EVT#0 in this datasheet (check yours to see if this differs on the C6747). You would then use "0" as the event number in the BIOS config of that specific HWI_INTx.

    There are other configurations you must set up for ECM (masks, enables, etc). Again, check out the ppts for chapter 4 of the BIOS workshop at the link above.

    My suggestion is to NOT use the ECM due to the add'l config steps UNLESS you need more than 12 user interrupts. The PPTS for chapter 4 walk you through a basic interrupt setup that might help you as well as lab4 demonstrates their use. I don't have a lab on ECM, but I do have a few slides on it that might pinpoint your problem if you still want to use ECM.

    Let me know if this helps, hurts, or is confusing...hopefully the former...

     

    Cheers,

    Eric

  • Thanks Eric,

    My problem is solved after adding the following code:


       IER |= (0x01<<8);
       CSR |= 0x01;

    Regards

  • Hi Eric,

    I want to respond to an interrupt generated by ARM (my board is omap-l138). But the interrupt always cannot deal with properly!

    I am using DSP/BIOS 5.41 in CCS3.3.  The interrupt source is CHIPINT3 and its #EVT is 67. I have configured HWI_13 to map EVT67.

    Here is my code:

    void main()

    {
              Init_int13();
      
        LOG_printf(&trace, "hello world!");
    }

    void Init_int13()
    {
        unsigned int *EVTMASK2 = (unsigned int*)0x01800088;
        unsigned int *EVTSET2 = (unsigned int*)0x01800028; 


        *EVTMASK2  |= (1<<3);
        *EVTSET2  |= (1<<3);

     
     HWI_eventMap(13, SYSCFG_CHIPINT3);
     HWI_dispatchPlug(ZDINTERRUPTID, (Fxn)Int13_ISR, 0, NULL);
     

     IER |= (0x1 << 13);
     CSR |= 0x1;
    }

     void Int13_ISR()
    {
       
         unsigned int key;
         unsigned int *EVTCLR2  = (unsigned int*) 0x01800048;    
       
         if(SYSCONFIG->CHIPSIG & (1<<3) == 1)
       {
           SYSCONFIG->KICKR[0] = KICK0R_UNLOCK;
           SYSCONFIG->KICKR[1] = KICK1R_UNLOCK;

     SYSCONFIG->CHIPSIG_CLR |= (1<<3);   //asserts syscfg_chipint2 intrrupt 
      *EVTCLR2 |= (1<<3);
                  // lock the system config registers.
        SYSCONFIG->KICKR[0] = KICK0R_LOCK;
           SYSCONFIG->KICKR[1] = KICK1R_LOCK;
        }
              
          LOG_printf(&trace, "config INT13.");

    return;
          
        }

    Best wishes!

    lex

  • Hi Eric,

    My interrupt invoked only once use my code above.

    I have cleared the CHIPSIG_CLR and EVTCLR, is there anything else should be cleared?

    thanks!

    lex