platformio / platform-ststm32

ST STM32: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm32
Apache License 2.0
394 stars 308 forks source link

Compile errors when including USBHID.h using mbed on bluepill_f103c8 #245

Open bremme opened 5 years ago

bremme commented 5 years ago

I'm trying to use the Bluepill as a USB HID device on the mbed framework. But I'm a bit lost on how to do this and or if this is supported at all. I have tried many things, but nothing seems to work:

Use platformio without Mbed OS

The default is what the documentation calls Mbed lib (https://docs.platformio.org/en/latest/frameworks/mbed.html). It still all a bit vague to me, but I think this is also called Mbed classic, Mbed 2 etc. To my understanding this is either a stripped down version of Mbed OS or an old version of Mbed. In any case without all the OS functions as described here: https://os.mbed.com/docs/mbed-os/v5.12/introduction/index.html.

If I just try to compile without the OS functionality and including USBHID.h. I get:

In file included from /home/bremme/.platformio/packages/framework-mbed/features/unsupported/USBDevice/targets/TARGET_STM/USBHAL_STM32.cpp:33:0:
/home/bremme/.platformio/packages/framework-mbed/features/unsupported/USBDevice/targets/TARGET_STM/USBHAL_STM32.h:49:2: error: #error "Target not supported !"

This might be the most clear message, the Bluepill target is just not supported.

When I search for Mbed libraries that might solve my problem, I find many USBDevice, USBHID libraries. But when I add those to lib_deps I always end up having other dependency issues, among others the MBRZA1H.h header seems to be missing every time.

Use platformio with Mbed OS

By setting build_flags = -D PIO_FRAMEWORK_MBED_RTOS_PRESENT in my platformio.ini file I enable the Mbed OS feature. But when I do this I get:

src/main.cpp:2:10: fatal error: USBHID.h: No such file or directory

While this should be the way to import the HID library according to the Mbed OS documentation.

Is this a bug or is this just expected behaviour? If this is expected perhaps someone can guide me to the documentation on which default Mbed libraries I can use on the Bluepill or how to find out. In case the Mbed support for the Bluepill is just not there yet, what would be an alternative solution to use USB HID on the Bluepill. I would really like to start using Mbed and learn something new or perhaps STM32Cube.

davo112358 commented 5 years ago

I'm up against the same issue. I noticed that in "framework-mbed\targets\TARGET_STM\TARGET_STM32F1\TARGET_BLUEPILL_F103C8\device\system_clock.c" someone believes it's impossible to configure the clocks properly for this board..

/**
  * This file configures the system clock as follows:
  *-----------------------------------------------------------------------------
  * System clock source                | 1- PLL_HSE_EXTC        | 3- PLL_HSI
  *                                    | (external 8 MHz clock) | (internal 8 MHz)
  *                                    | 2- PLL_HSE_XTAL        |
  *                                    | (external 8 MHz xtal)  |
  *-----------------------------------------------------------------------------
  * SYSCLK(MHz)                        | 72                     | 64
  *-----------------------------------------------------------------------------
  * AHBCLK (MHz)                       | 72                     | 64
  *-----------------------------------------------------------------------------
  * APB1CLK (MHz)                      | 36                     | 32
  *-----------------------------------------------------------------------------
  * APB2CLK (MHz)                      | 72                     | 64
  *-----------------------------------------------------------------------------
  * USB capable (48 MHz precise clock) | NO                     | NO
  *-----------------------------------------------------------------------------
  ******************************************************************************
  */

.. which of course makes zero sense considering my bluepill has no issues producing a reliable virtual serialport using stm32duino core.

In the function SetSysClock_PLL_HSE there is no attempt to initialise peripheral clocks unlike in the stm32duino system_clock.h. I fired up cubemx and verified the clock configuration that was used in stm32duino and injected the code to correctly (I think, lol) initialise for 48Mhz usb clock when targeting mbed:

RCC_PeriphCLKInitTypeDef PeriphClkInit;

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
    return 0; // FAIL
}

IMHO I feel like the bluepill has been nerfed in the later releases of the ststm32 platform. Why? I have no idea but I'm sure someone else can elaborate on the issue. I can only guess that USBDevice lib relies on rtos functionality now so consensus was to not bother supporting it on stm32f103c8 due to sram/flash limitations..

All my bluepills have 128kb of flash so I'm very keen to see this work, I'm trying my best to get familiar with platformio/mbed/stm32 etc but it's all quite a bit to take in!

Also before y'all tell me the bluepill usb hardware sitcho sucks, I've reflowed my connector and replaced R10 with 1.5k - verifiying D+ has 1.5k resistance to 3.3v rail etc. The usb port works like a dream for DFU / upload along with virtual serial port (as I mentioned earlier) using stm32duino/maple etc.

davo112358 commented 5 years ago

Same issue trying to target my STM32F407VE (usingenv: seeedArchMax) . USBDevice/USBSerial/USBHID seem to have dropped support for these targets.

There are tutorials online showing how to use USBSerial.h / mbed on both STM32F103C8 as well as STM32F407VE so it seems that at some point in time they've both been left behind / unsupported in current build of ststm32 platform.

davo112358 commented 5 years ago

Incidentally if you add ```defined(TARGET_BLUEPILL_F103C8)```` to the appropriate places in:

.platformio/packages/framework-mbed/features/unsupported/USBDevice/targets/TARGET_STM/USBHAL_STM32.h

and

.platformio/packages/framework-mbed/features/unsupported/USBDevice/targets/TARGET_STM/USBHAL_IP_DEVICE.h

then I had no trouble building it as long as you don't have the USBDevice library installed which seems to fail trying to build TARGET_RENESAS/TARGET_RZ.. due to missing dependencies etc:

[env:BLUEPILL_F103C8]
platform = ststm32
board = BLUEPILL_F103C8
framework = mbed

However the board locks up during instantiation of USBSerial which doesn't come as much of a surprise seeing as I don't have that much experience with HAL etc and took cues from the implementation of USBDevice support for F103RB:

#include <mbed.h>
#include <USBSerial.h>

DigitalOut statusLed(PC_13);

int main() {

  // put your setup code here, to run once:
  USBSerial usbSerial;

  //usbSerial.printf("Good Morning!\n");

  while(1) {
    // put your main code here, to run repeatedly:
    statusLed = 1;
    wait_ms(500);
    //usbSerial.printf("derp\n");
    statusLed = 0;
    wait_ms(500);
    //usbSerial.printf("lerp\n");
  }
}

To be honest this is not the first time I've been left with a bitter taste in my mouth when it comes to ST, frameworks (platformio, zephyr etc) and the venerable f103c8. Apparently it's not worth supporting so I'll be damned / die trying to add support for f103c8 and f407ve to platformio before I give up on ST all together in disgust and go back to using Atmel haha.

I'm going to see if I can dig through the older versions of platform-ststm32 and see where USBDevice support was dropped.

davo112358 commented 5 years ago

Ok so as far as I can tell F103C8 / F407VE etc was never officially supported mbed's USBDevice but I got it going, with a few quirks by using Zoltan Hudak's USBDevice library..

Download his USBDevice library from here.

Extract to .platformio/lib/USBDevice (ensure no other USBDevice library is installed)

Builds ok and actually works (doesn't lockup after reset 😁) with caveats:

[env:BLUEPILL_F103C8]
platform = ststm32
board = BLUEPILL_F103C8
framework = mbed
upload_protocol = stlink

#include <mbed.h>
#include <USBSerial.h>

DigitalOut statusLed(PC_13);

int main() {

  // put your setup code here, to run once:
  USBSerial usbSerial(0x1f00, 0x2012, 0x0001,  false);

  usbSerial.printf("Good Morning!\n");

  while(1) {
    // put your main code here, to run repeatedly:
    statusLed = 1;
    wait_ms(500);
    usbSerial.printf("derp\n");
    statusLed = 0;
    wait_ms(500);
    usbSerial.printf("lerp\n");
  }
}

The board gets stuck in an endless loop inside of USBDevice::write after usb cable is plugged in (no blinky 😭) - waiting for some kind of confirmation of completion:

    /* Wait for completion */
    do {
        result = endpointWriteResult(endpoint);
    } while ((result == EP_PENDING) && configured());

    return (result == EP_COMPLETED);

endpointWriteResult keeps returning EP_PENDING (endpoint = 5, configured() returns true) until a terminal is opened on the host OS and then she fires up and runs without issue (blinky! 😄). Terminate the terminal connection on the host OS and then it gets stuck in the same USBDevice::write loop blocking execution. (yes, no more blinking 😢)

So now I'm going to compare the USBDevice.cpp of this library with the current USBDevice to see if I can't solve it..

Of course OP wants to get USBHID working where I'm more interested in USBSerial but I believe the issue is the USBDevice library so if this is solved then both USBSerial and USBHID should work..

Nitrock28 commented 5 years ago

Hi @davo112358,

Thank you for digging that up, it has been promising for me, but only up to a point 😕.

What I am trying to do is to upload my program to the blue pill through USB-dfu using the bootloader from rogerclarkmelbourne, and then send data back through the USBSerial interface once the code is running. That way I only need a USB cable to do everything.

I followed your instructions and managed to compile your example, but once the upload is done, the led doesn't blink, and I don't have any device or port accessible as I would have when plugging e.g. a FDTI usb to serial device (/dev/ttyUSB0). I managed to make the led blink when uploading through a serial adapter, without bootloader (I don't have a STLINK), but still no serial port accessible from the host.

I tried unplugging the usb a few times to no avail.

I should also note that I managed to do exactly that, uploading trough DFU and sending serial data through USB in my code, using the Arduino core, but that core seems to lack some features that I need. Can you help me?