cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L431 ADC initialization problem

KGrib.1
Associate

Hi. I have a problem with ADC on a custom board with STM32L431CBY with external 24 MHz clock.

Everything (UART, SPI, DAC e.t.c.) works fine except ADC. Clock initialization:

static void setSystemClock(void)
{
    LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
    while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_4);
    LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
 
    LL_RCC_HSE_Enable();
    while(LL_RCC_HSE_IsReady() != 1);   // Wait till HSE is ready
    LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_6, 40, LL_RCC_PLLR_DIV_2);
    LL_RCC_PLL_EnableDomain_SYS();
    LL_RCC_PLL_Enable();
    while(LL_RCC_PLL_IsReady() != 1);
 
    LL_RCC_PLLSAI1_ConfigDomain_ADC(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_6, 40, LL_RCC_PLLSAI1R_DIV_2);
    LL_RCC_PLLSAI1_EnableDomain_ADC();
    LL_RCC_PLLSAI1_Enable();
    while(LL_RCC_PLLSAI1_IsReady() != 1);
 
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
    while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL);
 
    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
 
    LL_Init1msTick(80000000);
    LL_SetSystemCoreClock(80000000);
 
    LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2);
    LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_PCLK1);
}
    // Enabling clocks and setting ADC clock source
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
 
    LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
    //LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_SYSCLK);
 
    // DMA interrupt configuration
    NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
    LL_DMA_InitStruct.PeriphOrM2MSrcAddress = LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA);
    LL_DMA_InitStruct.MemoryOrM2MDstAddress = (uint32_t)bufAdcData;
    LL_DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
    LL_DMA_InitStruct.Mode = LL_DMA_MODE_NORMAL;
    LL_DMA_InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
    LL_DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
    LL_DMA_InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD;
    LL_DMA_InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;
    LL_DMA_InitStruct.NbData = ADC_BUFF_SZ;
    LL_DMA_InitStruct.PeriphRequest = LL_DMA_REQUEST_0;
    LL_DMA_InitStruct.Priority = LL_DMA_PRIORITY_LOW;
 
    if(LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &LL_DMA_InitStruct)) {
        setTerminalMessage(info, "Error DMA initialization");
    }
 
    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
 
    // ADC channel 15 pins setup
    LL_GPIO_StructInit(&LL_GPIO_InitStruct);
    LL_GPIO_InitStruct.Pin = LL_GPIO_PIN_1 | LL_GPIO_PIN_0;
    LL_GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
    LL_GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOB, &LL_GPIO_InitStruct);
 
    // ADC channel 11 pins setup -- 
    LL_GPIO_StructInit(&LL_GPIO_InitStruct);
    LL_GPIO_InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
    LL_GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
    LL_GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOA, &LL_GPIO_InitStruct);
 
    // ADC setup
    // Main init
    LL_ADC_StructInit(&LL_ADC_InitStruct);
    LL_ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
    LL_ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
    LL_ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
    LL_ADC_Init(ADC1, &LL_ADC_InitStruct);
 
    // Reg init
    LL_ADC_REG_StructInit(&LL_ADC_REG_InitStruct);
    LL_ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
    LL_ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
    LL_ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
    LL_ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
    LL_ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED; //LL_ADC_REG_DMA_TRANSFER_LIMITED; // Circular - LL_ADC_REG_DMA_TRANSFER_UNLIMITED
    LL_ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
    LL_ADC_REG_Init(ADC1, &LL_ADC_REG_InitStruct);
 
    // Common struct
    LL_ADC_CommonStructInit(&LL_ADC_CommonInitStruct);
    LL_ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV1;
    // LL_ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV4;
    LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &LL_ADC_CommonInitStruct);
    LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE);
 
    // ADC disable power down
    LL_ADC_DisableDeepPowerDown(ADC1);
    LL_ADC_EnableInternalRegulator(ADC1);
 
    // waiting for regulator sync.
    uint32_t wait_loop_index;
    wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
    while(wait_loop_index != 0) {
        __ASM volatile ("nop");
        wait_loop_index--;
    }
 
    // Calibration
    LL_ADC_StartCalibration(ADC1, LL_ADC_DIFFERENTIAL_ENDED);
    while(LL_ADC_IsCalibrationOnGoing(ADC1));
 
 
    LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);
    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_15);
    LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_2CYCLES_5);
    LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_DIFFERENTIAL_ENDED);
 
    readyAdcDataFl = false;
    errorAdcDataFl = false;
    irqAdcDataFl = false;
 
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
    LL_ADC_Enable(ADC1);
    LL_ADC_REG_StartConversion(ADC1);
 
    setTerminalMessage(info, "DMA waiting");
    while(false == readyAdcDataFl);
    setTerminalMessage(info, "DMA event done");

void DMA1_Channel1_IRQHandler(void)
{
    if(LL_DMA_IsActiveFlag_TC1(DMA1) == 1) {
        LL_DMA_ClearFlag_TC1(DMA1);
        stopADC();
        readyAdcDataFl = true;
 
    }
    if(LL_DMA_IsActiveFlag_TE1(DMA1) == 1) {
        LL_DMA_ClearFlag_TE1(DMA1);
        errorAdcDataFl = true;
    }
}
 

And i do not get interrupt from DMA event. Can anybody give me advice?

1 REPLY 1

> i do not get interrupt from DMA event

Read out and check/post content of ADC and relevant DMA registers content.

JW