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

NRF_USB->EVENTS_EPDATA fails to trigger

Hiya!

I am writing code to add support for USB on the NRF58233/58240 to MakeCode. MakeCode relies upon WebUSB. At any point, a user can close the website which causes the web usb stack to stop reading from the device. When this happens, the synchronous code I've written hangs indefinitely.

I have added a software timeout that causes the NRF to exit the while loop and resume application operation until it gets an out transaction from the host. The timeout however is too short on some occasions and times out prematurely.

Instead of increasing the timeout, is there a more elegant way to detect that the host is no longer reading a transaction? Isn't it weird that the EPDATA event is not triggered?

I attach a reference to the code:

codal-nrf52/NRF52USB.cpp at master · lancaster-university/codal-nrf52 (github.com)

and a screenshot from my usb analyser with the timeout in the above code removed:

After line 5471, the MCU has entered the while loop on EVENTS_EPDATA which it never exits. I am at this time using an NRF52833 DK (PCA10100 v0.7.0) and a NRF52840-DK (PCA10056 v2.0.1). The issue is present on both DKs.

Happy to share binaries as required... 

Parents
  • Hello James,

    Please bear with me, as I am just starting to look into the USB peripheral. About the EVENTS_EPDATA not triggering, could it be that you haven't flagged the right data endpoint in EPDATASTATUS?

    From the nRF52840 PS section 6.35.8:
    "The EPDATA event indicates that a successful (acknowledged) data transaction has occurred on the dataendpoint(s) flagged in register EPDATASTATUS. A successful (acknowledged) data transaction on endpoint0 is signalled by the EP0DATADONE event"

    Another question when using webUSB, do you know if the host will suspend the device just because it's not used by the application anymore? If the USB device is suspended by the host you could use USBEVENT event with SUSPEND bit in the EVENTCAUSE register.

    In Zephyr and nRF connect SDK, USB classes purge buffer/cancel transfer on suspend event, but since webUSB is not really an USB class, and I do not know what the host will perform, so not suspend would help but it's worth taking into account what the actual USB host respond will be when the browser is closed.

    One of our developers recommended using EVENTS_ENDEPIN to check if the buffer was transferred instead of using EPDATA, together with a timeout as you have done. EVENTS_ENDEPIN[n] is described in 6.35.13.12. and it indicates that "The whole EPIN[n] buffer has been consumed" which means the buffer has been transferred to the host. Can you try using this event instead of EPDATA in your loop together with the timeout?

    BTW in Zephyr there is a simple webUSB sample, I don't know if it would be helpful for your project: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/subsys/usb/webusb/README.html

    Best regards,

    Marjeris

Reply
  • Hello James,

    Please bear with me, as I am just starting to look into the USB peripheral. About the EVENTS_EPDATA not triggering, could it be that you haven't flagged the right data endpoint in EPDATASTATUS?

    From the nRF52840 PS section 6.35.8:
    "The EPDATA event indicates that a successful (acknowledged) data transaction has occurred on the dataendpoint(s) flagged in register EPDATASTATUS. A successful (acknowledged) data transaction on endpoint0 is signalled by the EP0DATADONE event"

    Another question when using webUSB, do you know if the host will suspend the device just because it's not used by the application anymore? If the USB device is suspended by the host you could use USBEVENT event with SUSPEND bit in the EVENTCAUSE register.

    In Zephyr and nRF connect SDK, USB classes purge buffer/cancel transfer on suspend event, but since webUSB is not really an USB class, and I do not know what the host will perform, so not suspend would help but it's worth taking into account what the actual USB host respond will be when the browser is closed.

    One of our developers recommended using EVENTS_ENDEPIN to check if the buffer was transferred instead of using EPDATA, together with a timeout as you have done. EVENTS_ENDEPIN[n] is described in 6.35.13.12. and it indicates that "The whole EPIN[n] buffer has been consumed" which means the buffer has been transferred to the host. Can you try using this event instead of EPDATA in your loop together with the timeout?

    BTW in Zephyr there is a simple webUSB sample, I don't know if it would be helpful for your project: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/subsys/usb/webusb/README.html

    Best regards,

    Marjeris

Children
  • Hiya,

    Thanks for the detailed reply.

     About the EVENTS_EPDATA not triggering, could it be that you haven't flagged the right data endpoint in EPDATASTATUS?

    I mostly ignore EPDATASTATUS as the USB code is synchronous. From what I understand, the hardware uses this register to flag whether a transaction has completed and it is not up to me to set the flag... If the flag is being set by the hardware, surely the EPDATA event should trigger?

    Another question when using webUSB, do you know if the host will suspend the device just because it's not used by the application anymore? If the USB device is suspended by the host you could use USBEVENT event with SUSPEND bit in the EVENTCAUSE register.

    As you can see from the USB trace, it doesn't look like the host issues a suspend command.

    One of our developers recommended using EVENTS_ENDEPIN to check if the buffer was transferred instead of using EPDATA, together with a timeout as you have done. EVENTS_ENDEPIN[n] is described in 6.35.13.12.

    This could work, but presumably this wouldn't work for EP0 which has a status stage? Is there a chronological dependency on EPDATA for the status stage for EP0? What happens if I trigger EP0STATUS before EPDATA has been triggered? 

    Should I add a special case for EP0?

  • Hi James,

    I forwarded your questions to our software team last week and I am still working on finding the answers to your latest questions as this is a bit out of my scope. I am sorry for the delays on this.

    Best regards,

    Marjeris

Related