cancel
Showing results for 
Search instead for 
Did you mean: 

stm32h750 vb adc+dma LLlib issue

mize
Associate II
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

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Imen.D
ST Employee

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.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

View solution in original post

3 REPLIES 3
Imen.D
ST Employee

Hello @mize ,

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

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

HI,

   IOC file is attached, cubemx version is 6.12.0-RC9

   THX

   by the way any idea about my 2nd issue?

Imen.D
ST Employee

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.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen