This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ADC and EOP interrupt levels

I use the PEC to transfer data from the ADC and the EOP interrupt to reset the PEC pointers. As i understand you still need to have an end of conversion interrupt from the ADC to use the PEC EOP interrupt.
Does anyone know which of the two interrupts should have greater priority or should they be the same?

Parents
  • Sorry to jump in but your statements are very interesting. I think you have a misconception in using the EOP interrupt.

    In your example you are using the ADC interrupt to move your ADC results, typically this could be at a high priority but to reset the counters you don't need the same high priority level. This is why you could use the EOP (not that you must) at a much lower level. This is a setting in the PEC control register. Note the EOP is for all PECs so this ISR needs to understand who called it.

    If you are you using the EOP for the ADC PEC then you won't get the ADC interrupt it is an either or not both.

    Secondly you are NOT ALLOWED to have more than one interrupt set to the same level. If you do the interrupt controller will OR the results and "strange" behavior will result.

    At least this is my understanding.

Reply
  • Sorry to jump in but your statements are very interesting. I think you have a misconception in using the EOP interrupt.

    In your example you are using the ADC interrupt to move your ADC results, typically this could be at a high priority but to reset the counters you don't need the same high priority level. This is why you could use the EOP (not that you must) at a much lower level. This is a setting in the PEC control register. Note the EOP is for all PECs so this ISR needs to understand who called it.

    If you are you using the EOP for the ADC PEC then you won't get the ADC interrupt it is an either or not both.

    Secondly you are NOT ALLOWED to have more than one interrupt set to the same level. If you do the interrupt controller will OR the results and "strange" behavior will result.

    At least this is my understanding.

Children
  • Chris, thanks for your comments, yes i do use the PEC EOP to reset the counters etc, the ADC end of Conv interrupt has no code in it. You say that if using the EOP for ADC then you wont get the End of Conv interrupt. But I Do, only if they are not at the same ILVL. Strange but true, i set breakpoints on both interrupts and they do occurr. So should the PEC EOP interrupt be higher than the ADC End Of Conv?
    Also your statement that more than one interrupt at the same ILVL is NOT ALLOWED surely is NOT true, else why is there a GLVL field in the interrupt control register. (do a search for GLVL).

  • If the ADC is in continuous conversion mode, you SHOULD get end of conversion interrupt after EOP interrupt, unless you set up a new PEC transfer or stop the AD converter before the next conversion after EOP is ready. (Wasn't that clearly said!) It is strange if you don't.

    If you set breakpoints to both interrupts, the EOP breakpoint is hit first, and if the AD converter is not stopped before the breakpoint, the end of conversion interrupt is certainly pending when you continue execution.

    If using two interrupts won't work, you can always use the ADC interrupt instead of EOP. Since you asked if the ADC and EOP interrupts should use the same priority, I take it to mean that you are not conserned about the time spent in the interrupt service. And even if you are, you can always just trigger a lower priority interrupt in the service routine, which is a trick I have often used with C167.

    P.S. I'm sure Chris ment same ILVL and GLVL.

  • Sorry for the confusion and I need to clarify what I am saying, so I would add to Sauli comments.

    Concerning the interrupt level, I used the term too loosely, I meant to say the combined entry for the bits GPX, ILVL and GLVL must be unique (no two enabled interrupt nodes written with the same value).

    The point of the EOP from the Infineon manual...

    When the selected number of PEC transfers has been executed, the respective PEC channel is disabled and a standard interrupt service routine is activated instead. Each PEC channel can either activate the associated channel-specific interrupt node, or activate its associated PEC subnode request flag in register PECISNC, which then activates the common node request flag in register.

    I assumed you were running an auto scan single conversion. If you are running auto scan continuous conversions then you need to service the EOP before the next conversion otherwise as Sauli has pointed out given the PEC count is zero the ADC interrupt will occur not the EOP interrupt. This is clearly defined behavior.

    If you could provide a snippet of code that demonstrates this issue then I would be glad to look at it and comment.

    Here is an example that does an auto-scan single conversion of all the ADC channels and uses the PEC to move them to an array in memory. T3 launches the auto-scan every 10 milliseconds (20MHz cpu clock). Both interrupts are enabled the ADC end of conversion and the EOP. The ADC end of conversion interrupt is on PEC0 (GLVL = 14, ILVL = 0) and the EOP interrupt (GLVL = 13, ILVL = 0). The EOP resets the pointers and PEC0 control. Only the EOP is ever vectored to by the CPU.

    #include <XC167.h>  /* Special Function Registers XC167 */
    #include <intrins.h>
    
    unsigned int results[16];
    unsigned int adcCnt;
    unsigned int eopCnt;
    
    void GPT1_Tmr3_ISR(void) interrupt 0x23 {
      ADC_CON_ADST = 1;
    }
    
    void ADC_Conv_ISR(void) interrupt 0x28 {
      adcCnt++;
    }
    
    void INT_EOP_ISR(void) interrupt 0x4C {
    
      if(PECISNC_C0IR) { /* PEC channel 0 */
        PECISNC_C0IR = 0;
        eopCnt++;
        DSTP0 = _sof_(&results[0]);
        PECC0 = 0x4210;
      }
    }
    
    void main (void) {
      /* setup ADC, autoscan single conversion of all 16 channels */
      ADC_CON = 0x022F;
      ADC_CON1 = 0x8000;
      PECC0 = 0x4210;
      SRCP0 = _sof_(&ADC_DAT);
      DSTP0 = _sof_(&results[0]);
      PECSEG0 = 0;
      P5DIDIS = 0xFCFF;
      ADC_CIC = 0x0078; /* ADC Conv: (ILVL) = 14, (GLVL) = 0, (GPX) = 0 */
    
      /* setup End Of PEC */
      PECISNC = 0x0001;
      EOPIC = 0x0074;  /* EOP: (ILVL) = 13, (GLVL) = 0, (GPX) = 0   */
    
      /* use T3 to launch autoscan every 10 msec */
      GPT12E_T3CON = 0x0080;
      GPT12E_T3    = 0x61A8;
      GPT12E_T2CON = 0x0025;
      GPT12E_T2    = 0x61A8;
      GPT12E_T3IC = 0x006C; /* Timer 3: (ILVL) = 11, (GLVL) = 0, (GPX) = 0 */
      GPT12E_T3CON_T3R = 1;
    
      PSW_IEN = 1;  /* globally enable interrupts */
    
      for(;;);
    }
    

  • HI, thanks for the clarification, my ADC code is pratically as yours is except my EOP is ILVL = 10 & GLVL = 0, my ADC Conv is ILVL = 10 & GLVL = 1. In your example you have the EOP at a lower ILVL than the ADC Conv, is this the best way round if its the EOP that actually does something. I only ask as one of my previous questions was which should have higher priority? Just to clarify also, i run in Auto Scan Continuous mode, which leads me to ask when i service the EOP to reset the PEC & DESTP1 should i stop conversion before doing so then restart after?

    Thanks for all your help.

  • I will start with the point of the EOP is to have a considerable lower priority than the interrupt level used by the PEC. Given your question I would recommend that the EOP should be lower (not in the same group) that the ADC conversion complete interrupt is. The second thing to remember is any interrupt in a group will NOT interrupt another if another within that group is already active. If two or more interrupts within a group become active at the same time then the highest wins. However, if a lower priority within the group is active and a higher interrupt now becomes ready it is held off until the lower one has finished.

    In your situation given you are using continuous auto scan and planning to have both interrupts in the same group it makes no sense to me to use the EOP. Instead I would just use the ADC conversion complete to reset the PEC registers. So I wouldn't stop the ADC, just don't use the EOP.

    Some comments to the interrupts with the PEC.
    1) When the PEC count is greater than 1 you only get the PEC transfer
    2) When the PEC count decrements to zero the PEC transfer will occur and then you can either have the EOP or ADC conversion complete (depending on your configuration).
    3) When the PEC count is zero you will only get the ADC conversion complete interrupt no matter what you configured for the EOP.

    Hope this helps.

    #include <XC167.h>            /* Special Function Registers XC167 */
    #include <intrins.h>
    
    unsigned int results[16];
    unsigned int adcCnt;
    
    void ADC_Conv_ISR(void) interrupt 0x28 {
      DSTP0 = _sof_(&results[0]);
      PECC0 = 0x0210;
      adcCnt++;
      P2 ^= 0x100;  /* toggle port pin */
    }
    
    void main (void) {
    
      /* setup ADC, autoscan signle conversion of all 16 channels */
      ADC_CON = 0x023F;
      ADC_CON1 = 0x8000;
      PECC0 = 0x0210;
      SRCP0 = _sof_(&ADC_DAT);
      DSTP0 = _sof_(&results[0]);
      PECSEG0 = 0;
      P5DIDIS = 0xFCFF;
      ADC_CIC = 0x0078; /* ADC Conv: (ILVL) = 14, (GLVL) = 0, (GPX) = 0 */
      DP2 |= 0x100;     /* use P2.8 to indicate an ADC service */
      PSW_IEN = 1;      /* globally enable interrupts */
    
      ADC_CON_ADST = 1;     /* begin the ADC conversions */
    
      for(;;);
    }