cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with USB Mass Storage Device class on STM32F401RBT6

HSumm.1
Associate III

Hi

My board has, among other things, an STM32F401RBT6 and a full-size USB B (device) connector. System clock is an external 25MHz TCXO.

I have verified that the hardware is working correctly, because I have already implemented a compound device class containing USB Audio device and Communications Device class and that all works perfectly.

When I try to flash a project containing a very simple MSC Device class with a 16K RAM Disk, nothing happens. Specifically I followed this ST Video tutorial: https://www.youtube.com/watch?v=GjQqZd1keBo which is very clear and he literally only writes/changes 5 lines of code. Yet when I plug in the USB cable to the PC I see nothing at all on the PC. I have tried on Linux, nothing shows up, even on an lsusb command typed in a terminal. I have tried on the only Windows machine I have, which is a WinXP Laptop. Again, nothing...

The video tutorial is written for a STM32F446 on a Nucleo board; the only changes I made compared to the video were:

1) Reduce the RAM disk size from 64K to 16K because my F401 processor has less memory than the F446

2) Different clock configuration as my processor is max 84MHz and my external clock TCXO is 25MHz. However the USB peripheral is correctly configured at 48MHz and processor clock at 84MHz etc so I do not believe there are any issues here.

I used "min heap size" 0x2000 and "min stack size" 0x400 as in the video.

Any help would be very much appreciated, I have googled and YouTubed for days and got nowhere, and all my hair is almost torn out...

Thanks in advance

Hans Summers

26 REPLIES 26

> Core Reset bit of the GRSTCTL register is set by this function to cause a USB core reset, but the reset is not considered to have executed successfully.

Sounds like some clock missing.

Read out and check/compare to the working case the relevant RCC registers content.

JW

Hi JW

The clock setup is indeed different between the working case and the non-working case. The situation in the working case is greatly complicated because I required a specific 512fs clock for 48ksps I2S which means 24.576MHz; a consequence is that the USB clock is not precisely 48MHz and neither is the CPU clock precisely 84MHz (it is 72.something). The USB clock is however, close enough to 48MHz to work fine. This is on the WORKING case which is quite a complex implementation, compound USB with Audio and CDC classes.

What I was trying, to start with, with the current "problem" case is just the very simple example shown in the ST training video https://www.youtube.com/watch?v=GjQqZd1keBo - the project setup is all generated by Cube MX and the clock configuration is correct and exact (48MHz USB clock, 84MHz CPU, etc). The demo is very simple, there are only 3 lines of code (and 1 amended line). It's hard to imagine how anything could go wrong but...

Next steps:

1) My current installation dates from February this year. I note that ST have a one sub-version higher version of CubeMX and a version increment of the libraries too. So I have downloaded those and will try again to see if it is a bug somewhere in CubeMX and/or the Libraries and see if that was solved by the newer version.

2) I will try setting up the peculiar clock scheme I have in my other, working project (note, both are on the exact same hardware, my own PCB design not an ST board).

Thanks, Hans

> The clock setup is indeed different between the working case and the non-working case.

Okay but it's still simple to check whether the differences correspond only to the different source crystal, isn't it?

Specifically, you should check whether PLL produces 48MHz at PLLQ, and whether the OTG_FS is enabled in its respective AxBENR. I'm not using specifically the 'F401 so maybe there's something else to be enabled/switched on, too, but the comparison with the working example should quickly reveal that.

> What I was trying, to start with, with the current "problem" case is just the very simple example

I know. Many people here say that. Expecting miracles is not the best strategy, even if miracles sometimes do happen (telling somebody about an already known defficiency somebody else has already painfully discovered, may seem like miracle, for example). USB is never simple. That clicking sometimes leads to working specimens is nice; but if it does not, you have to debug it exactly as you debug your own code (with the drawback that you have to develop understanding of somebody else's code in the process).

JW

TDK
Guru

I don't see how you can have USB working with a clock other than 48 MHz. That doesn't seem right.

If you feel a post has answered your question, please click "Accept as Solution".
HSumm.1
Associate III

Hi TDK, JW

The USB clock in my other (working) project with compound device class containing Audio and CDC, is 48.04 MHz which is within specification. The reason for that is that I need a 24.576 MHz clock (as close as possible) for 512 fs I2S audio CODEC sampling at 48 ksps. So I had to roll with a weird clock scheme what produces 48.04 MHz for the USB, 72.06 MHz for the CPU (HCLK) and 24.580 for the audio I2S master clock. Anyway that project WORKS...

This one is supposed to be simple... but as JW says, that's expecting miracles and doesn't always work out that way. The beauty of using CubeMX and Libraries is that it gets you started quickly. The ugliness is when things don't work due to bugs etc then you end up in deep debug mode...

FYI I tried again from scratch after upgrading CubeMX to the latest version 5.6.1, and upgrading STM32Cube for F4 to the latest 1.25.0 - all with the same result (fail).

The hunt continues - but thanks to you guys I feel I'm getting closer to the prey...

Hans

> 48.04 MHz which is within specification

USB2.0 requires the clock to be within 2500ppm i.e. 0.25% of specification; 48.04MHz deviates from 48MHz by 0.0832% - 832ppm, even adding conservative 100ppm for crystal error results in the clock being within limit

But you could have achieved a similar setup while running system clock higher, almost at 84MHz, using PLLM=24 => VCOIN=24.576MHz/24=1.024MHz; PLLN=328 => VCOOUT = 335.872MHz; PLLP=4 (0b01) => SYSCLK = 83.968MHz, PLLQ=7 => Q = 47, 982MHz which deviates -0.0381% or 381ppm.

A spredsheet to calculate these, here. Enjoy! =)

JW

Hi JW

Thanks - when I have the rest of it working, I will check on that too!

Hans

HSumm.1
Associate III

Hi all

Just an update of the situation so far...

In summary - I can swap the firmware in the device (based on STM32F401RBT6) back and forth between my main project and this demo-project which I had hoped to evolve into a USB bootloader with the Mass Storage Device class. The main project implements compound USB device class containing an Audio device (stereo duplex 48ksps 24-bit) and a CDC serial communications port - and it works FINE. The bootloader project with MSC doesn't work - on the same hardware, with the same cables plugged in, nothing changed. Failure is in the USB_CoreReset function, where the processor never clears the reset bit that would indicate a successful reset of the USB peripheral.

As per one of the suggestions, I changed the clock scheme to that of my main project, and still no joy.

I also upgraded to the latest STCubeMX and F4cube (I was one minor version behind) and that made no difference either.

I'm now assuming that there may be a library bug somewhere but have not been able to locate it. I did a Meld diff (Linux code differencing tool) on my working main project and on this demo MSC project. There were many differences since the original main project was written on a somewhat older version of Cube with slightly earlier HAL libraries and ST have made a *lot* of changes; however I could not find any differences which I think would be important. I did try changing a few things but still got no improvement on the issue; still the same timeout failure in USB_CoreReset.

Now... I seem to have reached a dead end on this - so, since I have apparently needed to accumulate more low level USB knowledge than I ever thought I would need to have :\ I will try a different approach. I'm going to take a copy of my working main project and modify that. I believe I should be able to leave the low level stuff in place and modify just the top layers, removing my compound device, audio and CDC devices, and replacing that with Mass Storage Class. If that works then I can piece by piece strip out the other parts of the application to shrink it, and then customize it to be my bootloader.

Hans

Update...

I ripped out of my application project, the Compound Device Class with Audio and CDC sub-classes, and instead put in the MSC from the CubeMX example. I had to make a few adjustments for some changes which occurred since my application project was created. Result: it worked, right away. My STM32F401RBT6 is now recognized as a 16KB Flash disk. Works on both Windows and Linux. Windows won't format it in FAT16 and neither will Linux (which says it needs 1MByte minimum) but this was not unexpected and is not going to be an issue in my application. I can now proceed with the next steps in the bootloader development!

It would be nice to know what caused the supposedly simple CubeMX-generated MSC example to fail - presumably some kind of library issue - but I don't have time or inclination to dig into it any further. My project is onblocked and now I can continue, that's all that matters 🙂

Many thanks for the support an encouragement!

Hans

Hi Hans,

I have a very similar problem as yours (nothing shows up after the board is connected to PC) and struggled for a few weeks.

Could you show me where should I modify?

Thanks

Simon