USB on STM32F103 blue pill

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

USB on STM32F103 blue pill

Postby dflogeras » Fri May 03, 2019 11:47 am

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.

User avatar
Giovanni
Site Admin
Posts: 12106
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 549 times
Been thanked: 471 times
Contact:

Re: USB on STM32F103 blue pill

Postby Giovanni » Fri May 03, 2019 12:24 pm

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

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: USB on STM32F103 blue pill

Postby dflogeras » Fri May 03, 2019 12:56 pm

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:

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

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: USB on STM32F103 blue pill

Postby dflogeras » Fri May 03, 2019 3:50 pm

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.

User avatar
Giovanni
Site Admin
Posts: 12106
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 549 times
Been thanked: 471 times
Contact:

Re: USB on STM32F103 blue pill

Postby Giovanni » Fri May 03, 2019 5:23 pm

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

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: USB on STM32F103 blue pill

Postby dflogeras » Fri May 03, 2019 8:59 pm

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

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.

User avatar
Giovanni
Site Admin
Posts: 12106
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 549 times
Been thanked: 471 times
Contact:

Re: USB on STM32F103 blue pill

Postby Giovanni » Fri May 03, 2019 9:05 pm

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

User avatar
wurstnase
Posts: 90
Joined: Tue Oct 17, 2017 2:24 pm
Has thanked: 34 times
Been thanked: 17 times
Contact:

Re: USB on STM32F103 blue pill

Postby wurstnase » Sun May 05, 2019 12:17 pm

When it helps to have a working USB-CDC example for the blue pill, I could upload something.
\o/ Nico

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: USB on STM32F103 blue pill

Postby dflogeras » Tue May 14, 2019 2:41 pm

Thanks for the offer Nico, however I have a working CDC example, it's my HID I cannot get working.

dflogeras
Posts: 180
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 2 times
Been thanked: 10 times

Re: USB on STM32F103 blue pill

Postby dflogeras » Tue May 14, 2019 2:45 pm

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.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 4 guests