This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bulk OUT works , but IN not

I inserted code.

OUT 0x04 endpoint works, but 0x84 IN endpoint doesn't. 

I use libusb from Linux PC to communicate with nrf52840 via USB. At PC I call function "libusb_bulk_transfer" - it results in timeout - and at SOC no enter to event handler.

I see USB registers - IN endpoint packet counter don't increment, and no response.UGate.23.03.2020.zipUNrf.23.03.2020.zip

  • Hi,

     

    Thanks for providing both firmware and host software to test with. Makes it very easy to look into.

    Firmware built with SDK v16.0.0 (SES)

    I built the software on ubuntu 19.10, and ran it:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ======= Wallit USB BLE Node server ==========================================================
    === LibUSB init ..... done. ===
    === Get Device List ..... done. ===
    === USB devices:
    ==============================================================================================
    VID:0a5c,PID:5801 (bus 1, device address: 4) path: 1.5
    - Intel -
    VID:8087,PID:07dc (bus 1, device address: 3) path: 1.3
    - Intel -
    VID:8087,PID:8000 (bus 1, device address: 2) path: 1
    - Linux Foundation -
    VID:1d6b,PID:0002 (bus 1, device address: 1)
    - Linux Foundation -
    VID:1d6b,PID:0003 (bus 3, device address: 1)
    - Segger -
    VID:1366,PID:1015 (bus 2, device address: 101) path: 6
    VID:1bcf,PID:28a0 (bus 2, device address: 3) path: 4
    - Logitech -
    VID:046d,PID:c52b (bus 2, device address: 2) path: 2
    - Nordic -
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Seems to be working? Could it be that I'm missing something?

     

    Kind regards,

    Håkon

  • Thank you!

    Yes - this works because at that moment  address is 0x04 - for this BULK OUT all works - please change it to 0x84 to reproduce issue - in this case function

    libusb_bulk_transfer( h_nordic, 0x84, nrf_frame, 32, received, 300 );

    results in timeout and I see no activity at EP4 registers inside nrf52840.
    here was said you have ellisys qualifiers and can see what happens in the D+,D- usb line.
    I have not such possibility it costs 50 000 EUR.
  • Hi,

     

    Thanks for clearing that up - I had a feeling I didn't see the whole picture!

    1. You should handle this error from dmesg:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [122449.313587] usb 2-1: USB disconnect, device number 122
    [122453.543735] usb 2-1: new full-speed USB device number 123 using xhci_hcd
    [122453.692697] usb 2-1: not running at top speed; connect to a high speed hub
    [122453.693668] usb 2-1: config 1 interface 0 altsetting 0 endpoint 0x4 has invalid maxpacket 512, setting to 64
    [122453.693670] usb 2-1: config 1 interface 0 altsetting 0 endpoint 0x84 has invalid maxpacket 512, setting to 64
    [122453.695147] usb 2-1: New USB device found, idVendor=1915, idProduct=7777, bcdDevice= 1.01
    [122453.695149] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    [122453.695151] usb 2-1: Product: nRF52 USB HID mouse on nrf_drv Demo
    [122453.695152] usb 2-1: Manufacturer: Nordic Semiconductor
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    That is done by setting the EP size to 0x40 (64) or lower:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #define USBD_ENDPOINT1_DESCRIPTOR \
    0x07, /* bLength | length of descriptor (7 bytes) */ \
    0x05, /* bDescriptorType | descriptor type (ENDPOINT) */ \
    0x04, /* bEndpointAddress | endpoint address (IN1 endpoint) */ \
    0x02, /* bmAttributes | endpoint attributes (usual data) */ \
    0x40, /* bMaxPacketSizeLowByte */ \
    0x00, /* bMaxPacketSizeHighByte | maximum packet size (512 bytes) */ \
    0 /* bInterval | polling interval (10ms) */
    //===================================================================================================================
    #define USBD_ENDPOINT2_DESCRIPTOR \
    0x07, /* bLength | length of descriptor (7 bytes) */ \
    0x05, /* bDescriptorType | descriptor type (ENDPOINT) */ \
    0x84, /* bEndpointAddress | endpoint address (OUT1 endpoint) */ \
    0x02, /* bmAttributes | endpoint attributes (bulk, usual data \
    000010) */ \
    0x40, /* bMaxPacketSizeLowByte */ \
    0x00, /* bMaxPacketSizeHighByte | maximum packet size (512 bytes) */ \
    0 /* bInterval | polling interval (10ms) */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I also changed the transfer blocks to different sizes, where transfer_in has .size = 62 at my end.

    2. It does not seem that you send data? I added a call to send_ep() in main (every time it had run 3000 times, execute send_ep()). Quick way to trigger a periodic transfer if you add this to the main loop:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    static uint32_t count_out;
    count_out ++;
    if (count_out % 3000 == 0)
    //if (0)
    {
    NRF_LOG_INFO("Trying to send data");
    send_ep();
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Log when polling for data:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    00> ================================== USBD example started =========================================================
    00> Reset reasons:
    00> - SREQ
    00> No USB power detection enabled
    00> Starting USB now
    00> No USB Enable - stall
    00> USB Start
    00> SUSPEND state detected
    00> RESUMING from suspend
    00> === GetDescriptor >>>
    00> = Respond Device descriptor =
    00> === EP Transfer ===========================
    00> === SetAddress >>>
    00> === GetDescriptor >>>
    00> = Respond Device descriptor =
    00> === GetDescriptor >>>
    00> Trying to send data
    00> === EPIN ===
    00> Trying to send data
    00> === EPIN ===
    00> === EP Transfer ===========================
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Since you are triggering a new transfer from the usbd callback again, it'll send quite often. With the current logic, you technically just need to call send_ep() once, and it should start pumping data (given that no err is returned in the call to usbd_event_handler, case NRF_DRV_USBD_EVT_EPTRANSFER, nrfx_usbd_ep_transfer)

    3. I changed the read size to 64 in libusb main.c example:

      epres = libusb_bulk_transfer( h_nordic, 0x84, nrf_frame, 64, received, 300 );
    and this is the output from the program, which matches the length on the IN transfer:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ======= Wallit USB BLE Node server ==========================================================
    === LibUSB init ..... done. ===
    === Get Device List ..... done. ===
    === USB devices:
    ==============================================================================================
    VID:0a5c,PID:5801 (bus 1, device address: 4) path: 1.5
    - Intel -
    VID:8087,PID:07dc (bus 1, device address: 3) path: 1.3
    - Intel -
    VID:8087,PID:8000 (bus 1, device address: 2) path: 1
    - Linux Foundation -
    VID:1d6b,PID:0002 (bus 1, device address: 1)
    - Linux Foundation -
    VID:1d6b,PID:0003 (bus 3, device address: 1)
    - Segger -
    VID:1366,PID:1015 (bus 2, device address: 112) path: 6
    VID:1bcf,PID:28a0 (bus 2, device address: 3) path: 4
    - Logitech -
    VID:046d,PID:c52b (bus 2, device address: 2) path: 2
    - Nordic -
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

     

    Could you try to make similar changes and see if it works on your end?

     

    Kind regards,

    Håkon

  • I got something different

    ==============================================================================================

    === found descriptor for open device ===
    opening bus.dev: 3.62
    === Nordic normally opened ===
    no active kernel driver.
    === Prepare data EP ===
    === EP transfer 0 ===
    bulk ep callback - actual_length = 0
    complete.
    LIBUSB_TRANSFER_STALL
    Segmentation fault

    I insert you cycle with send_ep() as you advised - got above mentioned message

  • Hi,

     

    Here's the edited project I'm using:

    UGate.zip

    I also included the .hex file I've used in the build folder.

     

    Could you see if this works?

     

    Kind regards,

    Håkon