Skip to main content
Explorer II
July 12, 2024
Solved

stm32h750 vb adc+dma LLlib issue

  • July 12, 2024
  • 3 replies
  • 1505 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.

    3 replies

    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.

    mizeAuthor
    Explorer 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.DAnswer
    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.

    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.