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.

ISR interrupt conflict !

I am using the f28027 micro.
I am very keen to know if it is possible to use ADCINT2 interrupt and CPU1timer interrupt at the same program. Also if it is possible to be a conflict between those interrupts at the core and if so what is the priority.

Both interrupts are remaped to ISR functions
   EALLOW;  
   PieVectTable.ADCINT2 = &adc_isr;
   PieVectTable.TINT1 = &cpu_timer1_isr;
   EDIS;

  • Yes, you can use ADCINT2 and TINT1 interrupt at the same time.

    From a priority standpoint, ADCINT2 (which belong to interrupt group 1) has higher priority over TINT1 (which belong to INT13) 

    Regards,

    Manoj

  • Dionisis,

    You can use any combination of interrupts on the device that you want.  The priority applies when more than one interrupt is pending at the same time.  Priority is fixed in hardware (see device datasheet SPRS523i Table 3-12, and also the C28x CPU and Instruction User's Guide, SPRU430E, section 3.2).  For the core, INT1 is highest priority, then INT2, then INT3, and so on.  For the PIE, INTx.1 is highest priority, and INTx.8 is lowest in a group.  So, PIE group 1, interrupt 1 is highest priority among all PIE interrupts.

    Regards,

    David

  • David and Manoj ,

    So there is the possibility that  the ADC is the only interrupt that happens.

     Suppose I am using 7 cycle sampling 2 channels (SOC0-1) simultaneously in continue mode and command a ADCINT2 interrupt every time the EOC1 happens. On the other hand I am commanding an interrupt using the cpu timer1 adjusted for 1 interrupt every second using the "ConfigCpuTimer(&CpuTimer1, 60, 1000000)".
    Is there the possibility that only the ADC interrupt happens?

  • You must be able to complete the ADCINT2 ISR faster than the ADCINT2 interrupts occur or you will not meet realtime requirements.  In other words, you cannot do more processing than you can handle in the time you have in between interrupts.  The CpuTimer1 interrupt will get taken after the ADCINT2 ISR is processed, and before the next ADCINT2 interrupt occurs.

    Regards,

    David

  • David you mentioned that : You must be able to complete the ADCINT2 ISR faster than the ADCINT2 interrupts occur

    Is that realized by managing the ISR function as small as possible or there are other ways?

  • Dionisis,

    dionisis said:
    David you mentioned that : You must be able to complete the ADCINT2 ISR faster than the ADCINT2 interrupts occur

    Is that realized by managing the ISR function as small as possible or there are other ways?

    This is a fundamental rule of any processor.  If your interrupt comes in (for example) every 10 uS, then the ISR that services that interrupt cannot exceed 10 uS in execution time in order to keep up with the interrupts.  This assumes a fixed execution time for your ISR of course (I'm not talking about some funky situation where the ISR has variable execution time, in which case the ISR could occasionally take longer than the interrupt rate).

    In your case, it sounds like your ADCINT2 interrupt is relatively high speed.  So yes, you want to optimize the code for the ISR.  You can use the compiler optimizer on the ISR source file (either project level settings, or file level settings just for this source file).  If the execution time is still too long, you may need to try hand written assembly code.

    Regards,

    David

     

  • Indeed the ADCINT2 interrupt is high speed approximatly 13 cycles (60Mhz clock). However the ISR function is relative small  :

    interrupt void  adc_isr(void)
    {
    VoltageA6 = AdcResult.ADCRESULT0;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    }

    Voltage is a float32

  • I'm confused.  Are you saying the ISR takes 13 cycles to execute the code, or that you have only 13 cycles to execute the ISR with a 60 MHz SYSCLKOUT (meaning that you're sampling ADC data at a 4.6 MHz rate)?  I'm getting the feeling you're talking about the later, meaning you have only 13 cycles to execute the ISR.

    The hardware entry and exit operations for the ISR will take longer than 13 cycles.  Each of these is 8 cycles (entry is 8, and return from ISR is another 8).

    - David

  • I should add, you also need to clear the ADCINT flag in the ISR:

     AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;  // Clear ADCINT1 flag

  • Sry for not being clear. The ADC requires 7 cycles (sampling) and 12-13 cycles conversion. However due to the usage of simultaneously mode an ADCINT1 and ADCINT2 interrupt happen between a time segment of 12-13 cycles. The ADCINT2 interrupt is remaped to the ISR function.

    So ADCINT2 to ADCINT2 equals 22-23 cycles

    ADCINT1 to ADCINT2 equals 12-13 cycles

  • dionisis, 

    What are you using the sampled ADC data for?  

    Typically if you are sampling as fast as possible, the goal is to fill up a buffer of conversion results.  One way to do this is to break the 16 available SOCs into two groups of 8.  Have an ISR at the end of each set of 8.  In the ISR, move the 8 conversions to the buffer.  This will reduce the interrupt frequency by a factor of 8, which will be much more efficient since there will be much less interrupt overhead.  Having two sets will make the ISR easier to implement, since grabbing the first sample will not be time-critical.  

    Note that even with the ISR "unrolled", sampling at the maximum possible rate will still consume a significant portion of the CPU bandwidth.  

     

  • What I am trying to achieve is to sample a voltage signal with 100K frequency and to average it over a period of 1/100K . By average I mean --> (Sum(samples) / Number of samples). For a low amount of samples accurate timing is essential. 

    By saying 2 groups of 8 do you mean simultaneously sampling?

  • By two groups of 8, I mean setting the SOCs as follows (for one channel of interest):

    SOC0,SOC1,SOC2,SOC3,SOC4,SOC5,SOC6,SOC7 => Configured to convert channel x, interrupt after EOC7

    SOC08SOC9,SOC10,SOC11,SOC12,SOC13,SOC14,SOC15 => Configured to convert channel x, interrupt after EOC15

    You could apply the same idea to simultaneous sampling (two channels):

    SOC0/SOC1,SOC2/SOC3,SOC4/SOC5,SOC6/SOC7 => Configured to convert channel Ax/Bx, interrupt after EOC7

    SOC08/SOC9,SOC10/SOC11,SOC12/SOC13,SOC14/SOC15 => Configured to convert channel Ax/Bx, interrupt after EOC15

    The above applies when you want exactly the max sample rate (e.g. 4.6 MSPS). However, if you want a specific sample frequency, the way to go is to use the ePWM (or CPU timer) as the trigger source, configured to generate the trigger at the frequency of interest.  

  • To be clear, if you use the ePWM or CPU timer, you wouldn't need to use the two sets of SOCs method.

  • Dear David,

    The purpose is : 

    1)to maximize the samples

    2)use an interrupt every 1/100K sec.(for averaging purpose)

    3) durring the above inter. to calculate the sum of the samples(ADCRESULT) and devide it to the number of those samples while keep sampling for the next period 

    As 3) seems to require lot of cycles would you reccomend to use all 16 SOCS in order to decrease the interrupt rate and meet the specifications set? (supposing that one channel is adequate)

  • If you want a specific sample rate (e.g. 100KHz) you won't use the two sets of conversions methods.

    I think what you want to do is setup the ePWM to 100KHz, use it to trigger a single SOC, which will sample at 100KHz with no averaging.  Get this to work well.

    From there you can start increasing the ePWM frequency (e.g. to 200KHz) and adding averaging.  Keep increasing the ePWM frequency by multiples of the target frequency until you run into the ISR overhead limit.  

    There may be ways to squeeze some more performance out after that fails, e.g by interleaving ePWMs and only triggering an ISR from one set of ePWMs, but try the first method and see if you can get what you need.

     

  • Also, you should distribute your averaging over the different ISRs, e.g. on each ISR

    Sum += AdcResult

    and then when it is time to average

    Average = Sum / Samples

    or better yet if the number of samples is an even power of 2, call it 2^N, then use

    Average = Sum >> N

    which will be much faster than a division

  • Dionisis,

    You haven't clearly stated what your ADC sample rate needs to be.  You mentioned 100 kHz, but I get the feeling this is the frequency of the signal you need to sample.  If so, then you need to sample it faster, how much faster depends on what you are doing in your application.  So, what ADC sample rate do you need?

    Also, is this a realtime application?  In other words, do you need to continuously take samples and compute at the same time?  The preceeding is what we call a realtime application.  A non-realtime application would be where you can take some samples, stop sampling, and then process the samples.

    If your application is non-realtime, the easiest thing to do is just have the ADC sample at the rate you need, and have the CPU buffer each sample as it happens.  This will pretty much consume the CPU while you're taking data, but if that is acceptable then fine.  The CPU could actually just poll the ADCINT bit rather than taking the interrupt.

    I completely agree with Devin that dividing by a 2^N value will be much better.  You should take 2^N samples if at all possible.

    - David

     

  • David  thnx  a lot  for your proposal.

    I will definitely try to implement the shifting, however I think i misunderstood the pari ot 100Khz sampling. So I will try to make it clear.

    The signal to be sampled has a frequency of 100Khz , so repeats 100000 per sec. As a result the 100Khz is  a parameter to define the average value only.

    Thus, if  I will use my samples that correspond to a signal of lets say 101Khz (by miscalculation of the 100Khz interrupt)I will obtain a different average value. Now imagine that I have only 10 samples (small sampling rate of 1Mhz) and I do miss 1 sample. The error will be significant compared to the occasion of having 50 samples and miss one.

    Aver=( Sampl1+Sampl2+..+SampleN)  / N ,   thus the error is somehow reverse propotioanl to the number of samples N

  • Yes Devin

    Its a realtime application , where I will have also to implement a PI control and furthermore change the PWM TBHS register once per 10us

  • It sounds like you're just trying to find the average amplitude of the signal?  Why not just stick an analog low-pass filter on it and use the ADC to read the filter output?  You're probably using some signal conditioning amplifier on the ADC input anyway.  Lower the cut-off frequency to filter out most of the signal, and just leave the DC component.

    If the signal you're sampling is 100 kHz, you're going to need to sample it quite fast to get decent results.  Suppose you sample at 3.2 MSPS.  Then you have 32 samples in a single period of the signal.  I don't know if that is enough to give you good results for the average value.  It depends on what the profile of the waveform looks like.

    - David

  • That could be a perfect solution but is somehow more complicated.

    To begin with you are absolutely right , I use a signal conditioning cirquit at the input. The signal of interest is a sinusoidal waveform where I inject a DC value to obtain the 0-3,3 V input.

    So I do need the max. samples possible ,and I do need to continue sampling during the calculation of the Average Value (to obtain the next period average).

    32 samples is an adequate number if it is possible to be achieved.