embassy icon indicating copy to clipboard operation
embassy copied to clipboard

USB on STM32F401/Blackpill

Open fry opened this issue 1 year ago • 3 comments

Hi. I am in the process of debugging why USB (in particular the stm32f4 usb_serial example) won't connect on both Windows and Linux. I am using the STM32F401CC based Blackpill board.

Fundamentally, older versions of embassy (at the very least before the F4/F7 clock configuration changes) worked fine. The main changes since then that I could make out are generalisation of the clock configuration, and I am relatively confident I configured the clock correctly (scalars from STM32CubeMX and the internet) to get the required 48Mhz:

    {
        use embassy_stm32::rcc::*;
        config.rcc.hse = Some(Hse {
            freq: Hertz(25_000_000),
            mode: HseMode::Oscillator,
        });
        config.rcc.pll_src = PllSource::HSE;
        config.rcc.pll = Some(Pll {
            prediv: PllPreDiv::DIV25,
            mul: PllMul::MUL336,
            divp: Some(PllPDiv::DIV4), // 25mhz / 25 * 336 / 4 = 84Mhz.
            divq: Some(PllQDiv::DIV7), // 25mhz / 25 * 336 / 7 = 48Mhz.
            divr: None,
        });
        config.rcc.ahb_pre = AHBPrescaler::DIV1;
        config.rcc.apb1_pre = APBPrescaler::DIV2;
        config.rcc.apb2_pre = APBPrescaler::DIV1;
        config.rcc.sys = Sysclk::PLL1_P;
    }

Cargo.toml and .cargo/config.toml chip are updated to stm32f401cc.

Here is the log output, after which nothing further happens (even when replugging the USB power):

0.000000 INFO  Hello World!
└─ usb_serial::____embassy_main_task::{async_fn#0} @ src\bin\usb_serial.rs:21
0.000000 TRACE BDCR ok: 00008200
└─ embassy_stm32::rcc::bd::{impl#2}::init @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.000000 DEBUG flash: latency=2
└─ embassy_stm32::rcc::_version::init @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:130
0.000000 DEBUG rcc: Clocks { sys: Hertz(84000000), pclk1: Hertz(42000000), pclk1_tim: Hertz(84000000), pclk2: Hertz(84000000), pclk2_tim: Hertz(84000000), hclk1: Hertz(84000000), hclk2: Hertz(84000000), hclk3: Hertz(84000000), plli2s1_q: None, plli2s1_r: None, pll1_q: Some(Hertz(48000000)), rtc: Some(Hertz(32000)) }
└─ embassy_stm32::rcc::set_freqs @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:130
0.000183 TRACE allocating type=Interrupt mps=8 interval_ms=255, dir=In
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.000518 TRACE   index=1
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.000701 TRACE allocating type=Bulk mps=64 interval_ms=0, dir=Out
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.001037 TRACE   index=1
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.001190 TRACE allocating type=Bulk mps=64 interval_ms=0, dir=In
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.001556 TRACE   index=2
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.001739 INFO  USB: device_descriptor used: 18
└─ embassy_usb::builder::{impl#1}::build @ D:\projects\embedded\embassy\embassy-usb\src\fmt.rs:143
0.001892 INFO  USB: config_descriptor used: 70
└─ embassy_usb::builder::{impl#1}::build @ D:\projects\embedded\embassy\embassy-usb\src\fmt.rs:143
0.002044 INFO  USB: bos_descriptor used: 12
└─ embassy_usb::builder::{impl#1}::build @ D:\projects\embedded\embassy\embassy-usb\src\fmt.rs:143
0.002227 INFO  USB: msos_descriptor used: 0
└─ embassy_usb::builder::{impl#1}::build @ D:\projects\embedded\embassy\embassy-usb\src\fmt.rs:143
0.002380 INFO  USB: control_buf size: 64
└─ embassy_usb::builder::{impl#1}::build @ D:\projects\embedded\embassy\embassy-usb\src\fmt.rs:143
0.002532 TRACE allocating type=Control mps=64 interval_ms=0, dir=Out
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.002868 TRACE   index=0
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.003021 TRACE allocating type=Control mps=64 interval_ms=0, dir=In
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.003326 TRACE   index=0
└─ embassy_stm32::usb_otg::usb::{impl#6}::alloc_endpoint @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.003479 TRACE start
└─ embassy_stm32::usb_otg::usb::{impl#7}::start @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.003692 TRACE Core id 00001200
└─ embassy_stm32::usb_otg::usb::{impl#9}::init @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.003906 TRACE SETUP waiting
└─ embassy_stm32::usb_otg::usb::{impl#18}::setup::{async_fn#0}::{closure#0} @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.004516 TRACE irq
└─ embassy_stm32::usb_otg::usb::{impl#0}::on_interrupt @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.004669 TRACE reset
└─ embassy_stm32::usb_otg::usb::{impl#10}::poll::{async_fn#0}::{closure#0} @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.004791 TRACE init_fifo
└─ embassy_stm32::usb_otg::usb::{impl#9}::init_fifo @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.004913 TRACE configuring rx fifo size=62
└─ embassy_stm32::usb_otg::usb::{impl#9}::init_fifo @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.005065 TRACE configuring tx fifo ep=0, offset=62, size=16
└─ embassy_stm32::usb_otg::usb::{impl#9}::init_fifo @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.005310 TRACE configuring tx fifo ep=1, offset=78, size=16
└─ embassy_stm32::usb_otg::usb::{impl#9}::init_fifo @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.005554 TRACE configuring tx fifo ep=2, offset=94, size=16
└─ embassy_stm32::usb_otg::usb::{impl#9}::init_fifo @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.005798 TRACE configure_endpoints
└─ embassy_stm32::usb_otg::usb::{impl#9}::configure_endpoints @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
0.006042 TRACE SETUP waiting
└─ embassy_stm32::usb_otg::usb::{impl#18}::setup::{async_fn#0}::{closure#0} @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117

In debugging this, I could use some help from someone familiar with the changes that happened to the USB driver in the past months. Similarly, what events are expected to happen with a successful connection? I would at least expect the interrupt to be fired more than once.

Any pointers into the right direction is appreciated, thank you!

fry avatar Jan 24 '24 08:01 fry

make sure to set this to false, the blackpill board doesn't have it wired up.

https://github.com/embassy-rs/embassy/blob/main/examples/stm32f4/src/bin/usb_serial.rs#L48

Dirbaio avatar Jan 24 '24 13:01 Dirbaio

I am also playing with the blackpill, I can confirm that USB detect is not available. So disabling the software detect should work. Only downside of this board are the USB-C cc resistors. It has only one 5k1 for both CC lines with is bad for the detection. So if you using a real host USB-C port it may not detect your device correct. When using a USB-A to USB-C cable that is not a issue because CC lines are not used.

vDorst avatar Jan 25 '24 19:01 vDorst

I ran into the same issue, also with a STM32F401CCU6 Blackpill board. Setting config.vbus_detection = false; (and correcting RCC settings) fixed the issue on my end. Works with both a USB-A to USB-C cable and a USB-C to USB-C cable here.

Juravenator avatar Feb 09 '24 11:02 Juravenator

Apologies for the late response - this was indeed the cause, thank you. I had only uncommented the line previously, not realising the default for that field is false. A very belated big thank you! :). The only problem I have now is that a connection attempt to a serial device from Windows seems to take at least 90 seconds. The only noticeable error line in the log would be

411.019744 TRACE SETUP_DATA_RX
└─ embassy_stm32::usb::_version::{impl#0}::on_interrupt @ D:\projects\embedded\embassy\embassy-stm32\src\fmt.rs:117
411.019775 ERROR received SETUP before previous finished processing

But this is likely not relevant to the board so I'll close the issue and try to debug this. Thank you for your help again!

fry avatar Apr 06 '24 07:04 fry