Giter Site home page Giter Site logo

libusb_stm32's People

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

STM32L433

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

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?

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.

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);

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 ^)

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?

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?

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

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.

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.

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.

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.

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?

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!

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).

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.

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...

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.

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

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.

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.

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?

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.

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?

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.

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"

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!

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...

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?

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.

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

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

Remove PMA size warning

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

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?

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

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.

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.

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.

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 :)

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?

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 ?

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

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?

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?

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.