Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32F7: Do not generate redundant IN tokens #11103

Merged
merged 1 commit into from Aug 9, 2019

Conversation

@desowin
Copy link
Contributor

commented Jul 24, 2019

Description

When STM32F746-DISCO board was being used in (unsupported) USBHost mode,
the communication was unreliable. Our investigation revealed that the
problem lied in redundant IN tokens that the host generated even though
it shouldn't. This could lead to endless high-frequency NAKs being
received from device, which caused watchdog reset as USBHost spent all
time in interrupt handlers.

In our application the clocks frequencies are:

  • HCLK = 48 MHz
  • APB1 = 6 MHz
  • APB2 = 12 MHz

We have captured the raw USB High-Speed traffic using OpenVizsla.
Without this change, when USB MSD device connected to the system
responded to IN with NAK, there were excessive IN tokens generated about
667 ns after the NAK. With this commit the IN tokens are generated no
sooner than 10 us after the NAK.

The high frequency of the IN/NAK pairs is not the biggest problem.
The biggest problem is that the USB Host did continue to send the IN token
after DATA and ACK packets were received from device - without any request
from upper layer (USB MSD).

The USB MSD devices won't have extra data available on Bulk IN endpoint
after the expected data was received by Host. In such case IN/NAK cycle
time is only houndreds of nanoseconds, the MCU has no time for anything else.

The problem manifested not only on Bulk endpoints, but also during
Control transfers. Example correct scenario (when this fix is applied):

  • SETUP stage
    • SETUP [host -> address 0 endpoint 0]
    • DATA0 [80 06 00 01 00 00 08 00] [CRC16: EB 94]
    • ACK
  • DATA stage
    • IN
    • NAK
      ... the IN/NAK repeated multiple time until device was ready
    • IN
    • DATA1 [12 01 10 02 00 00 00 40] [CRC16: 55 41]
    • ACK
  • STATUS stage
    • OUT
    • DATA1 ZLP
    • ACK

Without this commit, in DATA stage, after the ACK was received, the host
did send extra IN to which device responded with STALL. On bus it was:

  • DATA stage
    ...
    • IN
    • DATA1 [12 01 10 02 00 00 00 40] [CRC16: 55 41]
    • IN
    • STALL
    • IN
    • STALL
  • STATUS stage
    • OUT
    • DATA1 ZLP
    • STALL

In the fault case the next SETUP was sent only after 510 ms, which
indicates timeout in upper layer.

With this commit the next SETUP is sent 120 us after the STATUS stage ACK.

Pull request type

[X] Fix
[ ] Refactor
[ ] Target update
[ ] Functionality change
[ ] Docs update
[ ] Test update
[ ] Breaking change

Reviewers

Release Notes

Ireneusz Gaicki Tomasz Moń
STM32F7: Do not generate redundant IN tokens
When STM32F746-DISCO board was being used in (unsupported) USBHost mode,
the communication was unreliable. Our investigation revealed that the
problem lied in redundant IN tokens that the host generated even though
it shouldn't. This could lead to endless high-frequency NAKs being
received from device, which caused watchdog reset as USBHost spent all
time in interrupt handlers.

In our application the clocks frequencies are:
  * HCLK = 48 MHz
  * APB1 = 6 MHz
  * APB2 = 12 MHz

We have captured the raw USB High-Speed traffic using OpenVizsla.
Without this change, when USB MSD device connected to the system
responded to IN with NAK, there were excessive IN tokens generated about
667 ns after the NAK. With this commit the IN tokens are generated no
sooner than 10 us after the NAK.

The high frequency of the IN/NAK pairs is not the biggest problem.
The biggest problem is that the USB Host did continue to send the IN token
after DATA and ACK packets were received from device - *without* any request
from upper layer (USB MSD).

The USB MSD devices won't have extra data available on Bulk IN endpoint
after the expected data was received by Host. In such case IN/NAK cycle
time is only houndreds of nanoseconds, the MCU has no time for anything else.

The problem manifested not only on Bulk endpoints, but also during
Control transfers. Example correct scenario (when this fix is applied):
  * SETUP stage
    * SETUP [host -> address 0 endpoint 0]
    * DATA0 [80 06 00 01 00 00 08 00] [CRC16: EB 94]
    * ACK
  * DATA stage
    * IN
    * NAK
    ... the IN/NAK repeated multiple time until device was ready
    * IN
    * DATA1 [12 01 10 02 00 00 00 40] [CRC16: 55 41]
    * ACK
  * STATUS stage
    * OUT
    * DATA1 ZLP
    * ACK

Without this commit, in DATA stage, after the ACK was received, the host
did send extra IN to which device responded with STALL. On bus it was:
  * DATA stage
    ...
    * IN
    * DATA1 [12 01 10 02 00 00 00 40] [CRC16: 55 41]
    * IN
    * STALL
    * IN
    * STALL
  * STATUS stage
    * OUT
    * DATA1 ZLP
    * STALL

In the fault case the next SETUP was sent only after 510 ms, which
indicates timeout in upper layer.

With this commit the next SETUP is sent 120 us after the STATUS stage ACK.

@ciarmcom ciarmcom requested a review from ARMmbed/mbed-os-maintainers Jul 24, 2019

@ciarmcom

This comment has been minimized.

Copy link
Member

commented Jul 24, 2019

@desowin, thank you for your changes.
@ARMmbed/mbed-os-maintainers please review.

@bulislaw

This comment has been minimized.

Copy link
Member

commented Jul 24, 2019

@ARMmbed/team-st-mcd please review.

@SeppoTakalo SeppoTakalo requested a review from ARMmbed/team-st-mcd Jul 25, 2019

@mbed-ci

This comment has been minimized.

Copy link

commented Jul 25, 2019

Test run: SUCCESS

Summary: 11 of 11 test jobs passed
Build number : 1
Build artifacts

@SeppoTakalo SeppoTakalo removed the needs: CI label Jul 29, 2019

@0xc0170
0xc0170 approved these changes Aug 9, 2019

@0xc0170 0xc0170 merged commit 174cac7 into ARMmbed:master Aug 9, 2019

26 checks passed

continuous-integration/jenkins/pr-head This commit looks good
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
jenkins-ci/build-ARM Success
Details
jenkins-ci/build-GCC_ARM Success
Details
jenkins-ci/build-IAR Success
Details
jenkins-ci/cloud-client-test Success
Details
jenkins-ci/dynamic-memory-usage RTOS ROM(+0 bytes) RAM(+0 bytes)
Details
jenkins-ci/exporter Success
Details
jenkins-ci/greentea-test Success
Details
jenkins-ci/mbed2-build-ARM Success
Details
jenkins-ci/mbed2-build-GCC_ARM Success
Details
jenkins-ci/mbed2-build-IAR Success
Details
jenkins-ci/unittests Success
Details
travis-ci/astyle Success!
Details
travis-ci/docs Success!
Details
travis-ci/doxy-spellcheck Success!
Details
travis-ci/events Success! Runtime is 8640 cycles.
Details
travis-ci/gitattributestest Success!
Details
travis-ci/include_check Success!
Details
travis-ci/licence_check Success!
Details
travis-ci/littlefs Success! Code size is 8448B.
Details
travis-ci/psa-autogen Success!
Details
travis-ci/tools-py2.7 Success!
Details
travis-ci/tools-py3.5 Success!
Details
travis-ci/tools-py3.6 Success!
Details
travis-ci/tools-py3.7 Success!
Details

@0xc0170 0xc0170 removed the ready for merge label Aug 9, 2019

@jeromecoutant

This comment has been minimized.

Copy link
Contributor

commented Aug 19, 2019

ST_INTERNAL_REF 70627

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants
You can’t perform that action at this time.