Arm Mbed OS support forum

STM32F411CE Black Pill USB

I’m pretty new to mbed, and am experimenting with (as the title says) a Black Pill. It’s programming great, LED blinks, etc. but attempting to plumb up a USB device just hangs. Of course if I configure it for no connect on construction, the code continues running, but the device is never recognized by OSX.

Programming via DFU works great. Any experiences here with what I’m missing to talk to the device in my code?

Hello @livenerochi,

Unfortunately, I have no experience with Mac but the example below works fine on Linux (Ubuntu 18.04 LTS) and on Windows 10. Build it for a BLACKPILL custom target which is using the on-board 25 MHz crystal as system clock source rather than the internal 16 MHz RC oscillator.

https://os.mbed.com/users/hudakz/code/Blackpill_USBSerial/

As far as I can remember no manual installation of a Mbed USB driver is required on Mac, Linux and Windows 10. So in case it doesn’t work I’d recommend to try various USB cables.

The link below might be useful too:

https://os.mbed.com/users/hudakz/code/Blackpill_Hello/

Hi @hudakz -
I’m using your custom target mostly, and want to thank you for all the work that you’ve done! It got me to a basic blink test!

I’m also using platformio, and I think that my complications are due to that. I’m getting closer to figuring out how to use a custom target definition properly there, but had kind of patched yours into the framework tree, but with some changes that worked, but I did not fully understand. I believe that I may have ended up with a different clock setup than intended.

I need to do more work here to get my head around the right way to do things. Thanks again for all you’ve done here, though - it’s been super helpful!

@hudakz - I have gotten USB working now. I did restructure my project more in line with how platformio wants a custom target integrated, and that’s a good thing.

The key to making USB work was to enable the CLOCK_SOURCE_USB macro. I misread the comments, perhaps, and thought that was an option not a requirement. Perhaps you can help an mbed/stm32 noob understand better why the clocking needs to change for USB to function?

I had a bit of trouble getting the startup assembly included in the custom target to work with platformio. Unless I am mistaken, though, the toolchain directories don’t seem to differ from TARGET_STM32F411xE. I was able to get past that by deleting TOOLCHAIN* from the custom target directory and adding “extra_labels_add”: [ “STM32F411xE” ] to custom_targets_.json in my project. Any downside to that?

Lots to learn here, but excited I’m past that hurdle for the moment! Thanks again for blazing the trail here …

Hello Liv,

I’m glad you made it work.

why the clocking needs to change for USB to function?

I think it’s because USB requires a very accurate clock to work reliably. An RC (resistor-capacitor) oscillator (like the internal one) is usually not accurate enough for USB. That’s why we better use the external crystal oscillator available on the Blackpill board, which is more precise.

Unless I am mistaken, though, the toolchain directories don’t seem to differ from TARGET_STM32F411xE. I was able to get past that by deleting TOOLCHAIN* from the custom target directory and adding “extra_labels_add”: [ “STM32F411xE” ] to custom_targets_.json in my project. Any downside to that?

You are right, Liv. The toolchain directories don’t differ from the TARGET_STM32F411xE. Buf the cmsis_nvic.h file should because the Blackpill is equipped with 256kB of flash memory as opposed to 512kB of the NUCLEO_F411RE. And to have a modified cmsis_nvic.h for the Blackpill the TOOLCHAIN folders have to be copied too. However, after checking the cmsis_nvic.h file it seems I forget to modify it (as below) so your remark was very useful. Thank you!

cmsis_nvic.h:

/* mbed Microcontroller Library
 * SPDX-License-Identifier: BSD-3-Clause
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2016-2020 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
*/

#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H

#if !defined(MBED_ROM_START)
#define MBED_ROM_START  0x8000000
#endif

#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE  0x40000  // 256 KB
#endif

#if !defined(MBED_RAM_START)
#define MBED_RAM_START  0x20000000
#endif

#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE  0x20000  // 128 KB
#endif

#define NVIC_NUM_VECTORS        102
#define NVIC_RAM_VECTOR_ADDRESS MBED_RAM_START

#endif

Actually, there is a better solution. Add an “extra_labels_add”: [ “STM32F411xE” ] , as you did in the mbed_app.json, and “MBED_ROM_SIZE=0x40000” macro to the custom_targets.json file rather than copying the ’cmsis_nvic.h file and the TOOLCHAIN folders to the Blackpill custom target.

custom_targets.json:

    "BLACKPILL": {
        "inherits": [
            "MCU_STM32F4"
        ],
        "extra_labels_add": [
            "STM32F411xE"
        ],
        "macros_add": [
            "STM32F411xE",
            "MBED_ROM_SIZE=0x40000"
        ],
        "config": {
            "clock_source_usb": {
                "help": "As 48 Mhz clock is configured for USB, SYSCLK has to be reduced from 100 to 60 MHz (set 0 for the max SYSCLK value)",
                "value": "0",
                "macro_name": "CLOCK_SOURCE_USB"
            }
        },
        "overrides": {
            "clock_source": "USE_PLL_HSE_XTAL",
            "lse_available": 1
        },
        "device_has_add": [
            "USBDEVICE"
        ],
        "bootloader_supported": true,
        "detect_code": [
            "0740"
        ],
        "device_name": "MCU_STM32F411CE"
    }
}

And that is how I modified the Blackpill custom target.

Hi @hudaz -
I’ll definitely try these changes out - thanks!

I think it’s because USB requires a very accurate clock to work reliably. An RC (resistor-capacitor) oscillator (like the internal one) is usually not accurate enough for USB. That’s why we better use the external crystal oscillator available on the Blackpill board, which is more precise.

Ah yeah - I do understand the general need for a precision clock. What I don’t understand is what is specifically triggered by CLOCK_SOURCE_USB=1 specifically that makes USB work when USE_PLL_HSE_XTAL is already chosen. The comment and code state that this lowers the device clock from 100mhz to 60mhz, and I don’t fully understand the change there or why it is required.