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.

ADC interrupt service

Other Parts Discussed in Thread: HALCOGEN

Hi,

I'm trying to setup an application to acquire continuously by an ADC channel, The ADC is triggered in single conversion mode by the RTI. At FIFO full the ADC should call an iterrupt function to treat the data. The application should run indefenitly.

My HalCoGenSteps:

  • enable RTI, ADC1 and SCI2 drivers (the latter for debug messages)
  • enable ADC1 event IRQ (number 14) in VIM channel 0-31 panel
  • in "ADC1 Group event" panel set FIFO size to 32, RTI_COMP0 as trigger and Enable PIN0
  • in "ADC1 Memory" tab set BNDA to 32 and BNDB to 0

In the sys_main.c main function I've added:

    sciInit();

    adcInit();
    adcREG1->GxINTCR[0] = 0x0f;

    adcEnableNotification(adcREG1,adcGROUP0);
    adcStartConversion(adcREG1,adcGROUP0);

    rtiInit();
    rtiStartCounter(rtiCOUNTER_BLOCK0);
    rtiREG1-> SETINTENA = (0x01U << 8);
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    rtiStartCounter(rtiCOUNTER_BLOCK0);
    _enable_IRQ();

    while(1);

Running the code the "adc1Group0Interrupt" function (the ADC IRQ callbacjk) is called only once.

Where is the error? Do I forgot something?

Thank you,

Matteo

  • Hello Matteo,

    I have asked one of our ADC experts to take a look at your question. They should get back with shortly.

  • Hi Matteo,

    There are two issues:

    1. The BNDB value must be larger than the BNDA value. The difference (BNDB - BNDA) defines the number of buffers available to store group1 conversion results. This is okay for now since you are not using group1.
    2. The RTI interrupt signal is a "level" signal. Essentially, once the RTI interrupt condition is met, an interrupt flag gets set, which provides the rising edge required to trigger the ADC conversion. In order to trigger subsequent conversions using the RTI compare interrupt, this interrupt flag must be first cleared. A provision is included in the RTI module, which is unfortunately left out of the TRM. You an find the description of this feature in this earlier forum post: http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/133573/804226.aspx#804226
    Let me know if this solves your problem.
    Regards,
    Sunil
  • Hi Sunil,

    thank you for the answer but that's not the case you describe. In my case the RTI counter is updated every compare event, so it runs continuoously. I've tested this yet with another application.

    The problem here was to connect the "RTI compare 0" event in the "VIM Cahnnel 0-31" panel. In my first try I've not connected the interrupt because the tms570ls3137-rev(B) Datasheet exìplicitly says (Par 5.2.2):

    "For the RTI compare 0 interrupt source, the connection is made directly from the output of the RTI module. That is, the interrupt condition can be used as a trigger source even if the actual interrupt is not signaled to the CPU."

    Is that an error of the datasheet manual? (Moreover this NOTE is repeated 3 or 4 times in the manual).



  • Hi Matteo,

    I need to draw a picture to explain this better.

    As the image above shows, there are 3 "switches" or enables on the path between when the RTI indicates that an interrupt condition is met (sets the flag) and the CPU. The note in the documentation states that none of these switches need to be closed in order to use the RTI compare interrupt flag to trigger an ADC conversion, as also shown in the figure.

    The point I was trying to make is that when you do not truly generate an interrupt to the CPU by "closing" the three switches shown in the figure, there must be an alternate means to reset the RTI compare interrupt flag once it gets set. This mechanism is provided inside the RTI module itself, and will be documented in an update to the TRM. This mechanism is documented in the forum post that I had referenced.

    This will allow you to continue to trigger multiple ADC single-conversion sequences using the RTI compare 0 interrupt flag without actually interrupting the CPU each time.

    Regards,

    Sunil

  • Hi Sunil,

    where are the three "switches"?Perhaps using the VIM interrupt table in HalCoGen I enable all of them?

    Why if I don't connect the "RTI compare 0" in the above table my ADC is not triggered? From your Image the RTI-ADC connection seems uniterruptable but that's not my behaviour.

  • Hi Matteo,

    I need to make a correction to the figure:

    Switch 1 is inside the RTI module. This is the enable for the compare 0 interrupt, and is "closed" by your software enabling the compare 0 interrupt.

    Switch 2 is inside the VIM module. This is the enable for each interrupt request line input to the VIM. This is what was originally missing in your code, as you identified.

    Switch 3 is inside the CPU. This enables the CPU to actually respond to an interrupt.

    Given all this, consider the following information independent of what you need to get the RTI interrupt to the CPU.

    You don't actually need to interrupt the CPU in order to use the compare 0 condition to trigger the ADC. That is, you only need to "close" switch 1 in the above figure to trigger the ADC.

    The ADC module allows you to configure the edge that will trigger the conversion: rising/falling/either. The default selection is to look for a falling edge on the selected trigger event.

    When you choose the RTI compare 0 interrupt to trigger the ADC, the connection shown in the above figure allows the trigger event to happen even if the CPU is not really interrupted (typically, switch 2 inside VIM is left open). The condition of the RTI FRC matching the compare value causes the trigger signal to go high (rising edge). You need to configure the RTI automatic interrupt clear mechanism to clear this trigger signal (falling edge) when the FRC matches another compare value which is programmable as well. This allows you to create a "PWM" output on the trigger line that can trigger the ADC repeatedly and periodically as per your configuration.

    Regards, Sunil

  • Thank you Sunil, very clear.

    Can you please specify the three instructions (or the three registers) that corresponds to the three switches?

    Thank you,

    Matteo

  • Matteo,

    Switch 1 is closed by enabling interrupt request to get out of the RTI module. This is done by setting the correct bit in the RTI module's RTISETINTENA register. In your code, this is done by:

    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);

    Switch 2 is closed by enabling the appropriate channel number inside the VIM module's REQENASET register. This was missing in the code that you had posted.

    Switch 3 is closed by enabling the CPU to respond to IRQ requests. This is done by clearing the "I" bit in the CPSR, and is done in your code by:

    _enable_IRQ();

    Regards, Sunil


  • Sunil,

    I'm sorry but your scheme does not correspond to the behaviour I'm experimenting.

    I've setup a test code to acquire from ADC triggered by RTI_COMP0.The ADC is setup to call its ISR every 32 samples so I can easly verify if it's running or not. I've put debug messages both in the RTI_Compare0 and in the ADC event ISR.

    The code works only if I:

    1. enable RTI_COMPARE0 in "VIM Channel 0-31" panel in Halcogen
    2. enable rti Notification using rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    3. enable IRQ calling _enable_IRQ();

    the step 3 is required to download ADC data from FIFO in its ISR, and is not strictly related to RTI. According to your explanation the ADC should work with steps 2 and 3 only , and the step 1 could be avoided, but it doesn't.

    Matteo

  • According to your explanation ifI don't enable the RTI_COMPARE0 in VIM but instead enable the INTCLRENABLE0 using:

    rtiREG1->INTCLRENABLE &= 0xfffffff0;

    the RTI should emit continuos trigger for the ADC, but it doesn't. For my code to work (for ADC to be continuosly triggered) I need to enable the VIM interrupt too. Why? Do I forgot something?

  • Matteo,

    You also need to configure the initial compare value that will be used to clear the flag. This needs to be configured in the RTICOMP0CLR register. For example, if your initial compare value to set the flag is 5000, you could configure the initial clear compare value to be 10000. The same update compare value (RTIUDCP0) will be used to increment both these compare values.

    Regards, Sunil

  • The value to be configure is the COMP0CLR?

    If myinitial setup (in rtiInit) is:

      rtiREG1->CMP[0U].COMPx = 10U;

      rtiREG1->CMP[0U].UDCPx = 10U;

    I need to add:

      rtiREG1->COMP0CLR = 10U;

    right?

    Why in your example you use different values (10000 and 5000) ?

  • I just used the values as an example, without regard to what you had in your application.

    In your case, you are setting the flag first when the FRC becomes 10, 20, 30, ... So in order to get a 50% duty cycle waveform the flag would need to be cleared when the FRC becomes 15, 25, 35, ...

    That is, the initial COMP0CLR value would be 15.

    Regards, Sunil

  • It works. Thank you