cancel
Showing results for 
Search instead for 
Did you mean: 

Maintaining ADC operation while dynamically clock switching on STM32L4

almost_linear
Associate II

Hi all,

I am wondering whether it is possible to maintaining ADC(+DMA1 on AHB1) operation while clock switching on STM32L4. I am clocking the STM32L4 via HSE+PLL and the ADC from the PLLSAI1 (set to 40MHz).

Is it remotely possible to switch from HSE+PLL to HSE only (without disabling the PLL) and continue to use the PLLSAI1 for the ADC?

I did some benchwork testing with an oscilloscope on the Clock out (MCO pin) and the switch from HSE+PLL (80MHz) to HSE (16MHz) only takes about two cycles (2 x 62.5ns/16MHz).

I realize the Flash latency setting has to be changed as well when clock switching so dramatically.

System: nucleo-64 dev board, STM32l433, Win10, Atollic IDE, jlink ARM pro

Thanks and regards

Alex

5 REPLIES 5

IMO, if the ADC has an independent clock, you can switch the system clock freely (unless you then miss picking the ADC result in time).

Technically, you can keep running at lower system clock with high FLASH latency setting, it' just that it's inefficient... 🙂

JW

Kraal
Senior III

Hi,

As @Community member​ said, having an ADC clock higher than the core clock (and also the DMA clock) can lead to ADC overrun, if the ADC is free-running and if you do not allow the ADC data register to be overwritten with new result.

I don't know in this case what would happen with the DMA transfer is the ADC data register is updated at the same time...

almost_linear
Associate II

Thanks for your input guys.

I am taking care not to violate the ADC clock & sampling/convert timings.

From a first pass it would seem to work but only if I go:

HSE+PLL(80MHz)-> HSE(16MHz) -> HSE-PLL (16MHz)

Best guess at the moment is that I have an issue with my crystal.

Getting loads of hard, bus, memory and usage faults if i try and switch from HSE+PLL to HSE only.

> Getting loads of hard, bus, memory and usage faults if i try and switch from HSE+PLL to HSE only.

That doesn't make much sense.

Show us code. Better not it be some Cube/HAL gibberish.

JW

almost_linear
Associate II

        /* Switch from HSE+PLL to HSE only */
        LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
 
        /* Wait till System clock is ready */
        while(LL_RCC_HSE_IsReady() != 1){
 
        }
 
        LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
        if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0)
        {
            Error_Handler();
        }
 
        LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
        LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
        LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
 
        sys_clk_freq = RCC_GetSystemClockFreq();
        LL_Init1msTick(sys_clk_freq );
        LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
        LL_SetSystemCoreClock(sys_clk_freq );

Again, I think its more hardware related than software, as I have changed the dev board crystal from 8MHz to a 16MHz one.

Thanks

Alex