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.

MSPM0G1518: Synchronized ADC sampling issue MSPM0G1518, MSPM0G1507, LP-MSPM0G3519

Part Number: MSPM0G1518
Other Parts Discussed in Thread: LP-MSPM0G3519, MSPM0G1507

Hello, 

in our current project were running the following configuration on a MSPM0G1518:

  • CPU clock @ 78MHz, ULPCLK @ 39MHz
  • TIMG7 triggers interrupt every 100 µs
  • In an interrupt handler SYSTICK timer is started and every 10th call of interrupt handler SYSTICK counter value is read and SYSTICK timer is restarted (used for CPU Load calculation)
  • Every call of interrupt handler ADC conversion is started (2 ADCs with sequence of 10 signals each), in every 10th call of interrupt handler the a DMA is configured to transmit the results

 

The somehow weird behaviors we see (described for MEMRES8 of ADC0, but they are present for all other MEMRES of ADC0 as well, but with varying amplitude for the peaks/ drops):

  1. The overall "stable" results vary over multiple MCU resets between 2 values: sometimes it's 490, sometimes 515 for the given input voltage
  2. Every 10th conversion (the one which is started along the DMA) the result varies from the other 9. When the "stable" result is 490, then we see a peak to 515, when stable is 515 we see a drop to 490. 
    The amplitude of the peak/ drop although reduces, when the CPU clock and ULPCLK is reduced to 32MHz).

 

Both behaviors we only see for ADC0, results of ADC1 are stable and don't show variation or drops.

When running both ADCs non synchronized at different timings (different conversion times, different clock divs or different source) both described effects completely disappear. Also when not starting conversion of ADC1, the ADC0 doesn't show the issue anymore. 

We also checked the interrupt handler including the ADC conversions/DMAs never exceeding the 100µs. They finish 15-20 µs before the next interrupt triggers.

 

We tried figuring out the issue with a reduced project. Although the peaks/ drops appear much less frequent (over multiple resets), they are not gone completely. The variation of the "stable" result still persists as well.

As already mentioned, our interrupt routine in the project includes some more code, but cannot be published here.

The point that the peak/ drop error occurs less frequent, when the interrupt routine is smaller made us think, we have a timing issue. But as I said, timing was checked and is fine. There are no overlapping interrupt routines/ ADC conversions. 

 

This issue was also reproduced using a LP-MSPM0G3519 as well as MSPM0G1507. 

  • We made another minimal project reproducing the issue. In the following you can find the source code:

    For ADC measurements we only used supply monitor (channel 15) referencing to VDDA and VREF. Every 100µs the ADC results are written to a buffer to observe in graph view.

    Our observation:

    1. ADC0 results are way less stable than those from ADC1. Is there a explanation for this?

    2. The 1ms periodic jumps (every 10 AD conversion) can be seen over all channels measuring with the same reference.

    3. The periodic jumps are less noticeable or disappear completely when ADC0 and ADC1 are running from different clocks.

    4. In the minimal project the spikes/drops have a lower amplitude than in the original project. There we see spikes with +/- 30 digits compared to the other samples. 

    5. When the spikes are not present from the beginning, increasing CPU load (increased delay_cycles) the spikes are much more likely to appear. When they present from the beginning, most of the time they vanish when changing CPU load.

    main.c:

    #include "ti_msp_dl_config.h"
    
    
    int main(void)
    {
        SYSCFG_DL_init();
        NVIC_EnableIRQ( TIMER_SWTICK_INST_INT_IRQN );
    
        while (1) {
            DL_SYSTICK_disable();
            __WFI();
        }
    }

    tmr.c handling the ISR:

    #include "ti_msp_dl_config.h"
    
    
    struct adc {
      struct __attribute__( ( packed, aligned( 4 ) ) ) {
        uint16_t u_supply_vref_0; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VREF as reference voltage */
        uint16_t u_supply_vdda_0; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VDDA as reference voltage */
        uint16_t u_supply_vref_1; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VREF as reference voltage */
        uint16_t u_supply_vdda_1; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VDDA as reference voltage */
        uint16_t u_supply_vref_2; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VREF as reference voltage */
        uint16_t u_supply_vdda_2; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VDDA as reference voltage */
        uint16_t u_supply_vref_3; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VREF as reference voltage */
        uint16_t u_supply_vdda_3; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VDDA as reference voltage */
        uint16_t u_supply_vref_4; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VREF as reference voltage */
        uint16_t u_supply_vdda_4; /**< U_SUPPLY, A0_15, Internal supply voltage monitor with VDDA as reference voltage */
      } results;
    };
    struct adc adc0;
    struct adc adc1;
    
    
    volatile uint16_t adc00[1000u];
    volatile uint16_t adc01[1000u];
    volatile uint16_t adc02[1000u];
    volatile uint16_t adc03[1000u];
    volatile uint16_t adc04[1000u];
    volatile uint16_t adc05[1000u];
    volatile uint16_t adc06[1000u];
    volatile uint16_t adc07[1000u];
    volatile uint16_t adc08[1000u];
    volatile uint16_t adc09[1000u];
    
    volatile uint16_t adc10[1000u];
    volatile uint16_t adc11[1000u];
    volatile uint16_t adc12[1000u];
    volatile uint16_t adc13[1000u];
    volatile uint16_t adc14[1000u];
    volatile uint16_t adc15[1000u];
    volatile uint16_t adc16[1000u];
    volatile uint16_t adc17[1000u];
    volatile uint16_t adc18[1000u];
    volatile uint16_t adc19[1000u];
    
    volatile uint16_t     timeslice[1000u];
    volatile uint16_t     i;
    
    struct tmr {
      volatile uint32_t timestamp; /**< Time since MCU startup in ms */
      volatile uint16_t cpu_load;  /**< CPU busy time within last 1 ms. */
    };
    struct tmr tmr;
    
    /* Default to 10µs delay */
    volatile uint32_t delay = 780u;
    
    
    /**
     * @brief Handle interrupts triggered by TIMER_SWTICK
     * @details
     *
     */
    void TIMER_SWTICK_INST_IRQHandler( void ) {
      static uint8_t time_slice = 10u;  
    
      DL_SYSTICK_enable();
    
      adc00[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_0 );
      adc01[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_1 );
      adc02[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_2 );
      adc03[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_3 );
      adc04[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_4 );
      adc05[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_5 );
      adc06[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_6 );
      adc07[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_7 );
      adc08[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_8 );
      adc09[i] = DL_ADC12_getMemResult( ADC0_INST, DL_ADC12_MEM_IDX_9 );
    
      adc10[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_0 );
      adc11[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_1 );
      adc12[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_2 );
      adc13[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_3 );
      adc14[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_4 );
      adc15[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_5 );
      adc16[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_6 );
      adc17[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_7 );
      adc18[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_8 );
      adc19[i] = DL_ADC12_getMemResult( ADC1_INST, DL_ADC12_MEM_IDX_9 );
    
      timeslice[i] = time_slice;
      i++;
    
      if ( 1000 <= i ) {
        i = 0;
      }
    
      /* Execute every 10th time slice (1ms period) */
      if ( 10u <= time_slice ) {
        /* Store CPU busy time and reset timer */
        tmr.cpu_load = (DL_SYSTICK_getPeriod() - DL_SYSTICK_getValue()) / 780u;
        DL_SYSTICK_resetValue();
        time_slice = 0u;
    
        /* Configure and enable DMAs to transfer all ADC results to process them next time slice in task_1ms  */
        DL_DMA_disableChannel( DMA, DMA_CH0_ADC0_CHAN_ID );
        DL_DMA_setSrcAddr( DMA, DMA_CH0_ADC0_CHAN_ID, DL_ADC12_getFIFOAddress( ADC0_INST ));
        DL_DMA_setDestAddr( DMA, DMA_CH0_ADC0_CHAN_ID, (uint32_t)&adc0.results );
        DL_DMA_setTransferSize( DMA, DMA_CH0_ADC0_CHAN_ID, 5u  );
      
        DL_DMA_disableChannel( DMA, DMA_CH1_ADC1_CHAN_ID );
        DL_DMA_setSrcAddr( DMA, DMA_CH1_ADC1_CHAN_ID, DL_ADC12_getFIFOAddress( ADC1_INST ));
        DL_DMA_setDestAddr( DMA, DMA_CH1_ADC1_CHAN_ID, (uint32_t)&adc1.results );
        DL_DMA_setTransferSize( DMA, DMA_CH1_ADC1_CHAN_ID, 5u  );
    
        DL_DMA_enableChannel( DMA, DMA_CH0_ADC0_CHAN_ID );
        DL_DMA_enableChannel( DMA, DMA_CH1_ADC1_CHAN_ID );
      }
    
     
      /* Enable and start ADC conversion */
      DL_ADC12_enableConversions( ADC0_INST );
      DL_ADC12_enableConversions( ADC1_INST );
      DL_ADC12_startConversion( ADC0_INST );
      DL_ADC12_startConversion( ADC1_INST);
    
      time_slice++;
      tmr.timestamp++;
    
      DL_Common_delayCycles(delay);
    }

    syscfg

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "MSPM0G351X" --part "Default" --package "LQFP-100(PZ)" --product "mspm0_sdk@2.10.00.04"
     * @v2CliArgs --device "MSPM0G3519" --package "LQFP-100(PZ)" --product "mspm0_sdk@2.10.00.04"
     * @versions {"tool":"1.26.2+4477"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const ADC12   = scripting.addModule("/ti/driverlib/ADC12", {}, false);
    const ADC121  = ADC12.addInstance();
    const ADC122  = ADC12.addInstance();
    const Board   = scripting.addModule("/ti/driverlib/Board");
    const DAC12   = scripting.addModule("/ti/driverlib/DAC12");
    const GPIO    = scripting.addModule("/ti/driverlib/GPIO", {}, false);
    const GPIO1   = GPIO.addInstance();
    const SYSCTL  = scripting.addModule("/ti/driverlib/SYSCTL");
    const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK");
    const TIMER   = scripting.addModule("/ti/driverlib/TIMER", {}, false);
    const TIMER1  = TIMER.addInstance();
    const VREF    = scripting.addModule("/ti/driverlib/VREF");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    const divider7       = system.clockTree["PLL_PDIV"];
    divider7.divideValue = 8;
    
    const divider9       = system.clockTree["UDIV"];
    divider9.divideValue = 2;
    
    const gate8  = system.clockTree["MFPCLKGATE"];
    gate8.enable = true;
    
    const multiplier2         = system.clockTree["PLL_QDIV"];
    multiplier2.multiplyValue = 39;
    
    const mux8       = system.clockTree["HSCLKMUX"];
    mux8.inputSelect = "HSCLKMUX_SYSPLL0";
    
    const mux12                                     = system.clockTree["SYSPLLMUX"];
    mux12.overrideworkaroundFCCPeriod_SYSPLL_ERR_01 = true;
    mux12.workaroundFCCPeriod_SYSPLL_ERR_01         = 32;
    
    const oscillator2           = system.clockTree["SYSOSC"];
    oscillator2.enableSYSOSCFCL = true;
    
    ADC121.$name                             = "ADC0";
    ADC121.sampClkSrc                        = "DL_ADC12_CLOCK_ULPCLK";
    ADC121.samplingOperationMode             = "sequence";
    ADC121.adcMem0_name                      = "U_SUPPLY_VREF_0";
    ADC121.adcMem0chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem0vref                       = "VREF";
    ADC121.adcMem0vrefp                      = "INTREF";
    ADC121.adcMem1_name                      = "U_SUPPLY_VDDA_0";
    ADC121.adcMem1chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem2_name                      = "U_SUPPLY_VREF_1";
    ADC121.adcMem2chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem2vref                       = "VREF";
    ADC121.adcMem2vrefp                      = "INTREF";
    ADC121.adcMem3_name                      = "U_SUPPLY_VDDA_1";
    ADC121.adcMem3chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem4_name                      = "U_SUPPLY_VREF_2";
    ADC121.adcMem4chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem4vref                       = "VREF";
    ADC121.adcMem4vrefp                      = "INTREF";
    ADC121.adcMem5_name                      = "U_SUPPLY_VDDA_2";
    ADC121.adcMem5chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem6_name                      = "U_SUPPLY_VREF_3";
    ADC121.adcMem6chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem6vref                       = "VREF";
    ADC121.adcMem6vrefp                      = "INTREF";
    ADC121.adcMem7_name                      = "U_SUPPLY_VDDA3";
    ADC121.adcMem7chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem8_name                      = "U_SUPPLY_VREF_4";
    ADC121.adcMem8chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem8vref                       = "VREF";
    ADC121.adcMem8vrefp                      = "INTREF";
    ADC121.adcMem9_name                      = "U_SUPPLY_VDDA_4";
    ADC121.adcMem9chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC121.adcMem2stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem3stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem4stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem5stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem6stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem7stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem8stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.adcMem9stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC121.enableFIFO                        = true;
    ADC121.configureDMA                      = true;
    ADC121.sampCnt                           = 1;
    ADC121.endAdd                            = 9;
    ADC121.enabledDMATriggers                = ["DL_ADC12_DMA_MEM1_RESULT_LOADED","DL_ADC12_DMA_MEM3_RESULT_LOADED","DL_ADC12_DMA_MEM5_RESULT_LOADED","DL_ADC12_DMA_MEM7_RESULT_LOADED","DL_ADC12_DMA_MEM9_RESULT_LOADED"];
    ADC121.sampleTime0                       = "15us";
    ADC121.sampleTime1                       = "5us";
    ADC121.sampClkDiv                        = "DL_ADC12_CLOCK_DIVIDE_4";
    ADC121.peripheral.$assign                = "ADC0";
    ADC121.DMA_CHANNEL.$name                 = "DMA_CH0_ADC0";
    ADC121.DMA_CHANNEL.addressMode           = "f2b";
    ADC121.DMA_CHANNEL.configureTransferSize = true;
    ADC121.DMA_CHANNEL.transferSize          = 5;
    ADC121.DMA_CHANNEL.peripheral.$assign    = "DMA_CH0";
    
    ADC122.$name                             = "ADC1";
    ADC122.samplingOperationMode             = "sequence";
    ADC122.adcMem0_name                      = "U_SUPPLY_VREF_0";
    ADC122.adcMem0chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem0vref                       = "VREF";
    ADC122.adcMem0vrefp                      = "INTREF";
    ADC122.adcMem1_name                      = "U_SUPPLY_VDDA_0";
    ADC122.adcMem1chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem2_name                      = "U_SUPPLY_VREF_1";
    ADC122.adcMem2chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem2vref                       = "VREF";
    ADC122.adcMem2vrefp                      = "INTREF";
    ADC122.adcMem3_name                      = "U_SUPPLY_VDDA_1";
    ADC122.adcMem3chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem4_name                      = "U_SUPPLY_VREF_2";
    ADC122.adcMem4chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem4vref                       = "VREF";
    ADC122.adcMem4vrefp                      = "INTREF";
    ADC122.adcMem5_name                      = "U_SUPPLY_VDDA_2";
    ADC122.adcMem5chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem6_name                      = "U_SUPPLY_VREF_3";
    ADC122.adcMem6chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem6vref                       = "VREF";
    ADC122.adcMem6vrefp                      = "INTREF";
    ADC122.adcMem7_name                      = "U_SUPPLY_VDDA3";
    ADC122.adcMem7chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem8_name                      = "U_SUPPLY_VREF_4";
    ADC122.adcMem8chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem8vref                       = "VREF";
    ADC122.adcMem8vrefp                      = "INTREF";
    ADC122.adcMem9_name                      = "U_SUPPLY_VDDA_4";
    ADC122.adcMem9chansel                    = "DL_ADC12_INPUT_CHAN_15";
    ADC122.adcMem2stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem3stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem4stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem5stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem6stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem7stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem8stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.adcMem9stime                      = "DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP1";
    ADC122.enableFIFO                        = true;
    ADC122.configureDMA                      = true;
    ADC122.sampCnt                           = 1;
    ADC122.endAdd                            = 9;
    ADC122.enabledDMATriggers                = ["DL_ADC12_DMA_MEM1_RESULT_LOADED","DL_ADC12_DMA_MEM3_RESULT_LOADED","DL_ADC12_DMA_MEM5_RESULT_LOADED","DL_ADC12_DMA_MEM7_RESULT_LOADED","DL_ADC12_DMA_MEM9_RESULT_LOADED"];
    ADC122.sampleTime0                       = "15us";
    ADC122.sampleTime1                       = "5us";
    ADC122.sampClkSrc                        = "DL_ADC12_CLOCK_ULPCLK";
    ADC122.sampClkDiv                        = "DL_ADC12_CLOCK_DIVIDE_4";
    ADC122.peripheral.$assign                = "ADC1";
    ADC122.DMA_CHANNEL.addressMode           = "f2b";
    ADC122.DMA_CHANNEL.configureTransferSize = true;
    ADC122.DMA_CHANNEL.$name                 = "DMA_CH1_ADC1";
    ADC122.DMA_CHANNEL.transferSize          = 5;
    ADC122.DMA_CHANNEL.peripheral.$assign    = "DMA_CH1";
    
    Board.configureUnused = true;
    
    DAC12.dacPosVREF                = "VEREFP";
    DAC12.dacOutputPinEn            = true;
    DAC12.dacOutput12               = 819;
    DAC12.peripheral.$assign        = "DAC0";
    DAC12.peripheral.OutPin.$assign = "PA15";
    DAC12.OutPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric0";
    
    GPIO1.$name                         = "CHARGER";
    GPIO1.associatedPins[0].$name       = "DEBUG_0";
    GPIO1.associatedPins[0].pin.$assign = "PB10";
    
    SYSCTL.clockTreeEn       = true;
    SYSCTL.validateClkStatus = true;
    
    SYSTICK.periodEnable = true;
    SYSTICK.period       = 16777216;
    
    TIMER1.timerPeriod        = "100 us";
    TIMER1.timerMode          = "PERIODIC";
    TIMER1.timerStartTimer    = true;
    TIMER1.interrupts         = ["ZERO"];
    TIMER1.interruptPriority  = "0";
    TIMER1.$name              = "TIMER_SWTICK";
    TIMER1.peripheral.$assign = "TIMG7";
    
    VREF.basicIntVolt                  = "DL_VREF_BUFCONFIG_OUTPUT_2_5V";
    VREF.checkVREFReady                = true;
    VREF.basicMode                     = "DL_VREF_ENABLE_ENABLE_DL_VREF_ENABLE_DISABLE";
    VREF.basicExtVolt                  = 2.5;
    VREF.peripheral.$assign            = "VREF";
    VREF.peripheral.vrefPosPin.$assign = "PA23";
    VREF.vrefPosPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric2";
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    Board.peripheral.$suggestSolution          = "DEBUGSS";
    Board.peripheral.swclkPin.$suggestSolution = "PA20";
    Board.peripheral.swdioPin.$suggestSolution = "PA19";
    

  • Hi Timon,

    Thanks for your patience. The mention of both ADC using the same clock, as well as the mention of DMA uses suggest to me two things: simultaneous switching noise on the shared analog supply and periodic spikes caused by bus contention during DMA register writes.

    Can you try the following modifications and see if this makes the issue go away:

    1. Use different clock sources for ADC0 and ADC1 (e.g., ULPCLK for ADC0, SYSOSC for ADC1)

    2. Move DMA reconfiguration out of the ISR to a lower-priority task, or pre-configure DMA with a fixed descriptor so no re-arm is needed on the 10th cycle.

    Best Regards,

    Diego Abad