Giter Club home page Giter Club logo

libusb_stm32's Introduction

LNX build WIN build OSX build

Lightweight USB Device Stack

  • Lightweight and fast
  • Event-driven process workflow
  • Completely separated USB hardware driver and usb core
  • Easy to use.

Requirements

All requirements can be downloaded into a directory specified in environment variable CMSIS using make cmsis command.

Supported hardware

MCU SeriesFeaturesDriverFile
STM32L0x2 STM32L0x3 STM32F070 STM32F0x2 STM32F0x8 Doublebuffered[2]
8[1] endpoints
BC1.2
usbd_devfs usbd_stm32l052_devfs.c
usbd_devfs_asm usbd_stm32l052_devfs_asm.S
STM32L4x2 STM32L4x3 STM32G4 series Doublebuffered[2]
8[1] endpoints
BC1.2
usbd_devfs usbd_stm32l433_devfs.c
usbd_devfs_asm usbd_stm32l052_devfs_asm.S
STM32L1xx Doublebuffered[2]
8[1] endpoints
usbd_devfs usbd_stm32l100_devfs.c
usbd_devfs_asm usbd_stm32l100_devfs_asm.S
STM32F102 STM32F103 STM32F302 STM32F303 STM32F373 Doublebuffered[2]
External DP pullup
8[1] endpoints
usbd_devfs usbd_stm32f103_devfs.c
usbd_devfs_asm usbd_stm32f103_devfs_asm.S
STM32WB55 Doublebuffered[2]
External DP pullup
8[1] endpoints
usbd_devfs usbd_stm32wb55_devfs.c
STM32L4x5 STM32L4x6 Doublebuffered
6 endpoints
BC1.2
VBUS detection
usbd_otgfs usbd_stm32l476_otgfs.c
STM32F401 STM32F411 Doublebuffered
4 endpoints
VBUS detection
SOF output
usbd_otgfs usbd_stm32f429_otgfs.c
STM32F4x5 STM32F4x7 STM32F4x9 Doublebuffered
4 endpoints
VBUS detection
SOF output
usbd_otgfs usbd_stm32f429_otgfs.c
Doublebuffered
6 endpoints
VBUS detection
SOF output
usbd_otghs usbd_stm32f429_otghs.c
STM32F105 STM32F107 Doublebuffered
4 endpoints
VBUS detection
SOF output
usbd_otgfs usbd_stm32f105_otgfs.c
STM32F4x6 STM32F7 Doublebuffered
6 endpoints
VBUS detection
SOF output
usbd_otgfs usbd_stm32f446_otgfs.c
Doublebuffered
9 endpoints
VBUS detection
SOF output
usbd_otghs usbd_stm32f446_otghs.c
STM32H743 Doublebuffered
6 endpoints
VBUS detection
SOF output
usbd_otgfs usbd_stm32h743_otgfs.c
  1. Single physical endpoint can be used to implement
  • one bi-directional/single-buffer logical endpoint (CONTROL)
  • one uni-directional/double-buffer logical endpoint (BULK OR ISOCHRONOUS)
  • two uni-directional/single-buffer logical endpoints (BULK OR INTERRUPT)
  1. At this moment BULK IN endpoint can use both buffers, but it is not real doublebuffered.

  2. Tested with STM32L052K8, STM32L100RC, STM32L476RG, STM32F072C8, STM32F103C8, STM32F103CB, STM32F303CC, STM32F303RE, STM32F429ZI, STM32F105RBT6, STM32F107VCT6, STM32L433CCT6, STM32F070CBT6, STM32G431RB, STM32F411CEUx, STM32F405RG, STM32F446RE, STM32F373CC, STM32L053R8, GD32F103C8T6, STM32F745VE, STM32F401CE, STM32H743. See hardware.md for details.

Don't copy-paste the startup code from the demo without considering RCC and USB clock requirements.

The HSI oscillator usually does not meet the timing requirements for USB and may cause performance loss and a high error rate.

Implemented definitions for classes

  1. USB HID based on Device Class Definition for Human Interface Devices (HID) Version 1.11
  2. USB DFU based on USB Device Firmware Upgrade Specification, Revision 1.1
  3. USB CDC based on Class definitions for Communication Devices 1.2
  4. USB TMC based on USB Device Test and Measurement Class Specification, Revision 1.0

Using makefile

  • to build library module
make module MODULE=path/module.a DEFINES="mcu specified defines" CFLAGS="cpu specified compiler flags"
  • to build demo
make bluepill program
make stm32l052x8
  • to get a help
make help

Default values:

Variable Default Value Means
CMSIS ./CMSIS path to CMSIS root folder
CMSISDEV $(CMSIS)/Device path to CMSIS device folder
CMSISCORE $(CMSIS)/CMSIS/Include $(CMSIS)/CMSIS/Core/Include path to CMSIS core headers
MCU stm32l100xc MCU selection for demo project
CFLAGS -mcpu=cortex-m3 -mfloat-abi=soft MCU specified compiler flags
DEFINES STM32L1 STM32L100xC MCU specified defines
STPROG_CLI ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI Path to the ST Cube Programmer CLI
OPTFLAGS -Os Code optimization flags

Useful Resources

  1. USB Implementers Forum official site
  2. USB Made Simple
  3. LUFA - the Lightweight USB Framework for AVRs.
  4. Open Source ARM cortex m microcontroller library

libusb_stm32's People

Contributors

7134956 avatar aam335 avatar aitap avatar crvux avatar dmitrystu avatar dragonman225 avatar fabianinostroza avatar fortysixandtwo avatar fragonite avatar hedger avatar hooddanielc avatar horrordash avatar jarviscraft avatar jiribilek avatar mamins1376 avatar nickray avatar nminaylov avatar rafaelmartins avatar travisro avatar via avatar vvg77ripe avatar xcvista avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libusb_stm32's Issues

New chip request: STM32F446 and STM32F732.

Those chips are some of the newer high performance chips, and for STM32F446 I am planning to use it in a project. They uses an updated OTG block so existing STM32F405 code will likely not work.

STM32F446 is similar to STM32F405 that it has an OTG_FS block with internal PHY, as well as an OTG_HS block with internal FS PHY and ULPI pins.

STM32F732 is part of the new STM32F7 line. The OTG_FS block is similar to that of STM32F446. Its OTG_HS block features internal HS PHY and ULPI pins.

For STM32F446, it need three drivers: otgfs, otghs and otghs_ulpi. For STM32F732 it needs only otgfs and otghs. Since the internal PHY for OTG_HS in STM32F732 is already a HS PHY, there is no point except for compatibility reasons to use external PHY at all, so that more-or-less redundant feature can be left unsupported.

C++ compatibility with usb_string_descriptor & macros

Hi,

I'm trying to use this in a mixed C & C++ language project for the STM32H750 (looking at porting the otghs driver), and have some issues with usb_string_descriptor and USB_STRING_DESC.

Doing something like

static const struct usb_string_descriptor manuf_desc_en = USB_STRING_DESC("Open source USB stack for STM32");`

Gives this error, on member wString

error: invalid conversion from 'const char16_t*' to 'uint16_t {aka short unsigned int}' [-fpermissive]
                                     .wString = {CAT(u,s)}}

If I make wString a pointer, I get a different error, where C++ is pickier about extra braces around scalars

error: braces around scalar initializer for type 'uint16_t* {aka short unsigned int*}'
                                     .wString = {__VA_ARGS__}}

Changing the macros to this works, also need an explicit cast to uint16_t* so we lose the const-ness

/** Macro to create \ref usb_string_descriptor from array */
#define USB_ARRAY_DESC(...)        {.bLength = 2 + sizeof((uint16_t[]){__VA_ARGS__}),\
                                    .bDescriptorType = USB_DTYPE_STRING,\
                                    .wString = (uint16_t*)__VA_ARGS__}
/** Macro to create \ref usb_string_descriptor from string */
#define USB_STRING_DESC(s)         {.bLength = sizeof(CAT(u,s)),\
                                    .bDescriptorType = USB_DTYPE_STRING,\
                                    .wString = (uint16_t*)CAT(u,s)}

struct usb_string_descriptor {
    uint8_t  bLength;
    uint8_t  bDescriptorType;
    uint16_t* wString;
} __attribute__((packed));

Would it be ok to change usb_string_descriptor, USB_ARRAY_DESC, and USB_STRING_DESC to something like this? I'm not sure if the brace around the single element matters in this case. I don't think this modifies behavior.

Porting this library to other devices, round two

This recommendation is a continuation of the issue #2 but regarding the two USB peripherals found on STM32F2, F4 and F7 families. The existing v2 driver may work for the OTG_FS peripheral, but is there any consideration about the OTG_HS, either in built-in FS PHY mode, or in external HS PHY mode?

I am considering building a STM32F405RG USB 2.0 Hi-Speed Experiment Board for this, with all three USB connections being made available (OTG_FS, OTG_HS with external PHY and OTG_HS with internal FS PHY). Are you interested?

Remove PMA size warning

What's the reason of having the PMA size configurable? Isn't it fixed for a concrete part number?

Isochronous IN (TX) without double-buffer

I am using the STMF103 to implement a 50 to 300 byte transfer every 10 to 25ms to a host PC.
Currently, isochronous transfers have to be double-buffered - however since the PMA is limited to 512bytes on the STMF103, this means the isochronous packet size is in turn limited to less than 256bytes.
For my case, together with control ep, I could only have one double-buffered isochronous ep with a packet size of 224bytes if my understanding is correct.
While my design is flexible, I would prefer one large transfer over multiple smaller ones, mostly due to latency, so one larger buffer is preferrable to me. Since I'm only sending at max every 10ms I do not expect to need the second buffer.
Would it be possible to change this behaviour or is this a hardware limitation?
Currently I'm still in the phase where I don't need the bigger transfers, but I'd be interested to know for the future.

How do I un-stall to send data out?

I'm trying to write a serial console layer. When the host sends data, all is well, the device receives it and processes it. After that, it enters NAK state, as I understand it. Both endpoints are stalled.

But what if the device wants to send data in this state? How do I get the device to start sending, i.e. report to the host that it has data to send? The ep_setstall() function appears to be for internal use.

Device does not enumerate when connected via USB hub on STM32G431

Currently, I am trying to use your awesome library on STM32G431. However, I observe a strange behavior.

I flash your demo program to the MCU. When I connect it directly to my laptop's port, everything works perfectly. However, when I connect it via a USB hub, the device does not enumerate (there are no traces in dmesg) or with some of the USB hubs a trace "Cannot enable. Maybe the USB cable is bad?" appears in the log.

The demo works fine with the same cable and the same USB hubs with STM32F103.

Only the Dp and Dm pins are connected to the STM32G431 MCU. Is possible there is something wrong with the G4 implementation? What can I do to debug the issue? I am wondering if it can have something to do with power-cycling the USB.

EDIT: I am sorry about the empty issue; I misclicked.

Issues porting to F7

We've been making an effort to port the lib to the F723 using HS, but have been running into a few issues.

Using initialization code primarily pulled from the HAL. Copied over usbd_stm32f429_otghs.c as the base driver, since there seems to be a lot of overlap in the HS cores (other than the number of endpoints and some other constants). Similar to #9 (comment) , can't get past the bus reset event, and in dmesg enumeration seems to fail after a number of resets:

[ 9591.952638] usb 3-3.4.1: device descriptor read/all, error -110
[ 9592.128604] usb 3-3.4.1: new high-speed USB device number 82 using xhci_hcd
[ 9597.772548] usb 3-3.4.1: Using ep0 maxpacket: 8
[ 9603.216525] usb 3-3.4.1: device descriptor read/all, error -110
[ 9603.216578] usb 3-3.4-port1: attempt power cycle
[ 9603.896488] usb 3-3.4.1: new high-speed USB device number 83 using xhci_hcd
[ 9609.360465] usb 3-3.4.1: device descriptor read/8, error -110
[ 9614.480412] usb 3-3.4.1: device descriptor read/8, error -110
[ 9614.760386] usb 3-3.4.1: new high-speed USB device number 84 using xhci_hcd
[ 9620.112367] usb 3-3.4.1: device descriptor read/8, error -110
[ 9625.233309] usb 3-3.4.1: device descriptor read/8, error -110
[ 9625.336350] usb 3-3.4-port1: unable to enumerate USB device

(error -110 is said to be related to power but I'm not sure how much to trust that here, especially considering that the hsusb examples from cubef7 work fine)

Any potential guidance would be greatly appreciated (places to look, things to verify, resources, etc).

The HID device does not work on Windows

Hi,

I connected my device (on which the the demo firmware is flashed), but the device worked only on Linux but not on Windows. I am not sure why. This is the error I get on Windows events log (these messages are copied from different events to give more info):

Device USB\VID_0483&PID_5740&MI_02\7&118ad3aa&0&0002 had a problem starting.
Device USB\VID_0483&PID_5740&MI_02\7&118ad3aa&0&0002 was not migrated due to partial or ambiguous match.
This device cannot start. (Code 10)
Report Descriptor was not byte aligned.

Do you have an idea how to fix it?

Maybe showing my Linux output (which seems to work pretty well) may help? This is how my output in my Linux syslog looks like (the mouse moves circularly as supposed in the demo):

Jun 30 21:07:32 raspberrypi kernel: [31711.932127] usb 1-1.4.2: new full-speed USB device number 7 using dwc_otg
Jun 30 21:07:32 raspberrypi kernel: [31712.168976] usb 1-1.4.2: New USB device found, idVendor=0483, idProduct=5740, bcdDevice= 1.00
Jun 30 21:07:32 raspberrypi kernel: [31712.168993] usb 1-1.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=254
Jun 30 21:07:32 raspberrypi kernel: [31712.169003] usb 1-1.4.2: Product: CDC Loopback demo
Jun 30 21:07:32 raspberrypi kernel: [31712.169012] usb 1-1.4.2: Manufacturer: Open source USB stack for STM32
Jun 30 21:07:32 raspberrypi kernel: [31712.169021] usb 1-1.4.2: SerialNumber: 5682CFA2
Jun 30 21:07:32 raspberrypi kernel: [31712.174320] input: Open source USB stack for STM32 CDC Loopback demo as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.2/1-1.4.2:1.2/0003:0483:5740.0006/input/input9
Jun 30 21:07:32 raspberrypi kernel: [31712.182877] hid-generic 0003:0483:5740.0006: input,hidraw2: USB HID v1.00 Mouse [Open source USB stack for STM32 CDC Loopback demo] on usb-3f980000.usb-1.4.2/input2
Jun 30 21:07:32 raspberrypi mtp-probe: checking bus 1, device 7: "/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.2"
Jun 30 21:07:32 raspberrypi mtp-probe: bus: 1, device: 7 was not an MTP device
Jun 30 21:07:32 raspberrypi kernel: [31712.238869] cdc_acm 1-1.4.2:1.0: ttyACM0: USB ACM device
Jun 30 21:07:32 raspberrypi kernel: [31712.241358] usbcore: registered new interface driver cdc_acm
Jun 30 21:07:32 raspberrypi kernel: [31712.241374] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
Jun 30 21:07:33 raspberrypi systemd-udevd[1719]: Process '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev' failed with exit code 1.
Jun 30 21:07:33 raspberrypi systemd-udevd[1720]: Process '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev' failed with exit code 1.
Jun 30 21:07:33 raspberrypi mtp-probe: checking bus 1, device 7: "/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.2"
Jun 30 21:07:33 raspberrypi mtp-probe: bus: 1, device: 7 was not an MTP device
Jun 30 21:08:08 raspberrypi kernel: [31748.232050] usb 1-1.4.2: USB disconnect, device number 7

F405 BULK IN fails when length > 4

My F405 firmware sends bytes over a BULK IN endpoint to a PC every 10ms. If it send more than four bytes, then after a few hundred successful sends the USB pipe stops with a PROTOCOL_ERROR; see the attached pcap file line 470. This was captured on a Debian 10 host. The device is a Matek F405STD board.

I'm using the usbd_stm32f429_otgfs "driver". The otgfs BULK endpoint is not in a stalled state, according to ep_isstalled(). The device is not stuck. The protocol error is sent to the host exactly when I would expect the normal byte transfer to take place, so it seems the call to usbd_ep_write() caused the condition. My EP1 size is 64, as is my EP0.

I am at a loss as to what to look at next, please advise. The device and host code can be found here.

TX not working when buffer length equal to CDC_DATA_SZ

Hello there,
i just started playing around with this very nice library and came across the issue, that when i use the cdc_loop demo and im sending the given enpoint size (64B in this case) its not transmitting back to the host. When i change the line that writes to the endpoint to this:
usbd_ep_write(dev, CDC_TXD_EP, &fifo[0], (rxPos < CDC_DATA_SZ) ? rxPos : (CDC_DATA_SZ-1));
It works and sends two packets, first one is 63B and the next is 1B

Greets :)

CDC and Serial devices do not work (STM32F429)

Hello,

I flashed the code STM32F429 MCU, the HID (mouse) works fine (tested on Linux and Windows). However, CDC and Serial port devices don't work (tested on WIndows) and they are shown with a yellow exclamation mark.

Here are the information I got from windows device manager.

CDC Device:

Status:

The drivers for this device are not installed. (Code 28)
There are no compatible drivers for this device.

Events:

Device USB\VID_0483&PID_5740&MI_01\7&118ad3aa&0&0001 was configured.
Driver Name: null
Class Guid: {00000000-0000-0000-0000-000000000000}
Driver Date:
Driver Version:
Driver Provider:
Driver Section:
Driver Rank: 0x0
Matching Device Id:
Outranked Drivers:
Device Updated: false
Parent Device: USB\VID_0483&PID_5740\5682CFA2

Serial port:

Status:

This device cannot start. (Code 10)
A device which does not exist was specified.

Events:

Driver Management concluded the process to install driver usbser.inf_amd64_6821f829c6b22a54 for Device Instance ID USB\VID_0483&PID_5740&MI_00\7&118AD3AA&0&0000 with the following status: 0x0.

Driver Management has concluded the process to add Service usbser for Device Instance ID USB\VID_0483&PID_5740&MI_00\7&118AD3AA&0&0000 with the following status: 0.

Device USB\VID_0483&PID_5740&MI_00\7&118ad3aa&0&0000 requires further installation.

Do you have any idea what the problem is?

PlatformIO support

Major kudos for the library.

Simply including the repo in the PlatformIO project manifest doesn't work out of the box because of different inc vs include convention:

[env]
lib_deps =
    dmitrystu/libusb_stm32

We can create a library.json manifest in the repo to enable this. What do you think?

hid descriptor request lost

Hey,
I've been trying to implement an HID demo.
used an hid example from lufa as the descriptor values and cross compared the code they we're using with your implantation.

I will note that CDC loopback works well, so does modding it to become a debug print path.

I'm running on the stm32f042 nucleo.

long story short:
The computer gets the device descriptor, but gets no reply from HID Report request.

looking at wireshark the computer sends it as GET DESCRIPTOR HID REPORT (0x22)
image

but when I place a breakpoint on the point where it should receive it, nothing gets through, meaning the callback is not triggered.

here is a link to the repo:
https://github.com/maor1993/StamDevPlayGround/blob/master/stam/Src/usbhid.c

Any tests I should do to find out why?
Thanks,
Maor.

No seperate callback for in/out endpoint possible

The demo makes clear that the following is expected to work:

usbd_reg_endpoint(dev, CDC_RXD_EP, cdc_rxonly);
usbd_reg_endpoint(dev, CDC_TXD_EP, cdc_txonly);

(where CDC_RXD_EP = 0x01, CDC_TXD_EP = 0x81).
However, when the callbacks are stored, the in/out distinction is thrown away:

dev->endpoint[ep & 0x07] = callback;

Thus resulting in both endpoints having the same callback, despite expected to have their own.

Not entirely sure about this, how this relates to the endpoint limitation noted in the readme, since I haven't finished porting my code from HAL USB stack. But from the code I see no reason to not store and access the callbacks as follows:

dev->endpoint[((ep >> 4) & 0x08) | (ep & 0x07)]

For me not a big deal, as a workaround I can use a different base is for the in/out endpoints.
Or even better, just differenciate between in/out in the shared handler using the passed full ep number

What's USBD_DP_PORT and USBD_DP_PIN for?

I was going through the whole project with Doxygen. A few questions:

  1. What's USBD_DP_PORT and USBD_DP_PIN for?
    find it somewhere, but the comment is kinda confusing. Is it used to enable the external pull up resistor?
  2. If I'm not making mistake. usbd_poll() is used to process all event from USB, right?
    usbd_reg_config to register the config & deconfig process;
    usbd_reg_control to register the control part of USB device;
    usbd_reg_descr to register all the descriptor may be used.
    So if I'm going to implement an user-defined HID device, then I need to
    a. write a config process (which may just be just like modifying some lines in cdc_setconf, adding all endpoints I need, all callback for each endpoint)
    b. write all the descriptor I may need and register them.
    c. implement all request SET PROTOCOL, GET PROTOCOL, GET IDLE, SET IDLE, SET REPORT, GET REPORTin the callback registered in the usbd_reg_control. (ref: https://www.keil.com/pack/doc/mw/USB/html/_h_i_d.html)
    My problem is, what should we do in SET REPORT and GET REPORT? In the custom hid of stm32 HAL USB, they need to call
    hhid-> IsReportAvailable =1 and USBD_CtlPrepareRx, do libusb_stm32 need to do some similar thing like that?

STM32F070

I've successfully used this library with stm32f401re and now I'm trying to get it to work with stm32f070rb. Looking at the datasheet the register names, bits and memory locations are identical to the stm32l052, so that code should work, but it fails to set up the address in the initial step. If I compile the same code for the stm32f401re it works, so I'm pretty sure I have my descriptors set up.

I've set the GPIO to high speed, but it didn't help. I'm getting this error back under Linux.

device descriptor read/64, error -71
Device not responding to setup address.

Flash DFU bootloader is working, so it's not hardware and I was wondering if anyone had an example of it working on this device?

Problem in getinfo() for STM32F103

if (USBD_DP_PORT->IDR && _BV(USBD_DP_PIN)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);

The logical AND should probably be replaced by a bitwise AND, such that the bit value is used as a mask on the read port input data:
if (USBD_DP_PORT->IDR & _BV(USBD_DP_PIN)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);

Missing stm32.h

I'm trying to compile this library on Ubuntu for an STM32F048xx. I downloaded STM32CubeF0 v1.9.0 and added the following to the Makefile:

STARTUP.stm32f048xx  = $(CMSISDEV)/STM32L0xx/Source/Templates/gcc/startup_stm32f048xx.s
CFLAGS.stm32f048xx   = -mcpu=cortex-m0
DEFINES.stm32f048xx  = STM32F0 STM32F048xx

And try to build the module, but it fails:

$ make module CMSIS=../STM32Cube_FW_F0_V1.9.0/Drivers/CMSIS MCU=stm32f048xx
compiling src/usb_32v1.o
src/usb_32v1.c:18:19: fatal error: stm32.h: No such file or directory
 #include "stm32.h"

I'm new to the STM32 controllers so perhaps that should be obvious, but I wasn't able to find which library I'm missing here.

Interrupt Endpoint callbacks missing

I am trying to build a HID device, which calls for a pair of Interrupt endpoints. However the endpoint callbacks are not being called at all, although on the host side the system is trying to INTERRUPT IN.

What is amiss here? Is there something I need to be aware of?

Here is my code. I am using an interrupt-driven stack so this file is pretty self-contained.

High CPU load

While trying out this driver on a Blue Pill plugged into MacOS, I'm seeing a very large CPU load in the kernel (eventually, one core gets pegged at 100%). I'm trying out the demo in loopback mode, polled.

While I understand that the BP will be running flat out, polling the USB hardware, I don't understand why and how this would affect the overall load on the USB bus or host CPU. Is this a (known) bug?

My other question may be related: why is the packet size for data transfers limited to 8 bytes? It is set with a #define CDC_EP0_SIZE 0x08 in the demo, could that be raised to 64 bytes? Unfortunately, it also appears to be hardcoded in other places.

FWIW, my point of reference is another USB implementation - it's in Forth, but also for the same F103 µC of the Blue Pill. There, I don't see this load on the CPU, and 64-byte packets appear to work fine.

Porting this library to other devices

I wonder if this library can be used for other chips, like STM32F103, STM32F303 or STM32F405. From a quick check to the reference manual it seem to me that the F103 and F303 have the same USB peripheral, albeit at different addresses, as the L152.

Questions:

  • How difficult will it be porting the L152 files to F103 or F303? (Based on your experience porting it to the F042)
  • How to do it?

Moving driver and core entry points into special subsections.

The main idea to put driver entry points AKA const struct usbd_driver and core entry point void usbd_poll(usbd_device *dev); into special named sections like .text.usbd_driver and .text.usbd_core respectively.
It will have no effect on general linkage, but can help to put these sections to fixed places in bootloader (just after isr_vectors for instance).
So, because the size of const struct usbd_driver is fixed, the usbd_poll(usbd_device *dev) entry point also will be on fixed place even bootloader will be updated.
What do you think about this, guys ?

Provide hints where to find stm32.h and CMSIS

Hello,

if somebody lands on you libusb_stm32 page, it is hard to find stm32.h and CMSIS. stm32.h is in your root github directory. But what CMSIS do you reference? It is not in STCubeMx. Is it in StCubeXy? Presently downloading the 1.4 GByte to check...

Calculating _rxcnt in usbd_stm32l433_devfs.c wrong?

What is going on here?
https://github.com/dmitrystu/libusb_stm32/blob/master/src/usbd_stm32l433_devfs.c#L245
If endpoint size is greater than 62, we should align it by 32.
Then left shift by 5 bits to get number of blocks in bits 10:14,
then set bit 15 to 1 to indicate block size of 32 bytes and substract 0x400 (reduce NUM_BLOCK by one, because NUM_BLOCK=Number of 32 byte blocks - 1)
So should't it be _rxcnt = 0x8000 - 0x400 + (epsize << 5)?
Or am i missing something?

HID example request

Congratulations for your great work !
I have tested successfully your USB device stack with STM32F103C8 and STM32F407VET6. It works great !

Is there any HID example like the cdc_loop.c you have included in the demo folder ?
Any mouse or keyboard HID example is enough to be used as template for other HID devices

Thanks in advance

Tested on STM32F411CEUx

Hi Dmitry,

Just wanted to let you know your stack also works for STM32F411xE devices. I just had to adapt your usb.h with

#elif defined(STM32F411xE)

#define USBD_STM32F429FS
extern const struct usbd_driver usbd_otgfs;
#define usbd_hw usbd_otgfs

to let everything work. I tested it with your CDC and HID demo.

By the way i wanted to ask you if you plan on publishing also the mass storage device .h files (as i read in other issues, you mentioned there are some parts already done). Further, i want to implement an audio device but before starting on my own, is there anything like that already available? Ah and are you planning on doing some host or even OTG stacks too?

Thank you and thanks for this very nice light weight stack!

Using the demo source code in CubeIDE

Hello,

may I ask you if it is possible to show how to load the demo source code (for example of F429) into a STM32CubeIDE project (or to upload the final project of this IDE)? I tried doing that by myself for a long time but I could not get functional code.

More specifically, I am using the Discovery Board of STM32F429 MCU (where the USB connection is done by HS-IN-FS).

Regards

H7?

Is there a reason this library never supported the H-series of STM32's? I am trying to port a project from an F4 to an H753 and this is a major component of it.

Why I need two interface for acm?

This is not a bug report. I'm newbie to USB driver. I tried your demo, and I found there's two interfaces to support acm. And the endpoint of the first interface wasn't registered (CDC_NTF_EP). I noticed that you grouped these two interfaces together (USB_DTYPE_INTERFASEASSOC), why did you do that? Can you help me out?

Soft core reset error handling

Congratulations on the libs they are amazing and nicely written. I am working with STM32F407 and sometimes the USB_FS peripheral gets stuck (~20% of the times) in the low level driver for the specific microcontroller, specifically when calling the enable() and calling _WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST), reading the datasheet the soft core reset is optional (page 1278 of the user reference manual):

Typically, the software reset is used during software development and also when you
dynamically change the PHY selection bits in the above listed USB configuration registers.
When you change the PHY, the corresponding clock for the PHY is selected and used in the
PHY domain. Once a new clock is selected, the PHY domain has to be reset for proper
operation.

I got rid of that call and I just wait for the idle state _WBS(OTG->GRSTCTL, USB_OTG_GRSTCTL_AHBIDL); and everything works fine.

Does anybody have the same issue with the soft core reset or knows if such call is needed?
If the reset is needed is the case of adding a timeout in the while() to handle this problems?

Thank you again for the efforts.

Packed struct alignment warning for usb_string_descriptor

When compiling I was getting this warning:

usbd_stm32f429_otgfs.c:450:21: warning: taking address of packed member of 'struct usb_string_descriptor' may result in an unaligned pointer value [-Waddress-of-packed-member]
  450 |     uint16_t *str = dsc->wString;
      |                     ^~~

This can be fixed by changing the declaration of struct usb_string_descriptor in usb_std.h to include __attribute__ ((aligned (4)))

As such:

struct usb_string_descriptor {                                                     
    uint8_t  bLength;               /**<\brief Size of the descriptor, in bytes.*/
    uint8_t  bDescriptorType;       /**<\brief String descriptor type.*/           
    uint16_t wString[];             /**<\brief String data, as unicode characters or array of
                                     * \ref USB_STD_LANGID codes. */               
} __attribute__((packed)) __attribute__ ((aligned (4)));

Not sure if there are negative consequences to doing that.

stm32f070f6px

i am trying to get your library working on my stm32f070f6 chip from past two days.
i have read previous issue which says stm32l052 code should work on my chipset. beacuse startup code for my chip was missing in cdc_startup.c file. i had added it as below

#elif defined(STM32F070x6)
    /* set flash latency 1WS */
    _BMD(FLASH->ACR, FLASH_ACR_LATENCY, 1);
    if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_PLL) /* (1) */
    {
        RCC->CFGR &= (uint32_t) (~RCC_CFGR_SW); /* (2) */
        while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) /* (3) */
        {
            /* For robust implementation, add here time-out management */
        }
    }
    RCC->CR &= (uint32_t)(~RCC_CR_PLLON);/* (4) */
    while((RCC->CR & RCC_CR_PLLRDY) != 0) /* (5) */
    {
        /* For robust implementation, add here time-out management */
    }
    RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMUL)) | (RCC_CFGR_PLLMUL6); /* (6) */
    RCC->CR |= RCC_CR_PLLON; /* (7) */
    while((RCC->CR & RCC_CR_PLLRDY) == 0) /* (8) */
    {
        /* For robust implementation, add here time-out management */
    }
    RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL); /* (9) */
    while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) /* (10) */
    {
        /* For robust implementation, add here time-out management */
    }
    RCC->CFGR3 |= RCC_CFGR3_USBSW_PLLCLK;
#endif

but i am still unable to get it working. this clock setup was working with cubemx project so i think my startup code does set and enable usb clock through pll to 48Mhz.

defines that i was using are
STM32F0, STM32F070x6, USBD_SOF_DISABLED

default linker script for stm32f070f6px was used with --specs=nosys.specs

please help me

Porting to STM32F469

Hello, I'm trying to port this library to STM32F469, using a 32F469IDISCOVERY development board.

First I add STM32F469xx to the group of STM32F4 devices in usb.h,

#elif defined(STM32F405xx) || defined(STM32F415xx) || \
       defined(STM32F407xx) || defined(STM32F417xx) || \
       defined(STM32F427xx) || defined(STM32F437xx) || \
       defined(STM32F429xx) || defined(STM32F439xx) || \
+      defined(STM32F469xx)

then I modify usbd_stm32f429_otgfs.c and usbd_stm32f429_otghs.c since the name of the VBUS sense register field is different, as shown below.

        /* configuring Vbus sense and SOF output */
#if defined (USBD_VBUS_DETECT) && defined(USBD_SOF_OUT)
#if defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_VBDEN;
#else
        OTG->GCCFG = USB_OTG_GCCFG_VBUSBSEN | USB_OTG_GCCFG_SOFOUTEN;
#endif
#elif defined(USBD_VBUS_DETECT)
#if defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_VBDEN;
#else
        OTG->GCCFG = USB_OTG_GCCFG_VBUSBSEN;
#endif
#elif defined(USBD_SOF_OUT)
        OTG->GCCFG = USB_OTG_GCCFG_NOVBUSSENS | USB_OTG_GCCFG_SOFOUTEN;
#else
#if !defined(STM32F469xx)
        OTG->GCCFG = USB_OTG_GCCFG_NOVBUSSENS;
#endif
#endif

Finally, I add the following init code to cdc_startup.c. (Note that I haven't handle the USBD_PRIMARY_OTGHS case.)

#elif defined(STM32F469xx)
    /* set flash latency 4WS, see RM3086 p.80 */
    _BMD(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_4WS);
    /* setting up PLL 16MHz HSI, VCO=144MHz, PLLP = 144MHz PLLQ = 48MHz  */
    _BMD(RCC->PLLCFGR,
        RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLQ,
        _VAL2FLD(RCC_PLLCFGR_PLLM, 4) | _VAL2FLD(RCC_PLLCFGR_PLLN, 72) | _VAL2FLD(RCC_PLLCFGR_PLLQ, 6));
    /* enabling PLL */
    _BST(RCC->CR, RCC_CR_PLLON);
    _WBS(RCC->CR, RCC_CR_PLLRDY);
    /* switching to PLL */
    _BMD(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
    _WVL(RCC->CFGR, RCC_CFGR_SWS, RCC_CFGR_SWS_PLL);
    /* enabling GPIOA */
    _BST(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);
    /* setting PA10 (ID), PA11 (DM) and PA12 (DP) to AF10 (USB_FS) */
    _BST(GPIOA->AFR[1], (0x0A << 8) | (0x0A << 12) | (0x0A << 16));
    /* setting PA9 (VBUS) to input mode, and PA10, PA11, PA12 to AF mode */
    _BMD(GPIOA->MODER, (0x03 << 18) | (0x03 << 20) | (0x03 << 22) | (0x03 << 24), (0x02 << 20) | (0x02 << 22) | (0x02 << 24));
    /* setting PA10 to open-drain */
    _BST(GPIOA->OTYPER, (0x01 << 10));
    /* setting PA11, PA12 to high speed */
    _BMD(GPIOA->OSPEEDR, (0x03 << 22) | (0x03 << 24), (0x02 << 22) | (0x02 << 24));
    /* setting PA9, PA11, PA12 to no pull, PA10 to pull-up */
    _BMD(GPIOA->PUPDR, (0x03 << 18) | (0x03 << 20) | (0x03 << 22) | (0x03 << 24), (0x01 << 20));

I can compile the demo code with this linker script, which is generated by CubeMX, and the following Makefile rule:

stm32f469ni: clean
  @$(MAKE) demo STARTUP='$(CMSISDEV)/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f469xx.s' \
				LDSCRIPT='demo/stm32f469ni.ld' \
				DEFINES='STM32F4 STM32F469xx USBD_VBUS_DETECT' \
				CFLAGS='-mcpu=cortex-m4'

But the device would not enumerate, although if I trace the execution with a debugger, I could see that cdc_control() and cdc_getdesc() callbacks got called.

I wonder if I did something wrong or actually the USB control mechanism of STM32F469 is different from other F4 devices. Will keep debugging but if someone could point out the problems I would appreciate!

CDC IN ep callback invocation

I'm having trouble with the CDC TX. The callback isn't called after not performing any writes in the previous invocation.

The functionality is described in #1 and you suggest writing an empty message to notify the callback. at start (demo has this). But if the callback doesn't initiate another write then the next callback isn't invoked. I tried busy-notifying the ep whenever I there's data, but it causes weird data scrambling. I'm calling poll in a busy loop.

How is one supposed to know when to perform the notification?

OTG FS TX Fifo allocation

As you know the OTG FS parts have 1.25KB RAM for the FIFOs. The datasheet says that larger TX FIFOs improve performance, but I noticed your code only assigns the minimum required (epsize or 16 words in set_tx_fifo).
Before I have just split the remaining RAM (after RX and endpoint 0 TX) equally to each of the 3 IN endpoints. There's quite a lot of RAM for only 3 endpoints.
Do you think it is worth having a way for the application code to manually set these TX FIFO sizes?

Double buffer documentation

It would be interesting to have a demo or docs for the "not real" doublebuf functionality. Currently I have no idea how to use it - it didn't work when I simply "tried switching it on"

Any porting guide?

I appreciate devfs approach to split MCU dependant driver and usbd core.
But I would like to port/fork/extend this library to Milandr MCUs.
Are there any porting guide or any other docs to build devfs, for example, 1986VE92 (replacement for F103 but it has it's own peripherals, including usb)? Any tricks&tips?
p.s. It's pretty cool such amazing library are written by russian programmer ^)

STM32F429 OTG HS: Windows says: Device Descriptor Request Failed

I am mostly just using the cdc_loopback example using IRQ, the only different is it is running on thread as part of a FreeRTOS system.

There are 2 problems actually:

sometimes it gets stuck forever at:
usb/src/usbd_stm32f429_otghs.c:121

		_WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST);

but most of the time it gets through that, it gets into poll() a couple of times then no more.
meanwhile on my computer Windows says the USB device is not recognized and in Device Manager it says Device Descriptor Request Failed)

Is this a software problem or hardware problem? I dont know much about USB so its hard for me to tell.

Tested on STM32F401RE

I have the basic cdc_loop code working on an STM32F401RE, using unmodified stm32f429 driver code.

I haven't checked other types of endpoints, but as I only CDC for now I may not get to it for a while.

Programmatically enabling SOF interrupt

At the moment the SOF interrupt is enabled through a define. I would like to turn it on and off from my class.

I use the usbd_evt_eptx interrupt event to trigger the next transfer, or clear the sending flag. If for any reason I don't get that interrupt (I haven't seen this, but I'm guessing it is possible if the transfer fails?), then my transmit code will be stuck forever. I was thinking I could enable the SOF interrupt to keep an eye on my state, while there is something to send, then disable it when there isn't. The reason I want to disable it again is, if left enabled it will ruin my low power modes as I will be constantly switching out of low power mode.

I can of course write to the interrupt mask directly, but I would prefer to add an SOF enable function to the drivers that allowed me to turn it on and off from the class. It would be simple to implement and would not add much RAM use of code space. Is this something you would consider a pull request for?

Rename drivers

Currently all drivers are named numerically. This will likely get out of hand very soon, especially after OTG_HS get introduced. I suggest a rename to all driver names based on the device series and peripheral name, kind of inspired by how Linux kernel name drivers on device trees.

The naming convention would be usb_device_peripheral. The device part would be one of the typical chip the driver supports, and the peripheral part takes one of the four values:

  • fsdev: USB Full-Speed Device, as found in STM32F042,
  • otgfs: USB OTG Full-Speed in Device mode, as found in STM32F407,
  • otghs: USB OTG High-Speed in Device mode with internal Full-Speed PHY, as found in STM32F407,
  • otghs-ulpi: USB OTG High-Speed in Device mode with external ULPI High-Speed PHY, as found in STM32F407.

Here is a round-up of renamed current drivers:

  • usb_32v0 -> usb_stm32f042_fsdev,
  • usb_32v1 -> usb_stm32l151_fsdev,
  • usb_32v2 -> usb_stm32l476_otgfs,
  • usb_32v3 -> usb_stm32f103_fsdev.

And new names for a few new drivers:

  • usb_stm32f405_otgfs for OTG_FS on STM32F405/415/407/417
  • usb_stm32f405_otghs for OTG_HS in internal FS PHY mode on STM32F405/415/407/417
  • usb_stm32f405_otghs_ulpi for OTG_HS in external HS PHY mode on STM32F405/415/407/417

For the device detect macros, leave out the peripheral part of the driver name, as for each device the full set of drivers is made simultaneously available. (Example: USB_STM32F042 and USB_STM32F405,) The driver struct used in code would instead omit the device part, making code more portable. (example: usb_fsdev, usb_otgfs, usb_otghs and usb_otghs_ulpi.)

Несоответствие для STM32F072C8

Си версия драйвера заработала без проблем. Для ассемблерной изменил три определения.

#define RCC_APB1RSTR 0x28
#define RCC_APB1ENR 0x38
#define UID_BASE 0x1FF80050

#define RCC_APB1RSTR 0x10
#define RCC_APB1ENR 0x1C
#define UID_BASE 0x1FFFF7AC

STM32L433

Can i use the library for the STM32L433 controller?
If yes, what modifications should be made to the library?

Interrupt example?

First of all, thanks for writing this library. I'm seriously considering using it over the official ST libs which are a pretty big mess when it comes to USB especially.

Do you have a code example of the library with interrupts? The demo seems to use polling, unless I'm missing something...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.