Issue with using Triger MUX with ADC ISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issue with using Triger MUX with ADC ISR

675 Views
qingg
Contributor I

Hi,

I'm using the i.MX7ULP evaluation board, IAR Embedded Workbench Arm 8.50.1, and J-Link Plus for a project. And I encountered several issues where the ACD interrupt is not called.

I used example trgmux_lptmr_trigger_lpit under .\boards\evkmcimx7ulp\driver_examples\trgmux\lptmr_trigger_lpit in NXP’s official SDK_2.9.0_EVK-MCIMX7ULP as a starting point for my project (will be referred to as “Example 1” below). I also added some code from lpadc_single_interrupt under .\boards\evkmcimx7ulp\driver_examples\lpadc\single_interrupt in the same SDK (will be referred to as “Example 2” below). I needed both functionalities of timer trigger and ADC interrupt.

Specifically:

  • I moved the initialization portion of the code in Example 2's main() to a new function called AdcInit(). I then added a call to this function from DEMO_InitLptmrTrigger() which is called by main() in Example 1.
  • I made the following changes to DEMO_InitLptmrTrigger() from Example 1:

 

mLpadcConfigStruct.FIFOWatermark = 15U; /* Set watermark as 15U. */
LPTMR_SetTimerPeriod(LPTMR0, 1600U);​

 

The first statement above is to get 16 samples before the ADC triggers an ISR. The second statement above is to set the sampling period to 100 microseconds (16 MHz / (1 s / 100 us)).

  • I added ADC1_IRQHandler()/DEMO_LPADC_IRQ_HANDLER_FUNC() from Example 2 to Example 1
  • I added my own code to ADC1_IRQHandler() that reads all 16 values from ADC buffer when ADC1_IRQHandler() is called (which means the ADC buffer is full with 16 values):

 

    g_LpadcConversionInProgressFlag = true;
    int i = 0;
    while (g_LpadcConversionInProgressFlag)
    {
        g_LpadcConversionInProgressFlag = LPADC_GetConvResult(DEMO_LPADC_BASE, &g_LpadcResultConfigStruct);
        local_data[i] = ((g_LpadcResultConfigStruct.convValue) >> 3U);
        i++;
    }

 

  • I added my own code to ADC1_IRQHandler() that toggles a GPIO pin whenever ADC1_IRQHandler() is called:

 

    /* Toggle GPIO to PIN J11-1*/
    GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
    SDK_ISR_EXIT_BARRIER;

 

  • I removed function LPIT0_IRQHandler() in Example 1.

The resulting code is attached.

The only way to have ADC1_IRQHandler() called consistently, as observed through the GPIO toggle, is to reset the board by pressing the physical reset button.

If I stop debugging from IAR, and restart debugging, then ADC1_IRQHandler() is still called.

If I try to load another workspace, and then reload this workspace without resetting the board, then ADC1_IRQHandler() is not called.

If I reset the board and start debugging, ADC1_IRQHandler() is called again.

If I choose Reset in IAR's Debug menu, it will jump back to main(), and when I choose Go in IAR's Debug menu, ADC1_IRQHandler() is not called anymore.

In summary, either of these two things makes ADC1_IRQHandler() stop being called anymore: 1. Load another workspace and reload this workspace. 2. Reset in the debugging process so it jumps back to main() and continue debugging.

Can you help with this issue? Thank you!

Labels (1)
0 Kudos
1 Reply

605 Views
davidguinn
Contributor II

Hi,

I'm Qing's colleague, I looked into the issue, a long story short, if the system is reset when the NVIC's ADC1 interrupt is active(i.e. NVIC_IABR1's ACTIVE59 is set to 1), then the interrupt will never be executed again.  The ADC1 active's bit is not cleared if there is a reset in middle of the interrupt(i.e. use the reset processor button in the IDE).  Once that active bit is set for an interrupt, according to ARM's v7 documentation:

If an interrupt is active when it is disabled, it remains in the active state until this is cleared by a reset or an exception return.

Therefore as a temporary work around, I added code to detect this issue and do a reset:

if(NVIC_GetActive(DEMO_LPADC_IRQn))
{
  NVIC_SystemReset();
}

 

This does fix the issue, the Active bit is cleared and the ADC interrupt is cleared.  Is there an alternative way to clear NVIC_IABR1 bit(s) than a system reset?

Thank you,

David 

0 Kudos