STM32L496 external oscillator

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

Yruama
Posts: 2
Joined: Wed Jun 05, 2019 11:28 am
Has thanked: 1 time

STM32L496 external oscillator

Postby Yruama » Wed Jun 05, 2019 1:04 pm

Hello everyone,

I have a custom board running with ChibiOS with a simple "Hello world" thread which blinks a led. This program works fine when I use the intern oscillator of the microprocessor, but for some reason I can't make it work with an external clock (which I need for another use of my board).
Indeed, in this case the led doesn't blink anymore, proving that the entire board is stuck.
Here are the relevant parts of my configuration files :
In mcuconf.h :

Code: Select all

#define STM32_NO_INIT                       FALSE
#define STM32_VOS                           STM32_VOS_RANGE1
#define STM32_PVD_ENABLE                    FALSE
#define STM32_PLS                           STM32_PLS_LEV0
#define STM32_HSI16_ENABLED                 TRUE
#define STM32_LSI_ENABLED                   TRUE
#define STM32_HSE_ENABLED                   TRUE
#define STM32_LSE_ENABLED                   FALSE
#define STM32_MSIPLL_ENABLED                FALSE
#define STM32_ADC_CLOCK_ENABLED             TRUE
#define STM32_USB_CLOCK_ENABLED             TRUE
#define STM32_SAI1_CLOCK_ENABLED            TRUE
#define STM32_SAI2_CLOCK_ENABLED            TRUE
#define STM32_MSIRANGE                      STM32_MSIRANGE_4M
#define STM32_MSISRANGE                     STM32_MSISRANGE_4M
#define STM32_SW                            STM32_SW_PLL
#define STM32_PLLSRC                        STM32_PLLSRC_HSE
#define STM32_PLLM_VALUE                    1
#define STM32_PLLN_VALUE                    80
#define STM32_PLLP_VALUE                    7
#define STM32_PLLQ_VALUE                    6
#define STM32_PLLR_VALUE                    4
#define STM32_HPRE                          STM32_HPRE_DIV1
#define STM32_PPRE1                         STM32_PPRE1_DIV1
#define STM32_PPRE2                         STM32_PPRE2_DIV1
#define STM32_STOPWUCK                      STM32_STOPWUCK_MSI
#define STM32_MCOSEL                        STM32_MCOSEL_NOCLOCK
#define STM32_MCOPRE                        STM32_MCOPRE_DIV1
#define STM32_LSCOSEL                       STM32_LSCOSEL_NOCLOCK
#define STM32_PLLSAI1N_VALUE                72
#define STM32_PLLSAI1P_VALUE                7
#define STM32_PLLSAI1Q_VALUE                6
#define STM32_PLLSAI1R_VALUE                6
#define STM32_PLLSAI2N_VALUE                72
#define STM32_PLLSAI2P_VALUE                7
#define STM32_PLLSAI2R_VALUE                6
#define STM32_USART1SEL                     STM32_USART1SEL_SYSCLK
#define STM32_USART2SEL                     STM32_USART2SEL_SYSCLK
#define STM32_USART3SEL                     STM32_USART3SEL_SYSCLK
#define STM32_UART4SEL                      STM32_UART4SEL_SYSCLK
#define STM32_UART5SEL                      STM32_UART5SEL_SYSCLK
#define STM32_LPUART1SEL                    STM32_LPUART1SEL_SYSCLK
#define STM32_I2C1SEL                       STM32_I2C1SEL_SYSCLK
#define STM32_I2C2SEL                       STM32_I2C2SEL_SYSCLK
#define STM32_I2C3SEL                       STM32_I2C3SEL_SYSCLK
#define STM32_LPTIM1SEL                     STM32_LPTIM1SEL_PCLK1
#define STM32_LPTIM2SEL                     STM32_LPTIM2SEL_PCLK1
#define STM32_SAI1SEL                       STM32_SAI1SEL_OFF
#define STM32_SAI2SEL                       STM32_SAI2SEL_OFF
#define STM32_CLK48SEL                      STM32_CLK48SEL_PLLSAI1
#define STM32_ADCSEL                        STM32_ADCSEL_SYSCLK
#define STM32_SWPMI1SEL                     STM32_SWPMI1SEL_PCLK1
#define STM32_DFSDMSEL                      STM32_DFSDMSEL_PCLK2
#define STM32_RTCSEL                        STM32_RTCSEL_LSI


and in board.h :

Code: Select all

#if !defined(STM32_LSECLK)
#define STM32_LSECLK                32768U
#endif

#define STM32_LSEDRV                (3U << 3U)

#if !defined(STM32_HSECLK)
#define STM32_HSECLK                25000000U
#endif

#define STM32_HSE_BYPASS


Does anyone has an idea on how I could make my board work with the external clock ?
I use Chibios stable 18.2 and my platform is STM32L496
Any kind of help would be very much appreciated !
Regards,

Amaury B.

steved
Posts: 608
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 5 times
Been thanked: 77 times

Re: STM32L496 external oscillator

Postby steved » Wed Jun 05, 2019 1:18 pm

You need to adjust some values to give the right clocks:

Code: Select all

#define STM32_PLLM_VALUE                    1
#define STM32_PLLN_VALUE                    80
#define STM32_PLLP_VALUE                    7
#define STM32_PLLQ_VALUE                    6
#define STM32_PLLR_VALUE                    4

Have a look at the clock tree in the relevant manual.

From memory, CPU clock is:
((LSE/STM32_PLLM_VALUE)*STM32_PLLN_VALUE)/STM32_PLLP_VALUE

Your numbers are trying to operate the PLL at about 2GHz, which is unlikely to work.
Try these:

Code: Select all

      #define STM32_PLLM_VALUE                    25                   /* 1MHz into PLL */
      #define STM32_PLLN_VALUE                    336                 /* 336MHz out of PLL */
      #define STM32_PLLP_VALUE                    2                   /* 168MHz PLLCLK */
      #define STM32_PLLQ_VALUE                    7                   /* 48MHz clock */

Yruama
Posts: 2
Joined: Wed Jun 05, 2019 11:28 am
Has thanked: 1 time

Re: STM32L496 external oscillator

Postby Yruama » Wed Jun 05, 2019 3:59 pm

Thanks alot for the help, I will look further into that !
I might also have a problem with the quartz itself so it still doesn't work for now, but hopefully it is going to work in the end !
I will keep this post updated if I find a solution.
Amaury B.

rew
Posts: 270
Joined: Sat Jul 19, 2014 12:59 pm
Been thanked: 6 times

Re: STM32L496 external oscillator

Postby rew » Fri Jun 07, 2019 8:10 am

Speaking about clocks. I would personally like it better if chibios provided more help in determining those M/N/P/Q/R values.

I would then specify:
#define MCU_CLOCK 168000000
#define CRYSTAL_FREQ 25000000

and a little program would #include my specifications and spit out the include file that the chibios clock initialization uses. That does mean that you'd need a host-compiler to make that work.

User avatar
Giovanni
Site Admin
Posts: 12106
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 549 times
Been thanked: 471 times
Contact:

Re: STM32L496 external oscillator

Postby Giovanni » Fri Jun 07, 2019 10:06 am

rew wrote:Speaking about clocks. I would personally like it better if chibios provided more help in determining those M/N/P/Q/R values.

I would then specify:
#define MCU_CLOCK 168000000
#define CRYSTAL_FREQ 25000000

and a little program would #include my specifications and spit out the include file that the chibios clock initialization uses. That does mean that you'd need a host-compiler to make that work.


It would have multiple solutions, the right one could depend on other constraints and configurations, it is not so obvious.

Giovanni

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: STM32L496 external oscillator

Postby dflogeras » Fri Jun 07, 2019 11:31 am

Usually when I'm setting up a new project, I use ST Micro's CubeMX tool as an augmentation to the manual. It has a graphical clock tree for each device, and you can immediately see the outcome of changes you make on all the various subsystems. As Giovanni said, it's quite complex (especially the newer devices) and there is no "one solution", more of a balancing act. This tool helps you balance. Its intended purpose is to auto-generate code, which I do not use since ChibiOS suits me much better, but it is a nice cross-check.

As a side note, it's also good when laying out a board as a double-check for playing around with mapping specific peripherals to pins. As a design evolves, you start to notice things like "oh hey, this would be easier if the UART was on the other side of the chip" and safely swap things around and solve any conflicts that arise.

Hope it helps you.
Dave

jsavonet
Posts: 11
Joined: Fri Mar 01, 2019 10:00 am
Location: France, Lyon
Been thanked: 1 time

Re: STM32L496 external oscillator

Postby jsavonet » Fri Jun 07, 2019 4:15 pm

Hi all,

Thank you for your help. We finally found the issue.
Lots of mistake on our side...

First, the quartz was mounted the wrong way on the board.
Once we fixed the hardware part, we were able to measure the HSE and SYSCLK value through the MCO feature in STMCubeMx. PA8 pin can output differents clocks and with a scope it is really easy to validate prescalar and PLL coeffs.

After finding our coeff, we activated the same feature with ChibiOS:

Code: Select all

#define STM32_MCOSEL                        STM32_MCOSEL_SYSCLK
#define STM32_MCOPRE                        STM32_MCOPRE_DIV1

and set the pin in your main:

palSetPadMode( GPIOA, 8, PAL_MODE_ALTERNATE( 0 ) );


Then, It was pretty straightforward:

Set the quartz value in board.h

Code: Select all

/*
 * Board oscillators-related settings.
 */
#if !defined(STM32_LSECLK)
#define STM32_LSECLK                32768U
#endif

#define STM32_LSEDRV                (3U << 3U)

#if !defined(STM32_HSECLK)
#define STM32_HSECLK                25000000U
#endif

//#define STM32_HSE_BYPASS


And set the coeff for the PLL for a 20Mhz clock:

Code: Select all

/*
 * HAL driver system settings.
 */
#define STM32_NO_INIT                       FALSE
#define STM32_VOS                           STM32_VOS_RANGE1
#define STM32_PVD_ENABLE                    FALSE
#define STM32_PLS                           STM32_PLS_LEV0
#define STM32_HSI16_ENABLED                 TRUE
#define STM32_LSI_ENABLED                   TRUE
#define STM32_HSE_ENABLED                   TRUE
#define STM32_LSE_ENABLED                   FALSE
#define STM32_MSIPLL_ENABLED                FALSE
#define STM32_ADC_CLOCK_ENABLED             TRUE
#define STM32_USB_CLOCK_ENABLED             TRUE
#define STM32_SAI1_CLOCK_ENABLED            TRUE
#define STM32_SAI2_CLOCK_ENABLED            TRUE
#define STM32_MSIRANGE                      STM32_MSIRANGE_4M
#define STM32_MSISRANGE                     STM32_MSISRANGE_4M
#define STM32_SW                            STM32_SW_PLL
#define STM32_PLLSRC                        STM32_PLLSRC_HSE
#define STM32_PLLM_VALUE                    5
#define STM32_PLLN_VALUE                    16
#define STM32_PLLP_VALUE                    7
#define STM32_PLLQ_VALUE                    4
#define STM32_PLLR_VALUE                    4
#define STM32_HPRE                          STM32_HPRE_DIV1
#define STM32_PPRE1                         STM32_PPRE1_DIV1
#define STM32_PPRE2                         STM32_PPRE2_DIV1


Hope this can help someone in the futur,
Best,

Jeremy

rew
Posts: 270
Joined: Sat Jul 19, 2014 12:59 pm
Been thanked: 6 times

Re: STM32L496 external oscillator

Postby rew » Mon Jun 17, 2019 8:48 am

Giovanni wrote:It would have multiple solutions, the right one could depend on other constraints and configurations, it is not so obvious.
If you don't see how to automate something, try doing it by hand a few times.

So, external clock: 8 MHz, wanted clock 168 MHz, that's divide by 1, times 21. But wait! there are other solutions: divide by two, multiply by 42. Which one do you prefer? why? So, a program could figure out ALL possible combinations of coefficients that result in the required clock. Some are simply not possible, for example the 2 GHz intermediate clock that we saw above. You can remove those from the list. Then run a couple of heuristics to assign a score to each solution and chose the one with the best score. I would say that "lower numbers are better than bigger numbers". So you assign a score to each solution that promotes lower numbers. But maybe an asymmetry in the source clock could give unwanted effects when the divisor is 1, so maybe give a small penalty for that divisor?

Then you can run the algorithm a on a few examples and when it doesn't chose the solution you would have, analyse why. Did you miss a better solution? Are the heuristics tuned wrong? Do you consider 49.9 with a wanted value of 50 "Good enough", while the algorithm says: "not exact"?


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 5 guests