dmitrystu / libusb_stm32 Goto Github PK
View Code? Open in Web Editor NEWLightweight USB device Stack for STM32 microcontrollers
License: Apache License 2.0
Lightweight USB device Stack for STM32 microcontrollers
License: Apache License 2.0
Can i use the library for the STM32L433 controller?
If yes, what modifications should be made to the library?
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:
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.
libusb_stm32/src/usbd_stm32f103_devfs.c
Line 162 in 7b5e32e
if (USBD_DP_PORT->IDR & _BV(USBD_DP_PIN)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
I already have proprietary STM32F767 board and I want to integrate a Seekthermal USB camera.
Thank you.
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 ^)
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?
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?
Same problem as STM32F373xC. Possibly all "C" has same "feature".
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
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)
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.
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.
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.
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.
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?
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!
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).
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.
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...
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.
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
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.
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.
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?
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.
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?
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.
Is it possible to make it C99 compliant?
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"
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!
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...
I'm mostly doing USB-MIDI on STM32 devices and would like to switch to this library. Unless someone else is already working on it or has a functional implementation I will contribute mine when I have it ready.
Spec is here: http://www.usb.org/developers/docs/devclass_docs/midi10.pdf
I was going through the whole project with Doxygen. A few questions:
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.cdc_setconf
, adding all endpoints I need, all callback for each endpoint)SET PROTOCOL, GET PROTOCOL, GET IDLE, SET IDLE, SET REPORT, GET REPORT
in the callback registered in the usbd_reg_control
. (ref: https://www.keil.com/pack/doc/mw/USB/html/_h_i_d.html)SET REPORT
and GET REPORT
? In the custom hid of stm32 HAL USB, they need to callhhid-> IsReportAvailable =1
and USBD_CtlPrepareRx
, do libusb_stm32
need to do some similar thing like that?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.
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/417usb_stm32f405_otghs
for OTG_HS in internal FS PHY mode on STM32F405/415/407/417usb_stm32f405_otghs_ulpi
for OTG_HS in external HS PHY mode on STM32F405/415/407/417For 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
.)
Си версия драйвера заработала без проблем. Для ассемблерной изменил три определения.
Lines 37 to 39 in 87fc76d
#define RCC_APB1RSTR 0x10
#define RCC_APB1ENR 0x1C
#define UID_BASE 0x1FFFF7AC
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
What's the reason of having the PMA size configurable? Isn't it fixed for a concrete part number?
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.
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
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?
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
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.
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.
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.
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 :)
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?
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 ?
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
I want to use polling method for get message from the usb device. And I can't just use usbd_ep_read/usbd_ep_write methods because it may corrupt the configure process. How to decide if a usb device is connected and configured?
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?
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.