[Neowbit / STM32F401RET6] changing board clocks while keeping the USB alive

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

[Neowbit / STM32F401RET6] changing board clocks while keeping the USB alive

Post by shazz » Tue Apr 30, 2019 11:18 pm

Hi,

When I try to change the CPU freq (or any AHB/APB1/APB2 freqs) within to the spec limiits (84,84,,42,84), the USB connection fails whatever the value. As in the docs, I added:

Code: Select all

import pyb
pyb.freq(64000000)
in the boot.py, same result, the USB connection disappears.

Any idea ?

Default:

Code: Select all

sysclk: frequency of the CPU				: 56000000 
hclk: frequency of the AHB bus, core memory and DMA	: 56000000
pclk1: frequency of the APB1 bus			: 14000000
pclk2: frequency of the APB2 bus			: 28000000
Last edited by shazz on Wed May 01, 2019 12:03 pm, edited 1 time in total.
8bits should be enough...

User avatar
dhylands
Posts: 3268
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: [Neowbit / STM32F401RET6] changing board clocks

Post by dhylands » Wed May 01, 2019 12:04 am

USB requires a 48 MHz clock.

I suspect that the VCO is being set to a frequency that isn't an integer multiple of 48 and this causes the USB to drop.

One setup of PLL paramaters for the F4 with 8MHz HSE and 84 MHz CPU is:
#define MICROPY_HW_CLK_PLLM (8)
#define MICROPY_HW_CLK_PLLN (336)
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4)
#define MICROPY_HW_CLK_PLLQ (7)

VCO = HSE * PLLN/PLLM = 8 * 336 / 8 = 336 (which is between the limits of 100 and 432)
USB = VCO / PLLQ = 336 / 7 = 48.
CPU = VCO / PLLP = 336 / 5 = 84.

PLLP can only be 2, 4, 6, or 8.

Not all CPU frequencies can support a USB clock of 48 MHz.

Valid VCO frequencies (that support USB) would be 144, 192, 240, 288, 336, 384, 432
And the CPU frequencies will be one of those frequencies divided by 2, 4, 6, or 8.

Doing the math, these CPU frequencies: 18, 24, 30, 32, 36, 40, 42, 48, 54, 56, 60, 64, 72, and 84 should all work (using an 8MHz HSE) and have a way to get a 48 MHz USB clock. Choosing one of these CPU frequencies also requires a corresponding VCO that gives a USB frequency of 48 MHz.

Looking at the code, it looks like it tries to pick combinations that preserve the USB at 48 MHz, but obviously that will still only work for select frequencies.

That's the theory anyways.

When you switch frequencies, if there is a USB transaction happening, then it will most certainly fail (since the USB frequency will wind up momentarily not be 48 MHz while changing the frequency), and that may cause the USB connection to fail (perhaps drop) (I'm hypothesizing here since I haven't actually played with changing CPU frequencies on the fly).

User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

Re: [Neowbit / STM32F401RET6] changing board clocks

Post by shazz » Wed May 01, 2019 1:11 am

Thanks, interesting, I understand now the valid CPU frequencies.
I tried using those ones same result.
I tried also to "remount" the USB connection after changing the CPU freq in the boot.py:

Code: Select all

# boot.0
import pyb
pyb.freq(64000000)
pyb.delay(1000)
pyb.usb_mode('CDC+MSC')
pyb.sync()
But not better, the USB connection doesn't come back.
How do you do usually ? in the bootloader itself ?
8bits should be enough...

User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

Re: [Neowbit / STM32F401RET6] changing board clocks

Post by shazz » Wed May 01, 2019 12:02 pm

So I did not solve the USB issue but what I'm doing, I'm setting the clock at the beginning of the program and when I reset the board the USB+Serial comes back (so I guess the reset also resets the clocks)
Not perfect especially for debugging but at least the clock are well set.
8bits should be enough...

User avatar
dhylands
Posts: 3268
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: [Neowbit / STM32F401RET6] changing board clocks

Post by dhylands » Wed May 01, 2019 4:20 pm

I don't have any 401 boards with USB on them, but I figured I'd try to change the CPU frequency anyways, and this is what I got on my NUCLEO_F401RE:

Code: Select all

MicroPython v1.10-278-g673e154df on 2019-04-12; NUCLEO-F401RE with STM32F401xE
Type "help()" for more information.
>>> pyb.freq(64000000)

FATAL ERROR:
can't change freq
So that might be what's happening on your board too. The only way to know for sure would be to hook a serial port and dup the REPL on the serial port.

Post Reply