2017-01-09 04:28 AM
Hello all,
I have read through all contributions (e.g.,
https://community.st.com/0D50X00009XkdjTSAR
) and cubemx (1.5.0) examples I found but did not find a working solution. Timer triggered, single channel sampling via DMA works nicely (ADC1, but I checked also the other channels), see code extraction below. As soon as I comment (1) and uncomment (2) I do not get a DMA interrupt anymore.What do I miss?
Thanks, MarcusADC_HandleTypeDef adcHdl1;
ADC_HandleTypeDef adcHdl2;
ADC_HandleTypeDef adcHdl3;
DMA_HandleTypeDef adcDmaHdl2_0;
DMA_HandleTypeDef adcDmaHdl2_1;
DMA_HandleTypeDef adcDmaHdl2_3;static uint32_t adcData[6];
int main(void) {
...
MX_ADC_Init();
/*(1)*/ HAL_ADC_Start_DMA(&adcHdl1, adcData, 2); // DMA single channel ADC
/*(2)*/ //HAL_ADCEx_MultiModeStart_DMA(&adcHdl1, (uint32_t *)adcData, 6); // DMA multimode (triple) ADC
while(1);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *adcHdl) {
...
}
void MX_ADC_Init(void) {
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
adcHdl1.Instance = ADC1;
adcHdl2.Instance = ADC2;
adcHdl3.Instance = ADC3;
adcSetParameters(&adcHdl1);
adcHdl1.Init.DMAContinuousRequests = ENABLE;
adcHdl1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T5_TRGO;
adcHdl1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
adcSetParameters(&adcHdl2);
adcHdl2.Init.DMAContinuousRequests = DISABLE;
adcHdl2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
adcHdl2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
adcSetParameters(&adcHdl3);
adcHdl3.Init.DMAContinuousRequests = DISABLE;
adcHdl3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
adcHdl3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
if (HAL_ADC_Init(&adcHdl1) != HAL_OK) Error_Handler(PANIC);
if (HAL_ADC_Init(&adcHdl2) != HAL_OK) Error_Handler(PANIC);
if (HAL_ADC_Init(&adcHdl3) != HAL_OK) Error_Handler(PANIC);
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&adcHdl1, &sConfig) != HAL_OK) Error_Handler(PANIC);
sConfig.Channel = ADC_CHANNEL_6;
if (HAL_ADC_ConfigChannel(&adcHdl2, &sConfig) != HAL_OK) Error_Handler(PANIC);
sConfig.Channel = ADC_CHANNEL_4;
if (HAL_ADC_ConfigChannel(&adcHdl3, &sConfig) != HAL_OK) Error_Handler(PANIC);
/**Configure the ADC multi-mode */
/* (2) */
/* multimode.Mode = ADC_TRIPLEMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_1;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&adcHdl1, &multimode);
*/
}
void adcSetParameters(ADC_HandleTypeDef* adcHdl) {
adcHdl->Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
adcHdl->Init.Resolution = ADC_RESOLUTION12b;
adcHdl->Init.ScanConvMode = DISABLE;
adcHdl->Init.ContinuousConvMode = DISABLE;
adcHdl->Init.DiscontinuousConvMode = DISABLE;
adcHdl->Init.DataAlign = ADC_DATAALIGN_RIGHT;
adcHdl->Init.NbrOfConversion = 1;
adcHdl->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHdl) {
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_DMA2_CLK_ENABLE();
if(adcHdl->Instance==ADC1) {
__ADC1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
adcDmaHdl2_0.Instance = DMA2_Stream0;
adcDmaHdl2_0.Init.Channel = DMA_CHANNEL_0;
adcDmaHdl2_0.Init.Direction = DMA_PERIPH_TO_MEMORY;
adcDmaHdl2_0.Init.PeriphInc = DMA_PINC_DISABLE;
adcDmaHdl2_0.Init.MemInc = DMA_MINC_ENABLE;
adcDmaHdl2_0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
adcDmaHdl2_0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
adcDmaHdl2_0.Init.Mode = DMA_CIRCULAR;
adcDmaHdl2_0.Init.Priority = DMA_PRIORITY_HIGH;
adcDmaHdl2_0.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
adcDmaHdl2_0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
adcDmaHdl2_0.Init.MemBurst = DMA_MBURST_SINGLE;
adcDmaHdl2_0.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&adcDmaHdl2_0);
__HAL_LINKDMA(adcHdl, DMA_Handle, adcDmaHdl2_0);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
else if(adcHdl->Instance==ADC2) { ... }
else if(adcHdl->Instance==ADC3) { ... }
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
}
void DMA2_Stream0_IRQHandler(void) {
HAL_DMA_IRQHandler(&adcDmaHdl2_0);
}
#timer #dma #interrupt #interrupts #hal #triple-mode #stm32f7 #adc2017-01-17 06:48 AM
Hello
Eger.Marcus
,Try with the new release of CubeMx 4.0,then let me know about your update.
Regards
Imen
2017-01-18 04:56 AM
The problem seems to be solved:
1) I had to start the ADCs in a correct sequence (adc3 and adc2 before adc1) in main() such as
if (HAL_ADC_Start(&adcHdl3) != HAL_OK)
Error_Handler(SOME_ERROR);
if (HAL_ADC_Start(&adcHdl2) != HAL_OK)
Error_Handler(SOME_ERROR);
if (HAL_ADCEx_MultiModeStart_DMA(&adcHdl1, (uint32_t *)adcData, 3) != HAL_OK)
Error_Handler(SOME_ERROR);
2) I had to set (the same as in my code extract above)
multimode.DMAAccessMode = ADC_DMAACCESSMODE_1
otherwise the HAL_ADC_ErrorCallback() is fired.
Unfortunately, CubeMX does not help a lot, here (except point 2, which I did right by chance). I got the hint for the major point from an ST developer.
- Marcus
2017-01-18 06:12 AM
Hi
Eger.Marcus
,I'm pleased
to hear
that your problem has been resolved.Thank you for posting your issueand how you fixed it.
Regards
Imen
2019-03-01 08:49 AM
Hi Marcus,
I am also struggling with this issue, could you please if possible upload your full code/project somewhere?
Thanks!