Skip to main content
Associate II
July 12, 2024
Solved

stm32h750 vb adc+dma LLlib issue

  • July 12, 2024
  • 4 replies
  • 2642 views
Spoiler
 

HELLO,

I have 2 issues

1. A bug report

CubeMx generated init code is wrong with LL lib

mize_0-1720768050887.png

mize_1-1720768115515.png

the marco config is not change from HAL to LL

2. I cannot enable dual ADC1/ADC2 continous conversion with dma, and at every tranfer finish trigger a intterupt

below is my code 

/* ADC1 init function */

void MX_ADC1_Init(void)

{

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

LL_ADC_InitTypeDef ADC_InitStruct = {0};

LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};

LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

/* Peripheral clock enable */

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC12);

LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC);

/**ADC1 GPIO Configuration

PC4 ------> ADC1_INP4

*/

GPIO_InitStruct.Pin = LL_GPIO_PIN_4;

GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;

GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/* ADC1 DMA Init */

/* ADC1 Init */

LL_DMA_SetPeriphRequest(DMA1, LL_DMA_STREAM_4, LL_DMAMUX1_REQ_ADC1);

LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_4, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_4, LL_DMA_PRIORITY_VERYHIGH);

LL_DMA_SetMode(DMA1, LL_DMA_STREAM_4, LL_DMA_MODE_CIRCULAR);

LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_4, LL_DMA_PERIPH_NOINCREMENT);

LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_4, LL_DMA_MEMORY_NOINCREMENT);

LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_4, LL_DMA_PDATAALIGN_WORD);

LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_4, LL_DMA_MDATAALIGN_WORD);

LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_4);

/* USER CODE BEGIN ADC1_Init 1 */

/* USER CODE END ADC1_Init 1 */

/** Common config

*/

LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);

ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_16B;

ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;

LL_ADC_Init(ADC1, &ADC_InitStruct);

ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;

ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;

ADC_REG_InitStruct.SequencerDiscont = DISABLE;

ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;

ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;

LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);

ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;

ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_DUAL_REG_SIMULT;

ADC_CommonInitStruct.MultiTwoSamplingDelay= LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES_5;

LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);


/* Disable ADC deep power down (enabled by default after reset state) */

LL_ADC_DisableDeepPowerDown(ADC1);

/* Enable ADC internal voltage regulator */

LL_ADC_EnableInternalRegulator(ADC1);

/* Delay for ADC internal voltage regulator stabilization. */

/* Compute number of CPU cycles to wait for, from delay in us. */

/* Note: Variable divided by 2 to compensate partially */

/* CPU processing cycles (depends on compilation optimization). */

/* Note: If system core clock frequency is below 200kHz, wait time */

/* is only a few CPU processing cycles. */

__IO uint32_t wait_loop_index;

wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);

while(wait_loop_index != 0)

{

wait_loop_index--;

}

/** Configure Regular Channel

*/

LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_4);

LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_4, LL_ADC_SAMPLINGTIME_1CYCLE_5);

LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_4, LL_ADC_SINGLE_ENDED);

/* USER CODE BEGIN ADC1_Init 2 */

LL_ADC_StartCalibration(ADC1,LL_ADC_CALIB_OFFSET,LL_ADC_SINGLE_ENDED);

//HAL_ADCEx_Calibration_Start(&hadc1,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校验

/* USER CODE END ADC1_Init 2 */

}

/* ADC2 init function */

void MX_ADC2_Init(void)

{

/* USER CODE BEGIN ADC2_Init 0 */

/* USER CODE END ADC2_Init 0 */

LL_ADC_InitTypeDef ADC_InitStruct = {0};

LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

/* Peripheral clock enable */

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC12);

LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);

/**ADC2 GPIO Configuration

PB1 ------> ADC2_INP5

*/

GPIO_InitStruct.Pin = LL_GPIO_PIN_1;

GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;

GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN ADC2_Init 1 */

/* USER CODE END ADC2_Init 1 */

/** Common config

*/

LL_ADC_SetOverSamplingScope(ADC2, LL_ADC_OVS_DISABLE);

ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_16B;

ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;

LL_ADC_Init(ADC2, &ADC_InitStruct);

ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;

ADC_REG_InitStruct.SequencerDiscont = DISABLE;

ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;

ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;

LL_ADC_REG_Init(ADC2, &ADC_REG_InitStruct);

/* Disable ADC deep power down (enabled by default after reset state) */

LL_ADC_DisableDeepPowerDown(ADC2);

/* Enable ADC internal voltage regulator */

LL_ADC_EnableInternalRegulator(ADC2);

/* Delay for ADC internal voltage regulator stabilization. */

/* Compute number of CPU cycles to wait for, from delay in us. */

/* Note: Variable divided by 2 to compensate partially */

/* CPU processing cycles (depends on compilation optimization). */

/* Note: If system core clock frequency is below 200kHz, wait time */

/* is only a few CPU processing cycles. */

__IO uint32_t wait_loop_index;

wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);

while(wait_loop_index != 0)

{

wait_loop_index--;

}

/** Configure Regular Channel

*/

LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5);

LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_1CYCLE_5);

LL_ADC_SetChannelSingleDiff(ADC2, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED);

/* USER CODE BEGIN ADC2_Init 2 */

// HAL_ADCEx_Calibration_Start(&hadc2,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);

LL_ADC_StartCalibration(ADC2,LL_ADC_CALIB_OFFSET,LL_ADC_SINGLE_ENDED);

/* USER CODE END ADC2_Init 2 */

}

 

before is generated and below is added in main

 

LL_ADC_SetMultiDMATransfer(ADC12_COMMON,LL_ADC_MULTI_REG_DMA_EACH_ADC);

LL_DMA_SetDataLength(DMA1,LL_DMA_STREAM_4,4);

LL_DMA_ConfigAddresses(DMA1,LL_DMA_STREAM_4,(uint32_t)&(ADC12_COMMON->CDR),(uint32_t)&ADC_ConvertedValueDual[0],LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

LL_ADC_Enable(ADC1);

LL_ADC_Enable(ADC2);

LL_ADC_EnableIT_OVR(ADC1);

LL_DMA_EnableIT_TC(DMA1,LL_DMA_STREAM_4);

LL_DMA_EnableBufferableTransfer(DMA1,LL_DMA_STREAM_4);

LL_DMA_EnableStream(DMA1,LL_DMA_STREAM_4);


expected behavior is the adc1/2 convert periodicly every 5cycles, and dma transfer data to &ADC_ConvertedValueDual[0]

then the DMA1_Stream4_IRQHandler() should've been triggered, however none of these are happened

if you have any suggestion please kindly reply

thx alot

 

 

This topic has been closed for replies.
Best answer by Imen.D

Hello @mize ,

  1. I confirmed the 1st reported issue. For that, an internal ticket number 186541 is submitted in order to fix this.
  2. Did you check for transfer error interrupt?

How you configure and handle the DMA transfer complete interrupt ?

Did you start ADC conversions using LL_ADC_REG_StartConversion?

More details on the configuration of dual ADC mode and DMA provided in this section of RM0433.

4 replies

ST Technical Moderator
July 12, 2024

Hello @mize ,

Please share your ioc file and the version used of CubeMx, this will help to reproduce the case.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
mizeAuthor
Associate II
July 15, 2024

HI,

   IOC file is attached, cubemx version is 6.12.0-RC9

   THX

   by the way any idea about my 2nd issue?

Imen.DBest answer
ST Technical Moderator
July 15, 2024

Hello @mize ,

  1. I confirmed the 1st reported issue. For that, an internal ticket number 186541 is submitted in order to fix this.
  2. Did you check for transfer error interrupt?

How you configure and handle the DMA transfer complete interrupt ?

Did you start ADC conversions using LL_ADC_REG_StartConversion?

More details on the configuration of dual ADC mode and DMA provided in this section of RM0433.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
ST Technical Moderator
December 2, 2024

Hello @mize ,

This issue is fixed in the latest release of STM32CubeMx v6.13.0.

Thank you for your contribution.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks