Hi,
For fun, I've got one of those $3 F103 boards from ebay that needs a job to do. My end goal is to make a USB HID device that reads an original NES controller.
I've run into an issue setting up the USB driver. I have successfully set up the descriptors and strings, and have verified with Wireshark and Linux lsusb command that it appears to be enumerating correctly. I've compared the enumeration phase with another similar HID firmware and it looks like all the descriptors/reports/strings have been requested and accepted.
The problem is, after I've enumerated, I tried to use usbTransmit() to send my 3 bytes via an interrupt endpoint representing the status of my buttons and the call never returns. I have all DBG_ defines set, and it is not failing any asserts or checks, it just simply never comes back from the call and if I break in the debugger it is spinning waiting for an interrupt. On Wireshark, I can see the interrupt request go out host->device, but the response from device->host seems to be empty (again comparing with a working firmware where the 3 bytes are present at the end of the response packet). Note this might be the default response of the USB peripheral if it has nothing buffered to send.
Not sure how to debug further. I'm pretty sure the hardware/cabling is fine. I've also run a USB_RAW firmware adapted from the F7 hal demo, and it seems to work with bulk transfers. Maybe related to interrupt transfer? I'm not extremely well versed in USB.
I'm using ChibiOS-18.2.2, and gcc 7.3.0.
USB on STM32F103 blue pill
Moderators: RoccoMarco, barthess
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: USB on STM32F103 blue pill
Hi,
It could be related to interrupt endpoints, I don't have an example for those but the driver should wake up the thread after sending the data. Is it possible that the endpoint is never polled by host because problems with the descriptors?
Giovanni
It could be related to interrupt endpoints, I don't have an example for those but the driver should wake up the thread after sending the data. Is it possible that the endpoint is never polled by host because problems with the descriptors?
Giovanni
Re: USB on STM32F103 blue pill
I'm not sure. I started with working descriptors taken from a project that used libopencm3. Originally based on this:
https://github.com/paulfertser/stm32-tx-hid
I had changed the HID report to match my hardware, and I can verify that those descriptors/endpoints work fine.
The only modifications I did when porting to Chibi was remove the second USB configuration concerning DFU in the original project since I don't want/need that. From lsusb it seems to have accepted my descriptors:
Note, on Linux the report descriptors show up as "UNAVAILABLE" because the device is bound. I have confirmed they are the same as my working firmware, using Wireshark.
I can see the host requesting:
And a few moments later, the empty response:
https://github.com/paulfertser/stm32-tx-hid
I had changed the HID report to match my hardware, and I can verify that those descriptors/endpoints work fine.
The only modifications I did when porting to Chibi was remove the second USB configuration concerning DFU in the original project since I don't want/need that. From lsusb it seems to have accepted my descriptors:
Code: Select all
Bus 003 Device 042: ID 0483:5710 STMicroelectronics Joystick in FS Mode
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 3 Human Interface Device
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0x5710 Joystick in FS Mode
bcdDevice 2.00
iManufacturer 1 STMicroelectronics
iProduct 2 ChibiOS/RT Virtual COM Port
iSerial 3 510
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 50mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.00
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 43
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Note, on Linux the report descriptors show up as "UNAVAILABLE" because the device is bound. I have confirmed they are the same as my working firmware, using Wireshark.
I can see the host requesting:
Code: Select all
Frame 300: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface 0
USB URB
[Source: host]
[Destination: 3.38.1]
URB id: 0xffff926c06b5c6c0
URB type: URB_SUBMIT ('S')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x81, Direction: IN
Device: 38
URB bus id: 3
Device setup request: not relevant ('-')
Data: not present ('<')
URB sec: 1556878004
URB usec: 126921
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 3
Data length [bytes]: 0
[Response in: 305]
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 8
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
And a few moments later, the empty response:
Code: Select all
Frame 305: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface 0
USB URB
[Source: 3.38.1]
[Destination: host]
URB id: 0xffff926c06b5c6c0
URB type: URB_COMPLETE ('C')
URB transfer type: URB_INTERRUPT (0x01)
Endpoint: 0x81, Direction: IN
Device: 38
URB bus id: 3
Device setup request: not relevant ('-')
Data: present (0)
URB sec: 1556878004
URB usec: 186303
URB status: No such file or directory (-ENOENT) (-2)
URB length [bytes]: 0
Data length [bytes]: 0
[Request in: 300]
[Time from request: 0.059382000 seconds]
[bInterfaceClass: HID (0x03)]
Unused Setup Header
Interval: 8
Start frame: 0
Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
Number of ISO descriptors: 0
Re: USB on STM32F103 blue pill
OK, I revisited my baseline ChibiOS project, which is just a STM32F1 hal demo, with the added USB_RAW bits. I initially said it was working, but it seems to only receive. When I tried making it transmit, the same thing happens where it enters usbTransmit() and never wakes up again.
Is it possible the USB_ADDR2PTR and friends are calculating the wrong TX USBRAM offsets? The reference manual (if I'm reading it correctly) states that the memory is organized as 512 bytes, with 256 words of 16bits. However, the stm32_usb_pma_t for this device is being typedef'd to uint32_t. I don't pretend to understand the math being done in the helper macros though.
Is it possible the USB_ADDR2PTR and friends are calculating the wrong TX USBRAM offsets? The reference manual (if I'm reading it correctly) states that the memory is organized as 512 bytes, with 256 words of 16bits. However, the stm32_usb_pma_t for this device is being typedef'd to uint32_t. I don't pretend to understand the math being done in the helper macros though.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: USB on STM32F103 blue pill
Hi,
There are two organizations of the PMA, F1 uses the old one, 16 bits words aligned in 32 bits words, this is the reason for the strange code.
Could you try one of the demos as-is, just the minimum changes for the board.
Giovanni
There are two organizations of the PMA, F1 uses the old one, 16 bits words aligned in 32 bits words, this is the reason for the strange code.
Could you try one of the demos as-is, just the minimum changes for the board.
Giovanni
Re: USB on STM32F103 blue pill
I took testhal/STM32/STM32F1xx/USB_CDC
I changed it to use STM32F103C8_MINIMAL board, and STM32F103x8.ld linker script to match my hardware.
I also just dragged the D+ pin low for a second in main in lieu of usbDisconnect/usbConnect since the board.h doesn't support those.
All appears normal in the demo
So obviously usbTransmit _can_ work with this configuration.
I changed it to use STM32F103C8_MINIMAL board, and STM32F103x8.ld linker script to match my hardware.
I also just dragged the D+ pin low for a second in main in lieu of usbDisconnect/usbConnect since the board.h doesn't support those.
All appears normal in the demo
Code: Select all
ch> threads
stklimit stack addr refs prio state name
20000400 2000079C 200019F0 1 128 WTEXIT main
20001A80 20001ACC 20001B10 1 1 READY idle
200023B0 20002454 200024B0 1 128 SLEEPING blinker
20002500 20002C7C 20002D80 1 129 CURRENT shell
ch> info
Kernel: 5.1.0
Compiler: GCC 7.3.0
Architecture: ARMv7-M
Core Variant: Cortex-M3
Port Info: Advanced kernel mode
Platform: STM32F10x Performance Line Medium Density
Board: STM32F103 Minimal Module
Build time: May 3 2019 - 16:48:06
ch>
Code: Select all
Bus 003 Device 077: ID 0483:5740 STMicroelectronics Virtual COM Port
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0x5740 Virtual COM Port
bcdDevice 2.00
iManufacturer 1 (error)
iProduct 2 (error)
iSerial 3 (error)
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 67
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x00
bDataInterface 1
CDC ACM:
bmCapabilities 0x02
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 255
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
So obviously usbTransmit _can_ work with this configuration.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: USB on STM32F103 blue pill
Could you try adding the interrupt EP on top of the demo? in general, you could try to re-introduce your changes gradually, board and driver appear to work.
Giovanni
Giovanni
- wurstnase
- Posts: 121
- Joined: Tue Oct 17, 2017 2:24 pm
- Has thanked: 43 times
- Been thanked: 30 times
- Contact:
Re: USB on STM32F103 blue pill
When it helps to have a working USB-CDC example for the blue pill, I could upload something.
\o/ Nico
Re: USB on STM32F103 blue pill
Giovanni wrote:Could you try adding the interrupt EP on top of the demo? in general, you could try to re-introduce your changes gradually, board and driver appear to work.
I got back to this finally. I added another interface to the CDC demo, with my (to my knowledge) working HID descriptors. I have verified that the ACM is still working properly, and I can communicate with the board with that interface. It still hangs when I try to call usbTransmit() on the new interrupt endpoint.
For that matter, I noticed the CDC demo class has an interrupt endpoint (EP 2) as well. I'm not sure what it does as part of the CDC/ACM spec, but I tried writing a byte to that endpoint and it doesn't return from the call either.
Not sure what to try next.
Who is online
Users browsing this forum: No registered users and 48 guests