2021-11-01 06:55 AM
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?
2021-11-01 09:38 AM
> i do not get interrupt from DMA event
Read out and check/post content of ADC and relevant DMA registers content.
JW