Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The USB set address request failed in debug build #80

Closed
vklachkov opened this issue Jan 1, 2022 · 25 comments
Closed

The USB set address request failed in debug build #80

vklachkov opened this issue Jan 1, 2022 · 25 comments

Comments

@vklachkov
Copy link

Hi!

I used your library in my project for STM32F411CEU and noticed that sometimes Windows shows error 43 in Device Manager. If reconnect device, then everything works as it should

To reproduce the issue, I plugged and popped the device several times. Sometimes it also occurred if leave the stm32 connected via USB and flash using st-link

image

@vklachkov
Copy link
Author

My code is based on example...

static mut EP_MEMORY: [u32; 1024] = [0; 1024];

#[entry]
fn main() -> ! {
    rtt_init_print!();
    rprintln!("Hello!");

    let dp = pac::Peripherals::take().unwrap();

    let rcc = dp.RCC.constrain();

    let clocks = rcc
        .cfgr
        .use_hse(25.mhz())
        .sysclk(48.mhz())
        .require_pll48clk()
        .freeze();

    let gpioa = dp.GPIOA.split();
    let usb = USB {
        usb_global: dp.OTG_FS_GLOBAL,
        usb_device: dp.OTG_FS_DEVICE,
        usb_pwrclk: dp.OTG_FS_PWRCLK,
        pin_dm: gpioa.pa11.into_alternate(),
        pin_dp: gpioa.pa12.into_alternate(),
        hclk: clocks.hclk(),
    };

    let mut usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });

    let mut serial = SerialPort::new(&usb_bus);

    let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
        .product("Serial port")
        .device_class(USB_CLASS_CDC)
        .build();

    loop {
        if !usb_dev.poll(&mut [&mut serial]) {
            continue;
        }

        let mut buf = [0u8; 64];

        match serial.read(&mut buf[..]) {
            Ok(count) => {}
            Err(UsbError::WouldBlock) => {}
            Err(err) => {}
        };

        match serial.write(&[0x3a, 0x29]) {
            Ok(count) => {}
            Err(UsbError::WouldBlock) => {}
            Err(err) => {}
        };
    }
}

@vklachkov
Copy link
Author

Experimenting, I noticed that with an increase in frequency to 100mhz, the problem is no longer reproduced. And if you lower it to 25, then there is almost always an error when connecting.

@vklachkov
Copy link
Author

I get dump from the usb using Wireshark. This dump contains errors and successful connection. STM32 freq is 25mhz
rust-usb-cdc-bug.zip

@mvirkkunen
Copy link
Collaborator

By increasing the frequency, did you mean the sysclk frequency? Which hardware are you using? Have you tried running it in release mode just in case (although in this case it really shouldn't matter)?

The dump didn't seem to contain anything enumeration related, just a bunch of interrupt requests from another USB devide. At any rate this is very unlikely to be related to usbd-serial if the device doesn't even manage to enumerate, it's either got something to do with usb-device or synopsys-usb-otg.

@vklachkov
Copy link
Author

vklachkov commented Jan 1, 2022

@mvirkkunen

Yes, I mean sysclk. My chip is STM32F411CEU6. And yes, I always run in release No, in debug, I was wrong

Sorry, initially I took the dump incorrectly using wireshark. Recently updated the archive, there is a more correct dump. Although, nothing concrete and useful... I will try to write to the usb repository. If you don't have the error, then I'm sorry for the trouble

@mvirkkunen
Copy link
Collaborator

I was wondering about the entire hardware, is it custom or pre-existing board? Could it possibly have a power-on delay that causes an intermittent fault?

I can see the update dump now and it doesn't contain errors, it's possible that your recording setup doesn't see that type of low-level error.

usb-device is my repository as well so I'll just move this issue.

@mvirkkunen mvirkkunen transferred this issue from rust-embedded-community/usbd-serial Jan 1, 2022
@vklachkov
Copy link
Author

I am using a Chinese black pill. And everything works fine on firmware, written using C and CubeMX

image

@vklachkov
Copy link
Author

Hypothetically, i can try to get the dump using a cheap logic analyzer, but I'm not sure that it will be able to work correctly with usb 2.0

@vklachkov
Copy link
Author

I can't figure out what is what and whether my logical analyzer managed to capture data from usb

RUST USB CDC BUG.zip

@mvirkkunen
Copy link
Collaborator

mvirkkunen commented Jan 2, 2022

This logic analyzer dump is nice, looks like your logic analyzer works just fine. It looks like the device is responding with a STALL to the SET_ADDRESS request after some time for some reason.

Can you paste your list of dependencies from Cargo.toml with the versions numbers?

@vklachkov
Copy link
Author

vklachkov commented Jan 2, 2022

Can you paste your list of dependencies from Cargo.toml with the versions numbers?

My Cargo.toml:

[package]
name = "motor"
version = "3.0.0"
edition = "2021"

[dependencies]
nb = "1"
cortex-m = "*"
cortex-m-rt = "*"
embedded-hal = "0.2"
usb-device = "0.2.8"
usbd-serial = "0.1.1"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
arraydeque = { version = "0.4", default-features = false }

[dependencies.stm32f4xx-hal]
version = "0.10"
features = ["stm32f411", "rt", "usb_fs"]

@vklachkov
Copy link
Author

@mvirkkunen

I'm sorry, I made a mistake. Before that, I started the project in debug mode using the cargo-embed --chip stm32f411ceu command. After I started launching the project via cargo-embed --chip stm32f411ceu --release, the problem went away even at low frequencies. But this is still wrong behavior, I think

@vklachkov vklachkov changed the title The USB set address request failed. The USB set address request failed in debug build Jan 2, 2022
@mvirkkunen
Copy link
Collaborator

mvirkkunen commented Jan 2, 2022

Yes, it's odd. Even though debug mode Rust is slow, you're not doing anything else, and it shouldn't be that slow. Also, the dump shows a STALL condition, not a timeout from what I could tell from a quick look. I'll have to take a look at this more when I have time, I have some of the exact same board too.

@vklachkov
Copy link
Author

vklachkov commented Jan 2, 2022

If this problem is solved one day, I will be glad. Thank you for communicating! For now, I will work in the release and use your rtt library for debugging

My friend sent me such a link when I described my problem to him: https://community.st.com/s/question/0D50X0000B8jzZL/why-does-the-stm32f407-send-a-stall-on-usbfs

@mvirkkunen
Copy link
Collaborator

Yeah there are some weird race conditions in debug mode still it seems. What comes to debugging, stopping the device or even using semihosting is just a plain non-starter because USB has somewhat strict timeouts. I pretty much made the first version of the RTT library specifically for debugging USB, because semihosting was too slow and I didn't want to use an extra serial port.

I can't see what's behind the link, because I don't know what Discord server it is and I don't think it allows you to see messages unless I join the server.

@vklachkov
Copy link
Author

vklachkov commented Jan 2, 2022

Yeah there are some weird race conditions in debug mode still it seems. What comes to debugging, stopping the device or even using semihosting is just a plain non-starter because USB has somewhat strict timeouts. I pretty much made the first version of the RTT library specifically for debugging USB, because semihosting was too slow and I didn't want to use an extra serial port.

I can't see what's behind the link, because I don't know what Discord server it is and I don't think it allows you to see messages unless I join the server.

Excuse me. Corrected the link. It's time for me to sleep)

@mvirkkunen
Copy link
Collaborator

The Synopsys OTG IP is very fragile and easily breaks down in surprising ways when it's not handled exactly as the IP authors intended, even if you'd think your actions are reasonable.

mmm, sounds very nice indeed

@vklachkov
Copy link
Author

mmm, sounds very nice indeed

Another surprise from stm32) It's amazing why nobody didn't encounter this problem besides me

@Disasm
Copy link
Member

Disasm commented Jan 2, 2022

It's quite an old problem, there is even a warning which (unfortunately) doesn't work unless you build the firmware from a workspace which includes synopsys-usb-otg: https://github.com/stm32-rs/synopsys-usb-otg/blob/master/build.rs#L5-L7

@mvirkkunen
Copy link
Collaborator

It's possible people have just assumed it was because debug mode is slow and can break in weird ways, and never looked at it with a logic analyzer to see the surprise STALL status. This report might be a better fit for the Synopsys driver repo, unfortunately you can't move an issue to another org.

@vklachkov
Copy link
Author

It's possible people have just assumed it was because debug mode is slow and can break in weird ways, and never looked at it with a logic analyzer to see the surprise STALL status. This report might be a better fit for the Synopsys driver repo, unfortunately you can't move an issue to another org.

I can write anywhere, summarizing everything written, if it helps a little in solving the problem.

@vklachkov
Copy link
Author

Should I drop it here? https://github.com/stm32-rs/synopsys-usb-otg
Or where it will be more convenient

@Disasm
Copy link
Member

Disasm commented Jan 2, 2022

Yes, this is the right place.

@vklachkov
Copy link
Author

Close issue here...

@vklachkov
Copy link
Author

vklachkov commented Jan 2, 2022

And open here stm32-rs/synopsys-usb-otg#21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants