STM32F446RE custom board USB Full Speed

So I’ve been troubling about this for the past few weeks and still wasn’t able to figure out what is happening with my stm32f446re custom board.

I’m new to ARM and MBed, and a few weeks ago I got my hands on a custom STM32F446RE board which I require to modify its firmware to allow for some features for my system (its a HV Voltage source controller). Flashing is done via a ST-Link connection to a NUCLEO_F401RE board that has a USB to ST-Link thing?

The firmware that came with the board was compiled with mbed2 which is deprecated so I decided to upgrade to mbed os 6 (baremetal, although the “normal” profile also works on this board).
I can flash the custom board with no errors.

Here comes the tricky part:
The board has a USB FS connector (which seems to be all properly connected according to page 194 of the manual).

  • When compiled with mbed2, the USBSerial virtual com works, BUT ONLY ONCE (always after a fresh flash, if USB gets disconnected or MCU reboot/power off, flash is required again for it to work! The computer can’t even detect the device afterwards).
  • When compiled with mbed os 6 the USBSerial just hangs (waiting for a connection on the other endpoint) and nothing happens, i.e. the computer does not detect the device (like if it were a second try with the mbed2 compiled firmware).

What I’ve already tried:

  • Checked if the problem where some drivers (like the ST-Link ones, but from what I understood, this has nothing to do with the virtual serial USB)
  • Checked on multiple computers (always the same outcome)

What could be causing this? I’ve been with this problem for a long time now, and I’m really considering just using a serial UART connection to the pc… Even that not being the most desirable for my purpose.

Even this simple echo code fails as I said above.

#include "mbed.h"

USBSerial pc_serial;
//...
int main()
{
    // In the end my program only accesses these functions of the serial
    while(true)
    {
        pc_serial.printf("%c\n\r", pc_serial._getc());
    }
    return 0;
}

Note: Sorry if somethings are not very accurate or well explained, I’m pretty new to this.

Hello César,

Becuase the NUCLEO_F446RE board is not equipped with a USB connector connected to the main chip 's (STM32F446RE) USB peripheral but rather only with a one connected to the ST Link MCU (STM32F103CBT6) the configuration file mbed-os/targets/targets.json doesn’t configure the Mbed system software to use a USB device. That’s why we have to do it either in a custom targets.json or mbed_app.json file.

For example,

mbed_app.json:

{
    "target_overrides":{
        "*": {
            "target.device_has_add": ["USBDEVICE"]
        }
    }
}

This will assure that the correct clock settings are configured for the USB peripheral in the mbed-os/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/system_clock.c file by automatically defining a DEVICE_USBDEVICE macro (check how this macro is used in the system_clock.c file).

To avoid additional troubles, for example with the pc_serial._getc(), it’s a good practice to use a test program that is as simple as possible. So I’d suggest to first try something as follows:

#include "mbed.h"
#include "USBSerial.h"

int main()
{
   USBSerial   usbSerial(false, 0x1f00, 0x2012, 0x0001);

    printf("Starting...\r\n");

    while (1) {
        printf("blink\r\n");
        usbSerial.printf("blink\r\n");
        ThisThread::sleep_for(500ms);
    }
}