2022-04-18 08:41 AM
So, I have TIM2 setup to trigger an ADC conversion and the DMA moves the samples out to RAM. I want to do this every 100us for 1000 iterations. Sounds pretty straight forward. There are 3 ADC channels being sampled using the sequencer on every trigger, so 3000 samples total. Everything works except for the timing. I turned on the timer interrupt and I am only getting to around 600 interrupts when the DMA reports that all the samples have been transferred. I expect there to be 1000 timer ticks. It seems like the ADC is not getting triggered on the timer interrupt, but on something else. Ive tried a lot of configurations and it never seems to change the outcome. Im stumped... Micro is the STM32WB55
Timer setup:
SENS_Tim2.Instance = TIM2;
SENS_Tim2.Init.Prescaler = ((SystemCoreClock / 1000000u) - 1u); // Scale input clock to 1mhz
SENS_Tim2.Init.CounterMode = TIM_COUNTERMODE_UP;
SENS_Tim2.Init.Period = ((1000000u / SENS_PUMP_SAMPLE_FREQ) - 1u);
SENS_Tim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
SENS_Tim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
LOG_ASSERT_RETVAL(HAL_TIM_Base_Init(&SENS_Tim2));
clkCfg.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
LOG_ASSERT_RETVAL(HAL_TIM_ConfigClockSource(&SENS_Tim2, &clkCfg));
mCfg.MasterOutputTrigger = TIM_TRGO_UPDATE;
mCfg.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
LOG_ASSERT_RETVAL(HAL_TIMEx_MasterConfigSynchronization(&SENS_Tim2, &mCfg));
LOG_ASSERT_RETVAL(HAL_TIM_Base_Start_IT(&SENS_Tim2));
ADC setup:
(void)memset(&SENS_Adc, 0 , sizeof(SENS_Adc));
// Count the number of channels to convert
convCount = SENS_countChannels();
// Need at least 1.
LOG_ASSERT(convCount > 0);
// Clock config: SYSCLK -> HCLK1 -> APB2 PCLK2 -> ADC CLK
// SYSCLK = HSE, 32 MHz
// APB PCLK2 = HSE / 1
// ADC CLK = PCLK / 2 = 16 MHz
SENS_Adc.Instance = ADC1;
SENS_Adc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
SENS_Adc.Init.Resolution = ADC_RESOLUTION_12B;
SENS_Adc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
SENS_Adc.Init.ScanConvMode = ADC_SCAN_ENABLE;
SENS_Adc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
SENS_Adc.Init.LowPowerAutoWait = DISABLE;
SENS_Adc.Init.ContinuousConvMode = DISABLE;
SENS_Adc.Init.NbrOfConversion = convCount;
SENS_Adc.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
SENS_Adc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_FALLING;
SENS_Adc.Init.DMAContinuousRequests = DISABLE;
SENS_Adc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
SENS_Adc.Init.OversamplingMode = ENABLE;
SENS_Adc.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_4;
SENS_Adc.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_2;
SENS_Adc.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
SENS_Adc.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
// Init the ADC
LOG_ASSERT_RETVAL(HAL_ADC_Init(&SENS_Adc));
// Setup common config
cfg.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
cfg.SingleDiff = ADC_SINGLE_ENDED;
cfg.OffsetNumber = ADC_OFFSET_NONE;
// Set SMPS to Bypass mode
HAL_PWREx_SMPS_SetMode(PWR_SMPS_BYPASS);
// Setup the ADC DMA
DMAMGR_SessionStart(DMAMGR_ADC);
// Configure each channel
for(i = 0; i < convCount; ++i)
{
cfg.Channel = SENS_AdcChannel[SENS_AdcMeasurementChannels[i]];
cfg.Rank = SENS_IndexToRank[i];
// configure the channel
LOG_ASSERT_RETVAL(HAL_ADC_ConfigChannel(&SENS_Adc, &cfg));
}
Solved! Go to Solution.
2022-04-18 12:06 PM
Never mind, I would delete this post if I could, but I cant... Issue was the interrupt frequency was too high for the load...
2022-04-18 12:06 PM
Never mind, I would delete this post if I could, but I cant... Issue was the interrupt frequency was too high for the load...
2022-04-18 12:24 PM
Mark as answered